From 2681e47d4ae02e02867bed329003a9c88b7ba2a9 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Mon, 6 Oct 2014 17:04:57 +0200 Subject: [PATCH] Create a "use exactly this" operator in order to override package conflicts - references #220 --- RELEASE_NOTES.md | 3 +++ src/Paket/PackageResolver.fs | 17 ++++++++++------- src/Paket/Requirements.fs | 5 +++-- src/Paket/VersionRange.fs | 5 +++++ .../Paket.Tests/Resolver/ConflictGraphSpecs.fs | 13 ++++++++++++- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fd4d994336..33e065f852 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,6 @@ +#### 0.4.26 - 06.10.2014 +* Create a "use exactly this" operator in order to override package conflicts - https://github.com/fsprojects/Paket/issues/220 + #### 0.4.25 - 06.10.2014 * Throw if we don't get any versions diff --git a/src/Paket/PackageResolver.fs b/src/Paket/PackageResolver.fs index c6dacbef1c..6f521eaa19 100644 --- a/src/Paket/PackageResolver.fs +++ b/src/Paket/PackageResolver.fs @@ -93,13 +93,13 @@ let Resolve(getVersionsF, getPackageDetailsF, rootDependencies:PackageRequiremen versions | true,versions -> versions - let rec improveModel (filteredVersions,packages:ResolvedPackage list,closed:Set,stillOpen:Set) = + let rec improveModel (filteredVersions:Map,packages:ResolvedPackage list,closed:Set,stillOpen:Set) = if Set.isEmpty stillOpen then let isOk = filteredVersions |> Map.forall (fun _ v -> match v with - | [_] -> true + | [_],_ -> true | _ -> false) if isOk then @@ -110,15 +110,18 @@ let Resolve(getVersionsF, getPackageDetailsF, rootDependencies:PackageRequiremen let dependency = Seq.head stillOpen let rest = stillOpen |> Set.remove dependency - let compatibleVersions = + let compatibleVersions,globalOverride = match Map.tryFind dependency.Name filteredVersions with | None -> let versions = getAllVersions(dependency.Sources,dependency.Name) if Seq.isEmpty versions then failwithf "Couldn't retrieve versions for %s." dependency.Name - versions - | Some versions -> versions - |> List.filter dependency.VersionRequirement.IsInRange + if dependency.VersionRequirement.Range.IsGlobalOverride then + List.filter dependency.VersionRequirement.IsInRange versions,true + else + List.filter dependency.VersionRequirement.IsInRange versions,false + | Some(versions,globalOverride) -> + if globalOverride then versions,true else List.filter dependency.VersionRequirement.IsInRange versions,false let sorted = match dependency.Parent with @@ -134,7 +137,7 @@ let Resolve(getVersionsF, getPackageDetailsF, rootDependencies:PackageRequiremen match state with | Conflict _ -> let exploredPackage = getExploredPackage(dependency.Sources,dependency.Name,versionToExplore) - let newFilteredVersion = Map.add dependency.Name [versionToExplore] filteredVersions + let newFilteredVersion = Map.add dependency.Name ([versionToExplore],globalOverride) filteredVersions let newDependencies = exploredPackage.Dependencies |> Set.map (fun (n,v) -> {dependency with Name = n; VersionRequirement = v; Parent = Package(dependency.Name,versionToExplore) }) diff --git a/src/Paket/Requirements.fs b/src/Paket/Requirements.fs index 7699ef36a7..04e7719c71 100644 --- a/src/Paket/Requirements.fs +++ b/src/Paket/Requirements.fs @@ -25,5 +25,6 @@ type PackageRequirement = interface System.IComparable with member this.CompareTo that = match that with - | :? PackageRequirement as that -> compare (this.Parent,this.Name,this.VersionRequirement) (that.Parent,that.Name,that.VersionRequirement) - | _ -> invalidArg "that" "cannot compare value of different types" \ No newline at end of file + | :? PackageRequirement as that -> + compare (not this.VersionRequirement.Range.IsGlobalOverride,this.Parent,this.Name,this.VersionRequirement) (not that.VersionRequirement.Range.IsGlobalOverride,that.Parent,that.Name,that.VersionRequirement) + | _ -> invalidArg "that" "cannot compare value of different types" diff --git a/src/Paket/VersionRange.fs b/src/Paket/VersionRange.fs index 052a661e88..c75280fae7 100644 --- a/src/Paket/VersionRange.fs +++ b/src/Paket/VersionRange.fs @@ -13,6 +13,7 @@ type PreReleaseStatus = /// Represents version information. type VersionRange = + | OverrideAll of SemVerInfo | Specific of SemVerInfo | Minimum of SemVerInfo | GreaterThan of SemVerInfo @@ -26,6 +27,8 @@ type VersionRange = static member Between(version1,version2) = Range(Including, SemVer.parse version1, SemVer.parse version2, Excluding) + member x.IsGlobalOverride = match x with | OverrideAll _ -> true | _ -> false + type VersionRequirement = | VersionRequirement of VersionRange * PreReleaseStatus /// Checks wether the given version is in the version range @@ -43,6 +46,7 @@ type VersionRequirement = match range with | Specific v -> v = version + | OverrideAll v -> v = version | Minimum v -> v = version || (v <= version && checkPrerelease prerelease version) | GreaterThan v -> v < version && checkPrerelease prerelease version | Maximum v -> v = version || (v >= version && checkPrerelease prerelease version) @@ -74,6 +78,7 @@ type VersionRequirement = override this.ToString() = match this.Range with | Specific v -> v.ToString() + | OverrideAll v -> "== " + v.ToString() | Minimum v -> ">= " + v.ToString() | GreaterThan v -> "> " + v.ToString() | Maximum v -> "<= " + v.ToString() diff --git a/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs b/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs index 49d3978dd7..fda242d072 100644 --- a/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs +++ b/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs @@ -55,4 +55,15 @@ let ``should analyze graph2 and report conflict``() = | Conflict(_,stillOpen) -> let conflicting = stillOpen |> Seq.head conflicting.Name |> shouldEqual "D" - conflicting.VersionRequirement.Range |> shouldEqual (VersionRange.Between("1.6", "1.7")) \ No newline at end of file + conflicting.VersionRequirement.Range |> shouldEqual (VersionRange.Between("1.6", "1.7")) + +[] +let ``should override graph2 conflict to first version``() = + let resolved = resolve graph2 ["A",VersionRange.AtLeast "1.0"; "D",VersionRange.OverrideAll(SemVer.parse "1.4")] + getVersion resolved.["D"] |> shouldEqual "1.4" + + +[] +let ``should override graph2 conflict to second version``() = + let resolved = resolve graph2 ["A",VersionRange.AtLeast "1.0"; "D",VersionRange.OverrideAll(SemVer.parse "1.6")] + getVersion resolved.["D"] |> shouldEqual "1.6" \ No newline at end of file