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

Selective update should only update dependent packages #410

Merged
merged 3 commits into from
Dec 1, 2014
Merged
Show file tree
Hide file tree
Changes from all 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
22 changes: 0 additions & 22 deletions nuget/Paket.0.17.2.nuspec

This file was deleted.

24 changes: 0 additions & 24 deletions nuget/Paket.Core.0.17.2.nuspec

This file was deleted.

52 changes: 34 additions & 18 deletions src/Paket.Core/LockFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,35 @@ module LockFileParser =

/// Allows to parse and analyze paket.lock files.
type LockFile(fileName:string,options,resolution:PackageResolution,remoteFiles:ResolvedSourceFile list) =
let lowerCaseResolution =
resolution
|> Map.fold (fun resolution name p -> Map.add name p resolution) Map.empty

member __.SourceFiles = remoteFiles
member __.ResolvedPackages = resolution
member __.FileName = fileName
member __.Options = options

/// Gets all dependencies of the given package
member this.GetAllDependenciesOf(package) =
let usedPackages = HashSet<_>()

let rec addPackage (packageName:PackageName) =
Copy link
Member

Choose a reason for hiding this comment

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

@forki You could refactor it further to use an accumulator parameter, than we can call
addPackage package (HashSet<_>()) and remove this usedPackages.

Copy link
Member

Choose a reason for hiding this comment

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

the same logic is here - maybe could be reused?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes please send PR

Copy link
Member

Choose a reason for hiding this comment

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

Will do

let identity = NormalizedPackageName packageName
match resolution.TryFind identity with
| Some package ->
if usedPackages.Add packageName then
if not this.Options.Strict then
for d,_,_ in package.Dependencies do
addPackage d
| None ->
failwithf "Package %O was referenced, but it was not found in the paket.lock file." packageName

addPackage package

usedPackages

/// Checks if the first package is a dependency of the second package
member this.IsDependencyOf(dependentPackage,package) =
this.GetAllDependenciesOf(package).Contains dependentPackage

/// Updates the Lock file with the analyzed dependencies from the paket.dependencies file.
member __.Save() =
let output =
Expand All @@ -244,26 +264,22 @@ type LockFile(fileName:string,options,resolution:PackageResolution,remoteFiles:R
lockFile.Save()
lockFile

/// Parses a paket.lock file from lines
/// Parses a paket.lock file from file
static member LoadFrom(lockFileName) : LockFile =
LockFileParser.Parse(File.ReadAllLines lockFileName)
LockFile.Parse(lockFileName, File.ReadAllLines lockFileName)

/// Parses a paket.lock file from lines
static member Parse(lockFileName,lines) : LockFile =
LockFileParser.Parse lines
|> fun state -> LockFile(lockFileName, state.Options ,state.Packages |> Seq.fold (fun map p -> Map.add (NormalizedPackageName p.Name) p map) Map.empty, List.rev state.SourceFiles)

member this.GetPackageHull(referencesFile:ReferencesFile) =
let usedPackages = HashSet<_>()

let rec addPackage directly (packageName:PackageName) =
let identity = NormalizedPackageName packageName
match lowerCaseResolution.TryFind identity with
| Some package ->
if usedPackages.Add packageName then
if not this.Options.Strict then
for d,_,_ in package.Dependencies do
addPackage false d
| None ->
failwithf "%s references package %O, but it was not found in the paket.lock file." referencesFile.FileName packageName

referencesFile.NugetPackages
|> List.iter (addPackage true)
|> List.iter (fun package ->
try
usedPackages.UnionWith(this.GetAllDependenciesOf(package))
with exn -> failwithf "%s - in %s" exn.Message referencesFile.FileName)

usedPackages
usedPackages
17 changes: 9 additions & 8 deletions src/Paket.Core/UpdateProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Paket.UpdateProcess
open Paket
open System.IO
open Paket.Domain
open Paket.PackageResolver

/// Update command
let Update(dependenciesFileName, forceResolution, force, hard) =
Expand All @@ -22,14 +23,14 @@ let Update(dependenciesFileName, forceResolution, force, hard) =
InstallProcess.Install(sources, force, hard, lockFile)

let private fixOldDependencies (dependenciesFile:DependenciesFile) (package:PackageName) (oldLockFile:LockFile) =
let packageKeys = dependenciesFile.DirectDependencies |> Seq.map (fun kv -> NormalizedPackageName kv.Key) |> Set.ofSeq
oldLockFile.ResolvedPackages
let allDependencies = oldLockFile.GetAllDependenciesOf package

oldLockFile.ResolvedPackages
|> Seq.map (fun kv -> kv.Value)
|> Seq.filter (fun p -> not <| allDependencies.Contains p.Name)
|> Seq.fold
(fun (dependenciesFile : DependenciesFile) kv ->
let resolvedPackage = kv.Value
let name = NormalizedPackageName resolvedPackage.Name
if name = NormalizedPackageName package || not <| packageKeys.Contains name then dependenciesFile else
dependenciesFile.AddFixedPackage(resolvedPackage.Name, "= " + resolvedPackage.Version.ToString()))
(fun (dependenciesFile : DependenciesFile) resolvedPackage ->
dependenciesFile.AddFixedPackage(resolvedPackage.Name, "= " + resolvedPackage.Version.ToString()))
dependenciesFile

let private update (lockFileName) force (createDependenciesFile:LockFile -> DependenciesFile) =
Expand Down Expand Up @@ -71,4 +72,4 @@ let UpdatePackage(dependenciesFileName, packageName : PackageName, newVersion, f

fixOldDependencies dependenciesFile packageName
|> update lockFileName.FullName force
InstallProcess.Install(sources, force, hard, lockFile)
InstallProcess.Install(sources, force, hard, lockFile)
2 changes: 1 addition & 1 deletion tests/Paket.Tests/Lockfile/GenerateAuthModeSpecs.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module paket.lockFile.GenerateAuthModeSpecs
module Paket.LockFile.GenerateAuthModeSpecs

open Paket
open NUnit.Framework
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module paket.lockFile.GenerateContentNoneOptionSpecs
module Paket.LockFile.GenerateContentNoneOptionSpecs

open Paket
open NUnit.Framework
Expand Down
2 changes: 1 addition & 1 deletion tests/Paket.Tests/Lockfile/GenerateStrictModeSpecs.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module paket.lockFile.GenerateStrictModeSpecs
module Paket.LockFile.GenerateStrictModeSpecs

open Paket
open NUnit.Framework
Expand Down
50 changes: 50 additions & 0 deletions tests/Paket.Tests/Lockfile/QuerySpecs.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module Paket.LockFile.QuerySpecs

open Paket
open NUnit.Framework
open FsUnit
open TestHelpers
open Paket.Domain

let data = """NUGET
remote: https://nuget.org/api/v2
specs:
Castle.Windsor (2.1)
Castle.Windsor-log4net (3.3)
Castle.Windsor (>= 2.0)
log4net (>= 1.0)
Rx-Core (2.1)
Rx-Main (2.0)
Rx-Core (>= 2.1)
log (1.2)
log4net (1.1)
log (>= 1.0)
GITHUB
remote: fsharp/FAKE
specs:
src/app/FAKE/Cli.fs (7699e40e335f3cc54ab382a8969253fecc1e08a9)
src/app/Fake.Deploy.Lib/FakeDeployAgentHelper.fs (Globbing)
"""

let lockFile = LockFile.Parse("Test",toLines data)


[<Test>]
let ``should detect itself as dependency``() =
lockFile.IsDependencyOf(PackageName "Rx-Core",PackageName "Rx-Core")
|> shouldEqual true

[<Test>]
let ``should detect direct dependencies``() =
lockFile.IsDependencyOf(PackageName "Rx-Core",PackageName "Rx-Main")
|> shouldEqual true

[<Test>]
let ``should detect indirect dependencies``() =
lockFile.IsDependencyOf(PackageName "log",PackageName "Castle.Windsor-log4net")
|> shouldEqual true

[<Test>]
let ``should detect when packages are unrelated``() =
lockFile.IsDependencyOf(PackageName "log",PackageName "Rx-Core")
|> shouldEqual false
3 changes: 2 additions & 1 deletion tests/Paket.Tests/Paket.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
Expand Down Expand Up @@ -158,6 +158,7 @@
<Compile Include="Lockfile\GenerateAuthModeSpecs.fs" />
<Compile Include="Lockfile\GeneratorWithMutlipleSourcesSpecs.fs" />
<Compile Include="Lockfile\ParserSpecs.fs" />
<Compile Include="Lockfile\QuerySpecs.fs" />
<Compile Include="Lockfile\ParserWithMultipleSourcesSpecs.fs" />
<Compile Include="ReferencesFile\ReferencesFileSpecs.fs" />
<Compile Include="Simplifier\BasicScenarioSpecs.fs" />
Expand Down