Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Paket.sln
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{62D18A
EndProjectSection
EndProject
Global
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Expand Down
2 changes: 2 additions & 0 deletions src/Paket.Core/Common/Constants.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ let [<Literal>] GithubReleaseDownloadUrl = "https://github.com/fsprojects/Paket
let [<Literal>] LockFileName = "paket.lock"
/// 'paket.local'
let [<Literal>] LocalFileName = "paket.local"
/// 'paket.restore.sha512'
let [<Literal>] RestoreHashFile = "paket.restore.sha512"
/// 'paket.dependencies'
let [<Literal>] DependenciesFileName = "paket.dependencies"
/// '.paket'
Expand Down
8 changes: 8 additions & 0 deletions src/Paket.Core/Common/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,14 @@ let removeComment (text:string) =
| p1, p2 -> stripComment (min p1 p2)
remove 0

let getSha512Stream (stream:Stream) =
use hasher = System.Security.Cryptography.SHA512.Create() :> System.Security.Cryptography.HashAlgorithm
Convert.ToBase64String(hasher.ComputeHash(stream))

let getSha512File (filePath:string) =
use stream = File.OpenRead(filePath)
getSha512Stream stream

// adapted from MiniRx
// http://minirx.codeplex.com/
[<AutoOpen>]
Expand Down
5 changes: 1 addition & 4 deletions src/Paket.Core/Dependencies/NuGetCache.fs
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,7 @@ let rec ExtractPackageToUserFolder(fileName:string, packageName:PackageName, ver

let cachedHashFile = Path.Combine(Constants.NuGetCacheFolder,fi.Name + ".sha512")
if not <| File.Exists cachedHashFile then
use stream = File.OpenRead(fileName)
let packageSize = stream.Length
use hasher = System.Security.Cryptography.SHA512.Create() :> System.Security.Cryptography.HashAlgorithm
let packageHash = Convert.ToBase64String(hasher.ComputeHash(stream))
let packageHash = getSha512File fileName
File.WriteAllText(cachedHashFile,packageHash)

File.Copy(cachedHashFile,targetPackageFileName + ".sha512")
Expand Down
211 changes: 113 additions & 98 deletions src/Paket.Core/Installation/RestoreProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -362,105 +362,120 @@ let Restore(dependenciesFileName,projectFile,force,group,referencesFileNames,ign
let alternativeProjectRoot = None
if not lockFileName.Exists then
failwithf "%s doesn't exist." lockFileName.FullName
let dependenciesFile = DependenciesFile.ReadFromFile(dependenciesFileName)

let targetFilter =
targetFrameworks
|> Option.map (fun s -> s.Split(';') |> Array.map FrameworkDetection.Extract |> Array.choose id)

let lockFile,localFile,hasLocalFile =
let lockFile = LockFile.LoadFrom(lockFileName.FullName)
if not localFileName.Exists then
lockFile,LocalFile.empty,false
else
let localFile =
LocalFile.readFile localFileName.FullName
|> returnOrFail
LocalFile.overrideLockFile localFile lockFile,localFile,true

if not hasLocalFile && not ignoreChecks then
let hasAnyChanges,nugetChanges,remoteFilechanges,hasChanges = DependencyChangeDetection.GetChanges(dependenciesFile,lockFile,false)

let checkResponse = if failOnChecks then failwithf else traceWarnfn
if hasAnyChanges then
checkResponse "paket.dependencies and paket.lock are out of sync in %s.%sPlease run 'paket install' or 'paket update' to recompute the paket.lock file." lockFileName.Directory.FullName Environment.NewLine
for (group, package, changes) in nugetChanges do
traceWarnfn "Changes were detected for %s/%s" (group.ToString()) (package.ToString())
for change in changes do
traceWarnfn " - %A" change

let groups =
match group with
| None -> lockFile.Groups
| Some groupName ->
match lockFile.Groups |> Map.tryFind groupName with
| None -> failwithf "The group %O was not found in the paket.lock file." groupName
| Some group -> [groupName,group] |> Map.ofList

let resolved = lazy (lockFile.GetGroupedResolution())

let referencesFileNames =
match projectFile with
| Some projectFileName ->
let referencesFile = FindOrCreateReferencesFile projectFileName
let projectFileInfo = FileInfo projectFileName

createAlternativeNuGetConfig projectFileInfo
createProjectReferencesFiles dependenciesFile lockFile projectFileInfo referencesFile resolved targetFilter groups

[referencesFile.FileName]
| None -> referencesFileNames

let tasks =
groups
|> Seq.map (fun kv ->
let allPackages =
if List.isEmpty referencesFileNames then
kv.Value.Resolution
|> Seq.map (fun kv -> kv.Key)
else
referencesFileNames
|> List.toSeq
|> computePackageHull kv.Key lockFile

let packages =
allPackages
|> Seq.filter (fun p ->
match targetFilter with
| None -> true
| Some targets ->
let key = kv.Key,p
let resolvedPackage = resolved.Force().[key]

match resolvedPackage.Settings.FrameworkRestrictions with
| Requirements.ExplicitRestriction restrictions ->
targets
|> Array.exists (fun target -> Requirements.isTargetMatchingRestrictions(restrictions, SinglePlatform target))
| _ -> true)
// Shortcut if we already restored before
let newHash = getSha512File lockFileName.FullName
let restoreHashFile = Path.Combine(root, Constants.PaketFilesFolderName, Constants.RestoreHashFile)
let inline isEarlyExit () =
if File.Exists restoreHashFile then
let oldHash = File.ReadAllText(restoreHashFile)
oldHash = newHash
else false

if isEarlyExit () then
tracefn "Last restore is still up 2 date."
else
let dependenciesFile = DependenciesFile.ReadFromFile(dependenciesFileName)

let targetFilter =
targetFrameworks
|> Option.map (fun s -> s.Split(';') |> Array.map FrameworkDetection.Extract |> Array.choose id)

let lockFile,localFile,hasLocalFile =
let lockFile = LockFile.LoadFrom(lockFileName.FullName)
if not localFileName.Exists then
lockFile,LocalFile.empty,false
else
let localFile =
LocalFile.readFile localFileName.FullName
|> returnOrFail
LocalFile.overrideLockFile localFile lockFile,localFile,true

if not hasLocalFile && not ignoreChecks then
let hasAnyChanges,nugetChanges,remoteFilechanges,hasChanges = DependencyChangeDetection.GetChanges(dependenciesFile,lockFile,false)

let checkResponse = if failOnChecks then failwithf else traceWarnfn
if hasAnyChanges then
checkResponse "paket.dependencies and paket.lock are out of sync in %s.%sPlease run 'paket install' or 'paket update' to recompute the paket.lock file." lockFileName.Directory.FullName Environment.NewLine
for (group, package, changes) in nugetChanges do
traceWarnfn "Changes were detected for %s/%s" (group.ToString()) (package.ToString())
for change in changes do
traceWarnfn " - %A" change

let groups =
match group with
| None -> lockFile.Groups
| Some groupName ->
match lockFile.Groups |> Map.tryFind groupName with
| None -> failwithf "The group %O was not found in the paket.lock file." groupName
| Some group -> [groupName,group] |> Map.ofList

let resolved = lazy (lockFile.GetGroupedResolution())

let referencesFileNames =
match projectFile with
| Some projectFileName ->
let referencesFile = FindOrCreateReferencesFile projectFileName
let projectFileInfo = FileInfo projectFileName

createAlternativeNuGetConfig projectFileInfo
createProjectReferencesFiles dependenciesFile lockFile projectFileInfo referencesFile resolved targetFilter groups

[referencesFile.FileName]
| None -> referencesFileNames

let tasks =
groups
|> Seq.map (fun kv ->
let allPackages =
if List.isEmpty referencesFileNames then
kv.Value.Resolution
|> Seq.map (fun kv -> kv.Key)
else
referencesFileNames
|> List.toSeq
|> computePackageHull kv.Key lockFile

let packages =
allPackages
|> Seq.filter (fun p ->
match targetFilter with
| None -> true
| Some targets ->
let key = kv.Key,p
let resolvedPackage = resolved.Force().[key]

match resolvedPackage.Settings.FrameworkRestrictions with
| Requirements.ExplicitRestriction restrictions ->
targets
|> Array.exists (fun target -> Requirements.isTargetMatchingRestrictions(restrictions, SinglePlatform target))
| _ -> true)


match dependenciesFile.Groups |> Map.tryFind kv.Value.Name with
| None ->
failwithf
"The group %O was found in the %s file but not in the %s file. Please run \"paket install\" again."
kv.Value
Constants.LockFileName
Constants.DependenciesFileName
| Some depFileGroup ->
let packages = Set.ofSeq packages
let overriden =
packages
|> Set.filter (fun p -> LocalFile.overrides localFile (p,depFileGroup.Name))

restore(alternativeProjectRoot, root, kv.Key, depFileGroup.Sources, depFileGroup.Caches, force, lockFile, packages, overriden))
|> Seq.toArray
match dependenciesFile.Groups |> Map.tryFind kv.Value.Name with
| None ->
failwithf
"The group %O was found in the %s file but not in the %s file. Please run \"paket install\" again."
kv.Value
Constants.LockFileName
Constants.DependenciesFileName
| Some depFileGroup ->
let packages = Set.ofSeq packages
let overriden =
packages
|> Set.filter (fun p -> LocalFile.overrides localFile (p,depFileGroup.Name))

restore(alternativeProjectRoot, root, kv.Key, depFileGroup.Sources, depFileGroup.Caches, force, lockFile, packages, overriden))
|> Seq.toArray

RunInLockedAccessMode(
root,
(fun () ->
for task in tasks do
task
|> Async.RunSynchronously
|> ignore

CreateScriptsForGroups dependenciesFile lockFile groups))
RunInLockedAccessMode(
root,
(fun () ->
for task in tasks do
task
|> Async.RunSynchronously
|> ignore

CreateScriptsForGroups dependenciesFile lockFile groups
if targetFrameworks = None && projectFile = None && referencesFileNames = [] then
File.WriteAllText(restoreHashFile, newHash)))
4 changes: 2 additions & 2 deletions src/Paket.Core/PackageManagement/NugetConvert.fs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ let convertR rootDirectory force credsMigrationMode = trial {
return! createResult(rootDirectory, nugetEnv, credsMigrationMode)
}

let replaceNuGetWithPaket initAutoRestore installAfter fromBootstrapper result =
let replaceNuGetWithPaket initAutoRestore installAfter result =
let remove (fi : FileInfo) =
tracefn "Removing %s" fi.FullName
fi.Delete()
Expand Down Expand Up @@ -497,7 +497,7 @@ let replaceNuGetWithPaket initAutoRestore installAfter fromBootstrapper result =

if initAutoRestore && (autoVSPackageRestore || result.NuGetEnv.NuGetTargets.IsSome) then
try
VSIntegration.TurnOnAutoRestore fromBootstrapper result.PaketEnv |> returnOrFail
VSIntegration.TurnOnAutoRestore result.PaketEnv |> returnOrFail
with
| exn ->
traceWarnfn "Could not enable auto restore%sMessage: %s" Environment.NewLine exn.Message
Expand Down
2 changes: 1 addition & 1 deletion src/Paket.Core/PackageManagement/VSIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ let TurnOffAutoRestore environment =
}

/// Activates the Visual Studio NuGet autorestore feature in all projects
let TurnOnAutoRestore fromBootstrapper environment =
let TurnOnAutoRestore environment =
let exeDir = Path.Combine(environment.RootDirectory.FullName, Constants.PaketFolderName)

trial {
Expand Down
29 changes: 6 additions & 23 deletions src/Paket.Core/PublicAPI.fs
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,7 @@ type Dependencies(dependenciesFileName: string) =
static member Init() = Dependencies.Init(Directory.GetCurrentDirectory())

/// Initialize paket.dependencies file in the given directory
static member Init(directory) = Dependencies.Init(directory,false)

/// Initialize paket.dependencies file in the given directory
static member Init(directory,fromBootstrapper) =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While technically a breaking change in the public API - I don't think anyone used these weird overloads.

static member Init(directory) =
let directory = DirectoryInfo(directory)

RunInLockedAccessMode(
Expand All @@ -84,16 +81,10 @@ type Dependencies(dependenciesFileName: string) =
)

let deps = Dependencies.Locate()
deps.DownloadLatestBootstrapper(fromBootstrapper)
deps.DownloadLatestBootstrapper()

/// Converts the solution from NuGet to Paket.
static member ConvertFromNuget(force: bool,installAfter: bool, initAutoRestore: bool,credsMigrationMode: string option, ?directory: DirectoryInfo) : unit =
match directory with
| Some d -> Dependencies.ConvertFromNuget(force, installAfter, initAutoRestore, credsMigrationMode, false, d)
| None -> Dependencies.ConvertFromNuget(force, installAfter, initAutoRestore, credsMigrationMode, false)

/// Converts the solution from NuGet to Paket.
static member ConvertFromNuget(force: bool,installAfter: bool, initAutoRestore: bool,credsMigrationMode: string option, fromBootstrapper, ?directory: DirectoryInfo) : unit =
let dir = defaultArg directory (DirectoryInfo(Directory.GetCurrentDirectory()))
let rootDirectory = dir

Expand All @@ -102,7 +93,7 @@ type Dependencies(dependenciesFileName: string) =
fun () ->
NuGetConvert.convertR rootDirectory force credsMigrationMode
|> returnOrFail
|> NuGetConvert.replaceNuGetWithPaket initAutoRestore installAfter fromBootstrapper
|> NuGetConvert.replaceNuGetWithPaket initAutoRestore installAfter
)

/// Converts the current package dependency graph to the simplest dependency graph.
Expand Down Expand Up @@ -350,12 +341,8 @@ type Dependencies(dependenciesFileName: string) =
|> this.Process
|> List.map (fun (g, p,_,newVersion) -> g.ToString(),p.ToString(),newVersion)

/// Downloads the latest paket.bootstrapper into the .paket folder.
member this.DownloadLatestBootstrapper() : unit =
this.DownloadLatestBootstrapper(false)

/// Downloads the latest paket.bootstrapper into the .paket folder and try to rename it to paket.exe in order to activate magic mode.
member this.DownloadLatestBootstrapper(fromBootstrapper) : unit =
member this.DownloadLatestBootstrapper() : unit =
RunInLockedAccessMode(
this.RootPath,
fun () ->
Expand All @@ -370,14 +357,10 @@ type Dependencies(dependenciesFileName: string) =
| _ ->())

/// Pulls new paket.targets and bootstrapper and puts them into .paket folder.
member this.TurnOnAutoRestore(fromBootstrapper: bool): unit =
member this.TurnOnAutoRestore(): unit =
RunInLockedAccessMode(
this.RootPath,
fun () -> VSIntegration.TurnOnAutoRestore fromBootstrapper |> this.Process)

/// Pulls new paket.targets and bootstrapper and puts them into .paket folder.
member this.TurnOnAutoRestore(): unit =
this.TurnOnAutoRestore(false)
fun () -> VSIntegration.TurnOnAutoRestore |> this.Process)

/// Removes paket.targets file and Import section from project files.
member this.TurnOffAutoRestore(): unit =
Expand Down
8 changes: 4 additions & 4 deletions src/Paket/Paket.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
<StartAction>Project</StartAction>
<StartProgram>paket.exe</StartProgram>
<StartAction>Project</StartAction>
<StartArguments>update</StartArguments>
<StartWorkingDirectory>C:\proj\testing\testpaketfailure\</StartWorkingDirectory>
<StartArguments>restore</StartArguments>
<StartWorkingDirectory>C:\proj\Paket</StartWorkingDirectory>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
Expand All @@ -42,8 +42,8 @@
<WarningLevel>3</WarningLevel>
<DocumentationFile>
</DocumentationFile>
<StartArguments>install -v</StartArguments>
<StartWorkingDirectory>D:\temp\test</StartWorkingDirectory>
<StartArguments>restore</StartArguments>
<StartWorkingDirectory>C:\proj\Paket</StartWorkingDirectory>
</PropertyGroup>
<PropertyGroup>
<VisualStudioVersion Condition=" '$(VisualStudioVersion)' == '' ">14.0</VisualStudioVersion>
Expand Down
Loading