diff --git a/src/Paket.Core/FrameworkHandling.fs b/src/Paket.Core/FrameworkHandling.fs
index 471ae81232..68fba3aa6d 100644
--- a/src/Paket.Core/FrameworkHandling.fs
+++ b/src/Paket.Core/FrameworkHandling.fs
@@ -141,6 +141,23 @@ type FrameworkIdentifier =
| WindowsPhoneApp _ -> [ WindowsPhoneApp "v8.1" ]
| WindowsPhoneSilverlight _ -> [ WindowsPhoneSilverlight "v8.1" ]
+ /// Return if the parameter is of the same framework category (dotnet, windows phone, silverlight, ...)
+ member x.IsSameCategoryAs y =
+ match (x, y) with
+ | DotNetFramework _, DotNetFramework _ -> true
+ | Silverlight _, Silverlight _ -> true
+ | DNX _, DNX _ -> true
+ | DNXCore _, DNXCore _ -> true
+ | MonoAndroid _, MonoAndroid _ -> true
+ | MonoMac _, MonoMac _ -> true
+ | MonoTouch _, MonoTouch _ -> true
+ | Windows _, Windows _ -> true
+ | WindowsPhoneApp _, WindowsPhoneApp _ -> true
+ | WindowsPhoneSilverlight _, WindowsPhoneSilverlight _ -> true
+ | XamarinMac _, XamarinMac _ -> true
+ | XamariniOS _, XamariniOS _ -> true
+ | _ -> false
+
module FrameworkDetection =
let private cache = System.Collections.Concurrent.ConcurrentDictionary<_,_>()
diff --git a/src/Paket.Core/InstallModel.fs b/src/Paket.Core/InstallModel.fs
index 693d2a616b..383806f6cf 100644
--- a/src/Paket.Core/InstallModel.fs
+++ b/src/Paket.Core/InstallModel.fs
@@ -230,21 +230,21 @@ type InstallModel =
restrictions
|> List.exists (fun restriction ->
match restriction with
- | FrameworkRestriction.Portable p ->
+ | FrameworkRestriction.Portable _ ->
folder.Targets
|> List.exists (fun target ->
match target with
- | SinglePlatform t -> false
+ | SinglePlatform _ -> false
| _ -> true)
| FrameworkRestriction.Exactly target ->
folder.GetSinglePlatforms()
|> List.exists (fun t -> t = target)
| FrameworkRestriction.AtLeast target ->
folder.GetSinglePlatforms()
- |> List.exists (fun t -> t >= target)
+ |> List.exists (fun t -> t >= target && t.IsSameCategoryAs(target))
| FrameworkRestriction.Between(min,max) ->
folder.GetSinglePlatforms()
- |> List.exists (fun t -> t >= min && t < max) )
+ |> List.exists (fun t -> t >= min && t < max && t.IsSameCategoryAs(min)))
this.MapFolders(fun folder ->
if referenceApplies folder then
@@ -288,25 +288,7 @@ type InstallModel =
| [] -> this
| restrictions ->
let applRestriction folder =
- { folder with
- Targets =
- folder.Targets
- |> List.filter
- (function
- | SinglePlatform pf ->
- restrictions
- |> List.exists (fun restriction ->
- match restriction with
- | FrameworkRestriction.Exactly fw -> pf = fw
- | FrameworkRestriction.Portable r -> false
- | FrameworkRestriction.AtLeast fw -> pf >= fw
- | FrameworkRestriction.Between(min,max) -> pf >= min && pf < max)
- | _ ->
- restrictions
- |> List.exists (fun restriction ->
- match restriction with
- | FrameworkRestriction.Portable r -> true
- | _ -> false))}
+ { folder with Targets = applyRestrictionsToTargets restrictions folder.Targets}
{this with
ReferenceFileFolders =
diff --git a/src/Paket.Core/PackageResolver.fs b/src/Paket.Core/PackageResolver.fs
index 38c9c78527..1f1ff8e75c 100644
--- a/src/Paket.Core/PackageResolver.fs
+++ b/src/Paket.Core/PackageResolver.fs
@@ -18,6 +18,7 @@ module DependencySetFilter =
match restriction with
| FrameworkRestriction.Exactly v1 ->
restrictions
+ |> Seq.filter (fun r2 -> restriction.IsSameCategoryAs(r2) = Some(true))
|> Seq.exists (fun r2 ->
match r2 with
| FrameworkRestriction.Exactly v2 when v1 = v2 -> true
@@ -26,6 +27,7 @@ module DependencySetFilter =
| _ -> false)
| FrameworkRestriction.AtLeast v1 ->
restrictions
+ |> Seq.filter (fun r2 -> restriction.IsSameCategoryAs(r2) = Some(true))
|> Seq.exists (fun r2 ->
match r2 with
| FrameworkRestriction.Exactly v2 when v1 <= v2 -> true
diff --git a/src/Paket.Core/Requirements.fs b/src/Paket.Core/Requirements.fs
index 7ab980a905..a2ad3dafad 100644
--- a/src/Paket.Core/Requirements.fs
+++ b/src/Paket.Core/Requirements.fs
@@ -19,6 +19,19 @@ type FrameworkRestriction =
| FrameworkRestriction.AtLeast r -> ">= " + r.ToString()
| FrameworkRestriction.Between(min,max) -> sprintf ">= %O < %O" min max
+ member private x.GetOneIdentifier =
+ match x with
+ | Exactly r -> Some r
+ | Portable _ -> None
+ | AtLeast r -> Some r
+ | Between(r, _) -> Some r
+
+ /// Return if the parameter is a restriction of the same framework category (dotnet, windows phone, silverlight, ...)
+ member x.IsSameCategoryAs (y : FrameworkRestriction) =
+ match (x.GetOneIdentifier, y.GetOneIdentifier) with
+ | Some r, Some r' -> Some(r.IsSameCategoryAs r')
+ | _ -> None
+
type FrameworkRestrictions = FrameworkRestriction list
@@ -172,7 +185,7 @@ let optimizeDependencies packages =
yield name,versionRequirement,others @ restrictions]
-let combineRestrictions x y =
+let private combineSameCategoryOrPortableRestrictions x y =
match x with
| FrameworkRestriction.Exactly r ->
match y with
@@ -202,6 +215,12 @@ let combineRestrictions x y =
if min' = max' then [FrameworkRestriction.Exactly(min')] else
[]
+let combineRestrictions (x : FrameworkRestriction) y =
+ if (x.IsSameCategoryAs(y) = Some(false)) then
+ []
+ else
+ combineSameCategoryOrPortableRestrictions x y
+
let filterRestrictions (list1:FrameworkRestrictions) (list2:FrameworkRestrictions) =
match list1,list2 with
| [],_ -> list2
@@ -213,6 +232,29 @@ let filterRestrictions (list1:FrameworkRestrictions) (list2:FrameworkRestriction
if c <> [] then yield! c]
|> optimizeRestrictions
+/// Get if a target should be considered with the specified restrictions
+let isTargetMatchingRestrictions (restrictions:FrameworkRestrictions) = function
+ | SinglePlatform pf ->
+ restrictions
+ |> List.exists (fun restriction ->
+ match restriction with
+ | FrameworkRestriction.Exactly fw -> pf = fw
+ | FrameworkRestriction.Portable _ -> false
+ | FrameworkRestriction.AtLeast fw -> pf >= fw && pf.IsSameCategoryAs(fw)
+ | FrameworkRestriction.Between(min,max) -> pf >= min && pf < max && pf.IsSameCategoryAs(min))
+ | _ ->
+ restrictions
+ |> List.exists (fun restriction ->
+ match restriction with
+ | FrameworkRestriction.Portable r -> true
+ | _ -> false)
+
+/// Get all targets that should be considered with the specified restrictions
+let applyRestrictionsToTargets (restrictions:FrameworkRestrictions) (targets: TargetProfile list) =
+ let result = targets |> List.filter (isTargetMatchingRestrictions restrictions)
+ result
+
+
type ContentCopySettings =
| Omit
| Overwrite
diff --git a/tests/Paket.Tests/Paket.Tests.fsproj b/tests/Paket.Tests/Paket.Tests.fsproj
index a9721aafc3..ea36ef233c 100644
--- a/tests/Paket.Tests/Paket.Tests.fsproj
+++ b/tests/Paket.Tests/Paket.Tests.fsproj
@@ -91,6 +91,7 @@
+
Always
diff --git a/tests/Paket.Tests/RestrictionApplicationSpecs.fs b/tests/Paket.Tests/RestrictionApplicationSpecs.fs
new file mode 100644
index 0000000000..50bc8e175b
--- /dev/null
+++ b/tests/Paket.Tests/RestrictionApplicationSpecs.fs
@@ -0,0 +1,83 @@
+module Paket.Requirements.RestrictionApplicationSpecs
+
+open Paket
+open FsUnit
+open NUnit.Framework
+open Paket.Requirements
+
+let dotnet x = SinglePlatform(DotNetFramework(x))
+
+module TestTargetProfiles =
+ let DotNetFrameworkVersions =
+ [FrameworkVersion.V1
+ FrameworkVersion.V1_1
+ FrameworkVersion.V2
+ FrameworkVersion.V3
+ FrameworkVersion.V3_5
+ FrameworkVersion.V4_Client
+ FrameworkVersion.V4
+ FrameworkVersion.V4_5
+ FrameworkVersion.V4_5_1
+ FrameworkVersion.V4_5_2
+ FrameworkVersion.V4_5_3
+ FrameworkVersion.V4_6]
+
+ let DotNetFrameworkProfiles = DotNetFrameworkVersions |> List.map dotnet
+
+ let WindowsProfiles =
+ [SinglePlatform(Windows "v4.5")
+ SinglePlatform(Windows "v4.5.1")]
+
+ let SilverlightProfiles =
+ [SinglePlatform(Silverlight "v3.0")
+ SinglePlatform(Silverlight "v4.0")
+ SinglePlatform(Silverlight "v5.0")]
+
+ let WindowsPhoneSilverlightProfiles =
+ [SinglePlatform(WindowsPhoneSilverlight "v7.0")
+ SinglePlatform(WindowsPhoneSilverlight "v7.1")
+ SinglePlatform(WindowsPhoneSilverlight "v8.0")
+ SinglePlatform(WindowsPhoneSilverlight "v8.1")]
+
+ let AllProfiles =
+ DotNetFrameworkProfiles @
+ WindowsProfiles @
+ SilverlightProfiles @
+ WindowsPhoneSilverlightProfiles @
+ [SinglePlatform(MonoAndroid)
+ SinglePlatform(MonoTouch)
+ SinglePlatform(XamariniOS)
+ SinglePlatform(XamarinMac)
+ SinglePlatform(WindowsPhoneApp "v8.1")
+ ]
+
+[]
+let ``>= net10 contains all but only dotnet versions (#1124)`` () =
+ /// https://github.com/fsprojects/Paket/issues/1124
+ let restrictions = [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V1))]
+ let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles
+
+ restricted |> shouldEqual TestTargetProfiles.DotNetFrameworkProfiles
+
+[]
+let ``>= net452 contains 4.5.2 and following versions`` () =
+ let restrictions = [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5_2))]
+ let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles
+ let expected = [FrameworkVersion.V4_5_2; FrameworkVersion.V4_5_3; FrameworkVersion.V4_6] |> List.map dotnet
+
+ restricted |> shouldEqual expected
+
+[]
+let ``>= net40 < net451 contains 4.0 and 4.5`` () =
+ let restrictions = [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4), DotNetFramework(FrameworkVersion.V4_5_1))]
+ let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles
+ let expected = [FrameworkVersion.V4; FrameworkVersion.V4_5] |> List.map dotnet
+
+ restricted |> shouldEqual expected
+
+[]
+let ``>= sl30 contains all but only silverlight versions`` () =
+ let restrictions = [FrameworkRestriction.AtLeast(Silverlight "v3.0")]
+ let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles
+
+ restricted |> shouldEqual TestTargetProfiles.SilverlightProfiles
\ No newline at end of file