Skip to content

Commit

Permalink
Handle framework identifiers comparison
Browse files Browse the repository at this point in the history
FrameworkIdentifier instances were compared structurally before but it
was problematic in some cases as '>= net45' matched 'sl40' that wasn't
in the same framework.

Fixes #1124
  • Loading branch information
vbfox committed Oct 15, 2015
1 parent bfa68f5 commit 001ab06
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 17 deletions.
17 changes: 17 additions & 0 deletions src/Paket.Core/FrameworkHandling.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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<_,_>()
Expand Down
8 changes: 4 additions & 4 deletions src/Paket.Core/InstallModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/Paket.Core/PackageResolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
25 changes: 22 additions & 3 deletions src/Paket.Core/Requirements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -221,8 +240,8 @@ let isTargetMatchingRestrictions (restrictions:FrameworkRestrictions) = function
match restriction with
| FrameworkRestriction.Exactly fw -> pf = fw
| FrameworkRestriction.Portable _ -> false
| FrameworkRestriction.AtLeast fw -> pf >= fw
| FrameworkRestriction.Between(min,max) -> pf >= min && pf < max)
| FrameworkRestriction.AtLeast fw -> pf >= fw && pf.IsSameCategoryAs(fw)
| FrameworkRestriction.Between(min,max) -> pf >= min && pf < max && pf.IsSameCategoryAs(min))
| _ ->
restrictions
|> List.exists (fun restriction ->
Expand Down
84 changes: 74 additions & 10 deletions tests/Paket.Tests/RestrictionApplicationSpecs.fs
Original file line number Diff line number Diff line change
@@ -1,19 +1,83 @@
module Packet.RestrictionApplicationSpecs
module Paket.Requirements.RestrictionApplicationSpecs

open System.IO
open Paket
open Paket.Domain
open Chessie.ErrorHandling
open FsUnit
open NUnit.Framework
open TestHelpers
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")
]

[<Test>]
let ``>= net40 does not include silverlight (#1124)`` () =
let ``>= net10 contains all but only dotnet versions (#1124)`` () =
/// https://github.com/fsprojects/Paket/issues/1124
let restrictions = [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))]
let targets = KnownTargetProfiles.DotNetFrameworkProfiles @ KnownTargetProfiles.SilverlightProfiles
let restricted = applyRestrictionsToTargets restrictions targets
let restrictions = [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V1))]
let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles

restricted |> shouldEqual TestTargetProfiles.DotNetFrameworkProfiles

[<Test>]
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

[<Test>]
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

[<Test>]
let ``>= sl30 contains all but only silverlight versions`` () =
let restrictions = [FrameworkRestriction.AtLeast(Silverlight "v3.0")]
let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles

restricted |> shouldEqual KnownTargetProfiles.DotNetFrameworkProfiles
restricted |> shouldEqual TestTargetProfiles.SilverlightProfiles

0 comments on commit 001ab06

Please sign in to comment.