Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull request/refactor update process #843

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
36 changes: 18 additions & 18 deletions src/Paket.Core/AddProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,31 @@ let private addToProject (project : ProjectFile) package =
.AddNuGetReference(package)
.Save()

let private add installToProjects addToProjectsF dependenciesFileName package version force hard installAfter =
let private add installToProjects addToProjectsF dependenciesFileName package version options installAfter =
let existingDependenciesFile = DependenciesFile.ReadFromFile(dependenciesFileName)
let (PackageName name) = package
if (not installToProjects) && existingDependenciesFile.HasPackage package && String.IsNullOrWhiteSpace version then
if (not installToProjects) && existingDependenciesFile.HasPackage package && String.IsNullOrWhiteSpace version then
traceWarnfn "%s contains package %s already." dependenciesFileName name
else
let dependenciesFile =
existingDependenciesFile
.Add(package,version)
let lockFile = UpdateProcess.SelectiveUpdate(dependenciesFile,Some(NormalizedPackageName package),force)

let lockFile = UpdateProcess.SelectiveUpdate(dependenciesFile, Some(NormalizedPackageName package), options.Force)
let projects = seq { for p in ProjectFile.FindAllProjects(Path.GetDirectoryName lockFile.FileName) -> p } // lazy sequence in case no project install required

dependenciesFile.Save()

package |> addToProjectsF projects

if installAfter then
let sources = dependenciesFile.GetAllPackageSources()
InstallProcess.Install(sources, force, hard, false, lockFile)
InstallProcess.Install(sources, { SmartInstallOptions.Default with Common = options }, lockFile)

// Add a package with the option to add it to a specified project.
let AddToProject(dependenciesFileName, package, version, options : InstallerOptions, projectName, installAfter) =

// add a package with the option to add it to a specified project
let AddToProject(dependenciesFileName, package, version, force, hard, projectName, installAfter) =

let addToSpecifiedProject (projects : ProjectFile seq) package =
let addToSpecifiedProject (projects : ProjectFile seq) package =
match ProjectFile.TryFindProject(projects,projectName) with
| Some p ->
if package |> notInstalled p then
Expand All @@ -47,15 +47,15 @@ let AddToProject(dependenciesFileName, package, version, force, hard, projectNam
| None ->
traceErrorfn "Could not install package in specified project %s. Project not found" projectName

add true addToSpecifiedProject dependenciesFileName package version force hard installAfter
// add a package with the option to interactively add it to multiple projects
let Add(dependenciesFileName, package, version, force, hard, interactive, installAfter) =
let addToProjects (projects : ProjectFile seq) package =
add true addToSpecifiedProject dependenciesFileName package version options installAfter

// Add a package with the option to interactively add it to multiple projects.
let Add(dependenciesFileName, package, version, options : InstallerOptions, interactive, installAfter) =

let addToProjects (projects : ProjectFile seq) package =
if interactive then
for project in projects do
if package |> notInstalled project && Utils.askYesNo(sprintf " Install to %s?" project.Name) then
package |> addToProject project
add interactive addToProjects dependenciesFileName package version force hard installAfter

add interactive addToProjects dependenciesFileName package version options installAfter
104 changes: 59 additions & 45 deletions src/Paket.Core/InstallProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ let findPackageFolder root (PackageName name) =
| Some x -> x
| None -> failwithf "Package directory for package %s was not found." name

let private findPackagesWithContent (root,usedPackages:Map<PackageName,PackageInstallSettings>) =
let private findPackagesWithContent (root,usedPackages:Map<PackageName,PackageInstallSettings>) =
usedPackages
|> Seq.filter (fun kv -> defaultArg kv.Value.Settings.OmitContent false |> not)
|> Seq.map (fun kv -> findPackageFolder root kv.Key)
|> Seq.choose (fun packageDir ->
packageDir.GetDirectories("Content")
|> Seq.choose (fun packageDir ->
packageDir.GetDirectories("Content")
|> Array.append (packageDir.GetDirectories("content"))
|> Array.tryFind (fun _ -> true))
|> Seq.toList

let private copyContentFiles (project : ProjectFile, packagesWithContent) =
let private copyContentFiles (project : ProjectFile, packagesWithContent) =

let rules : list<(FileInfo -> bool)> = [
fun f -> f.Name = "_._"
Expand All @@ -49,7 +49,7 @@ let private copyContentFiles (project : ProjectFile, packagesWithContent) =
fromDir.GetDirectories() |> Array.toList
|> List.collect (fun subDir -> copyDirContents(subDir, lazy toDir.Force().CreateSubdirectory(subDir.Name)))
|> List.append
(fromDir.GetFiles()
(fromDir.GetFiles()
|> Array.toList
|> List.filter (onBlackList >> not)
|> List.map (fun file -> file.CopyTo(Path.Combine(toDir.Force().FullName, file.Name), true)))
Expand All @@ -64,40 +64,41 @@ let private removeCopiedFiles (project: ProjectFile) =
removeEmptyDirHierarchy dir.Parent

let removeFilesAndTrimDirs (files: FileInfo list) =
for f in files do
if f.Exists then
for f in files do
if f.Exists then
f.Delete()

let dirsPathsDeepestFirst =
let dirsPathsDeepestFirst =
files
|> Seq.map (fun f -> f.Directory.FullName)
|> Seq.distinct
|> List.ofSeq
|> List.rev

for dirPath in dirsPathsDeepestFirst do
removeEmptyDirHierarchy (DirectoryInfo dirPath)

project.GetPaketFileItems()
project.GetPaketFileItems()
|> List.filter (fun fi -> not <| fi.FullName.Contains(Constants.PaketFilesFolderName))
|> removeFilesAndTrimDirs

let CreateInstallModel(root, sources, force, package) =
async {
let CreateInstallModel(root, sources, force, package) =
async {
let! (package, files, targetsFiles) = RestoreProcess.ExtractPackage(root, sources, force, package)
let (PackageName name) = package.Name
let (PackageName name) = package.Name
let nuspec = Nuspec.Load(root,package.Name)
let files = files |> Array.map (fun fi -> fi.FullName)
let targetsFiles = targetsFiles |> Array.map (fun fi -> fi.FullName)
return package, InstallModel.CreateFromLibs(package.Name, package.Version, package.Settings.FrameworkRestrictions, files, targetsFiles, nuspec)
}

/// Restores the given packages from the lock file.
let createModel(root, sources,force, lockFile:LockFile) =
let createModel(root, sources, force, lockFile : LockFile, packages:Set<NormalizedPackageName>) =
let sourceFileDownloads = RemoteDownload.DownloadSourceFiles(root, lockFile.SourceFiles)
let packageDownloads =

let packageDownloads =
lockFile.ResolvedPackages
|> Map.filter (fun name _ -> packages.Contains name)
|> Seq.map (fun kv -> CreateInstallModel(root,sources,force,kv.Value))
|> Async.Parallel

Expand Down Expand Up @@ -139,17 +140,30 @@ let findAllReferencesFiles root =
|> ProjectFile.FindAllProjects
|> Array.choose (fun p -> ProjectFile.FindReferencesFile(FileInfo(p.FileName))
|> Option.map (fun r -> p, r))
|> Array.map (fun (project,file) ->
try
|> Array.map (fun (project,file) ->
try
ok <| (project, ReferencesFile.FromFile(file))
with _ ->
with _ ->
fail <| ReferencesFileParseError (FileInfo(file)))
|> collect

/// Installs all packages from the lock file.
let InstallIntoProjects(sources,force, hard, withBindingRedirects, lockFile:LockFile, projects) =
let InstallIntoProjects(sources, options : SmartInstallOptions, lockFile : LockFile, projects : (ProjectFile * ReferencesFile) list) =
let packagesToInstall =
if options.OnlyReferenced then
projects
|> Seq.ofList
|> Seq.map (fun (_, referencesFile)->
referencesFile
|> lockFile.GetPackageHull
|> Seq.map (fun p -> NormalizedPackageName p.Key))
|> Seq.concat
else
lockFile.ResolvedPackages
|> Seq.map (fun kv -> kv.Key)

let root = Path.GetDirectoryName lockFile.FileName
let extractedPackages = createModel(root,sources,force, lockFile)
let extractedPackages = createModel(root, sources, options.Common.Force, lockFile, Set.ofSeq packagesToInstall)

let model =
extractedPackages
Expand All @@ -161,29 +175,29 @@ let InstallIntoProjects(sources,force, hard, withBindingRedirects, lockFile:Lock
|> Array.map (fun (p,m) -> NormalizedPackageName p.Name,p)
|> Map.ofArray

for project : ProjectFile, referenceFile in projects do
for project : ProjectFile, referenceFile in projects do
verbosefn "Installing to %s" project.FileName

let usedPackages =
lockFile.GetPackageHull(referenceFile)
|> Seq.map (fun u ->
|> Seq.map (fun u ->
let package = packages.[NormalizedPackageName u.Key]
let referenceFileSettings =
let referenceFileSettings =
referenceFile.NugetPackages
|> List.tryFind (fun x -> NormalizedPackageName x.Name = NormalizedPackageName u.Key)
let copyLocal =
let copyLocal =
match referenceFileSettings with
| Some s -> s.Settings.CopyLocal
| None -> None
let omitContent =
let omitContent =
match referenceFileSettings with
| Some s -> s.Settings.OmitContent
| None -> None
let importTargets =
let importTargets =
match referenceFileSettings with
| Some s -> s.Settings.ImportTargets
| None -> None
let restriktions =
let restriktions =
match referenceFileSettings with
| Some s -> s.Settings.FrameworkRestrictions
| None -> []
Expand All @@ -192,12 +206,12 @@ let InstallIntoProjects(sources,force, hard, withBindingRedirects, lockFile:Lock
u.Key,
{ u.Value with
Settings =
{ u.Value.Settings with
FrameworkRestrictions =
{ u.Value.Settings with
FrameworkRestrictions =
// TODO: This should filter
restriktions @
u.Value.Settings.FrameworkRestrictions @
lockFile.Options.Settings.FrameworkRestrictions @
u.Value.Settings.FrameworkRestrictions @
lockFile.Options.Settings.FrameworkRestrictions @
package.Settings.FrameworkRestrictions

ImportTargets =
Expand Down Expand Up @@ -241,11 +255,11 @@ let InstallIntoProjects(sources,force, hard, withBindingRedirects, lockFile:Lock
|> Seq.map (fun u -> NormalizedPackageName u.Key,u.Value)
|> Map.ofSeq

project.UpdateReferences(model,usedPackageSettings,hard)
project.UpdateReferences(model, usedPackageSettings, options.Common.Hard)

removeCopiedFiles project

let getSingleRemoteFilePath name =
let getSingleRemoteFilePath name =
traceVerbose <| sprintf "Filename %s " name
lockFile.SourceFiles |> List.iter (fun i -> traceVerbose <| sprintf " %s %s " i.Name (i.FilePath root))
let sourceFile = lockFile.SourceFiles |> List.tryFind (fun f -> Path.GetFileName(f.Name) = name)
Expand All @@ -255,28 +269,28 @@ let InstallIntoProjects(sources,force, hard, withBindingRedirects, lockFile:Lock

let gitRemoteItems =
referenceFile.RemoteFiles
|> List.map (fun file ->
{ BuildAction = project.DetermineBuildAction file.Name
|> List.map (fun file ->
{ BuildAction = project.DetermineBuildAction file.Name
Include = createRelativePath project.FileName (getSingleRemoteFilePath file.Name)
Link = Some(if file.Link = "." then Path.GetFileName(file.Name)
else Path.Combine(file.Link, Path.GetFileName(file.Name))) })

let nuGetFileItems =
copyContentFiles(project, findPackagesWithContent(root,usedPackages))
|> List.map (fun file ->
|> List.map (fun file ->
{ BuildAction = project.DetermineBuildAction file.Name
Include = createRelativePath project.FileName file.FullName
Link = None })

project.UpdateFileItems(gitRemoteItems @ nuGetFileItems, hard)
project.UpdateFileItems(gitRemoteItems @ nuGetFileItems, options.Common.Hard)

project.Save()

if withBindingRedirects || lockFile.Options.Redirects then
if options.Common.Redirects || lockFile.Options.Redirects then
applyBindingRedirects root extractedPackages

/// Installs all packages from the lock file.
let Install(sources,force, hard, withBindingRedirects, lockFile:LockFile) =
let root = FileInfo(lockFile.FileName).Directory.FullName
let Install(sources, options : SmartInstallOptions, lockFile : LockFile) =
let root = FileInfo(lockFile.FileName).Directory.FullName
let projects = findAllReferencesFiles root |> returnOrFail
InstallIntoProjects(sources,force,hard,withBindingRedirects,lockFile,projects)
InstallIntoProjects(sources, options, lockFile, projects)
4 changes: 3 additions & 1 deletion src/Paket.Core/NugetConvert.fs
Original file line number Diff line number Diff line change
Expand Up @@ -405,4 +405,6 @@ let replaceNugetWithPaket initAutoRestore installAfter result =
VSIntegration.TurnOnAutoRestore result.PaketEnv |> returnOrFail

if installAfter then
UpdateProcess.Update(result.PaketEnv.DependenciesFile.FileName,true,true,true)
UpdateProcess.Update(
result.PaketEnv.DependenciesFile.FileName,
{ InstallerOptions.Default with Force = true; Hard = true; Redirects = true })
1 change: 1 addition & 0 deletions src/Paket.Core/Paket.Core.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<Compile Include="BindingRedirects.fs" />
<Compile Include="TemplateFile.fs" />
<Compile Include="NupkgWriter.fs" />
<Compile Include="ProcessOptions.fs" />
<Compile Include="InstallProcess.fs" />
<Compile Include="UpdateProcess.fs" />
<Compile Include="RemoveProcess.fs" />
Expand Down
30 changes: 30 additions & 0 deletions src/Paket.Core/ProcessOptions.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace Paket

// Options for UpdateProcess and InstallProcess.
/// Force - Force the download and reinstallation of all packages
/// Hard - Replace package references within project files even if they are not yet adhering
/// to the Paket's conventions (and hence considered manually managed)
/// Redirects - Create binding redirects for the NuGet packages
type InstallerOptions =
{ Force : bool
Hard : bool
Redirects : bool }

static member Default =
{ Force = false
Hard = false
Redirects = false }

static member createLegacyOptions(force, hard, redirects) =
{ InstallerOptions.Default with
Force = force
Hard = hard
Redirects = redirects }

type SmartInstallOptions =
{ Common : InstallerOptions
OnlyReferenced : bool }

static member Default =
{ Common = InstallerOptions.Default
OnlyReferenced = false }
Loading