diff --git a/Paket.sln b/Paket.sln index 8e9e3014d9..9320683307 100644 --- a/Paket.sln +++ b/Paket.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26403.7 +VisualStudioVersion = 15.0.26430.6 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}" EndProject @@ -102,6 +102,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{62D18A EndProjectSection EndProject Global + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU @@ -143,4 +146,7 @@ Global {7C622582-E281-4EAB-AADA-B5893BB89B45} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4} {7234B9B4-8CF5-4E68-AA29-050C087B9246} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4} EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection EndGlobal diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ac241026c1..7360c767c3 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,10 +1,18 @@ -#### 5.0.0-beta005 - 23.05.2017 +#### 5.0.0-beta006 - 24.05.2017 * BUGFIX: Fixed dotnetcore integration: * Paket now properly understands runtime and reference assemblies * Paket now understands the runtime graph and restores runtime dependencies * New API `InstallModel.GetRuntimeAssemblies` and `InstallModel.GetRuntimeLibraries` can be used to retrieve the correct assets for a particular RID and TFM * New command `paket generate-nuspec` * New Command: `FixNuspecs` - Can fix a list of nuspec files now +* New restriction system (https://github.com/fsprojects/Paket/pull/2336): + * Paket is now more accurate in calculating restrictions and referencing libraries + * Paket will convert (lock-)files to a new syntax (but still understands the old syntax), we might revert this within the beta phase + * This should fix a bunch of edge cases and invalid behavior in combination with portable profiles and netstandard + * Add support for net403 (required for some portable profiles) +* PERFORMANCE: Improved performance by pre-loading requests (https://github.com/fsprojects/Paket/pull/2336) +* PERFORMANCE: Report performance in a more detailed way (https://github.com/fsprojects/Paket/pull/2336) +* BREAKING CHANGE: Paket simplify no longer support simplifying restrictions (https://github.com/fsprojects/Paket/pull/2336) * BREAKING CHANGE: Paket.PowerShell is no longer supported * BREAKING CHANGE: `InstallModel` API changed and Paket.Core.dll users might need to adapt * DEPRECATED: `FixNuspec` function is now obsolete, use `FixNuspecs` instead diff --git a/build.fsx b/build.fsx index 378ab331af..24243dc85d 100644 --- a/build.fsx +++ b/build.fsx @@ -288,7 +288,7 @@ let mergePaketTool () = let result = ExecProcess (fun info -> info.FileName <- currentDirectory "packages" "build" "ILRepack" "tools" "ILRepack.exe" - info.Arguments <- sprintf "/verbose /lib:%s /ver:%s /out:%s %s" buildDir release.AssemblyVersion paketFile toPack + info.Arguments <- sprintf "/lib:%s /ver:%s /out:%s %s" buildDir release.AssemblyVersion paketFile toPack ) (TimeSpan.FromMinutes 5.) if result <> 0 then failwithf "Error during ILRepack execution." @@ -305,6 +305,8 @@ Target "MergePaketTool" (fun _ -> Target "RunIntegrationTests" (fun _ -> mergePaketTool () + // improves the speed of the test-suite by disabling the runtime resolution. + System.Environment.SetEnvironmentVariable("PAKET_DISABLE_RUNTIME_RESOLUTION", "true") !! integrationTestAssemblies |> NUnit3 (fun p -> { p with diff --git a/docs/content/dependencies-file.md b/docs/content/dependencies-file.md index 64bd443cc6..3a6a4476c4 100644 --- a/docs/content/dependencies-file.md +++ b/docs/content/dependencies-file.md @@ -92,6 +92,10 @@ Sometimes you don't want to generate dependencies for older framework versions. nuget Example >= 2.0 // only .NET 3.5 and .NET 4.0 +It means + +> Paket, I only compile for 'net35' and 'net40', please leave out all other stuff I don't need to compile for this set of frameworks. + #### Automatic framework detection Paket can detect the target frameworks from your project and then limit the installation to these target frameworks. You can control this in the [`paket.dependencies` file](dependencies-file.html): diff --git a/docs/content/nuget-dependencies.md b/docs/content/nuget-dependencies.md index 27890d9a76..fc0cc214d1 100644 --- a/docs/content/nuget-dependencies.md +++ b/docs/content/nuget-dependencies.md @@ -183,6 +183,16 @@ Sometimes you don't want to generate dependencies for older framework versions. nuget Example >= 2.0 framework: net35, net40 // .NET 3.5 and .NET 4.0 nuget Example >= 2.0 framework: >= net45 // .NET 4.5 and above +> Note: This feature is deprecated and can be seen as an expert feature. +> Using framework restrictions on single packages might make you projects uncompilable. +> The recommended way is to globally (on a group) specifiy the frameworks you want to compile for. + +This feature basically tells paket to only consider the specified frameworks for this package. +It means + +> Paket I use 'Example' only to compile against 'net35' and 'net40'. +> I never need this package to compile for another framework like 'net45'." + ### Putting the version no. into the path If you need to be NuGet compatible and want to have the version no. in the package path you can do the following: diff --git a/docs/content/references-files.md b/docs/content/references-files.md index 7ed64c3d31..70670a8352 100644 --- a/docs/content/references-files.md +++ b/docs/content/references-files.md @@ -66,6 +66,18 @@ Sometimes you don't want to generate dependencies for older framework versions. Newtonsoft.Json framework: net35, net40 DotNetZip framework: >= net45 +> Note: This feature is deprecated and can be seen as an expert feature. +> Using framework restrictions on single packages might make you projects uncompilable. +> The recommended way is to globally (on a group) specifiy the frameworks you want to compile for. + +This feature basically tells paket to only consider the specified frameworks for this package on this particular project. +The resolution will not be modified when restrictions are specified in the reference file. +It means + +> In this project 'Newtonsoft.Json' is only required when compiling against 'net35' or 'net40'. +> I never need this package to compile for another framework like 'net45', therefore don't add references for other frameworks. + + ## Redirects settings You can instruct Paket to create assembly binding redirects for NuGet packages: diff --git a/integrationtests/Paket.IntegrationTests/ConvertFromNuGetSpecs.fs b/integrationtests/Paket.IntegrationTests/ConvertFromNuGetSpecs.fs index bfec0594b0..d0f08a5f9b 100644 --- a/integrationtests/Paket.IntegrationTests/ConvertFromNuGetSpecs.fs +++ b/integrationtests/Paket.IntegrationTests/ConvertFromNuGetSpecs.fs @@ -44,13 +44,13 @@ let ``#1225 should convert simple C# project with non-matching framework restric requirement.Name |> shouldEqual (PackageName "Castle.Core") requirement.VersionRequirement.ToString() |> shouldEqual "3.3.3" requirement.ResolverStrategyForTransitives |> shouldEqual None - requirement.Settings.FrameworkRestrictions |> getRestrictionList |> shouldEqual [FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))] + requirement.Settings.FrameworkRestrictions |> getExplicitRestriction |> shouldEqual (FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))) let requirement2 = depsFile.GetGroup(Constants.MainDependencyGroup).Packages.Tail.Head requirement2.Name |> shouldEqual (PackageName "Newtonsoft.Json") requirement2.VersionRequirement.ToString() |> shouldEqual "7.0.1" requirement2.ResolverStrategyForTransitives |> shouldEqual None - requirement2.Settings.FrameworkRestrictions |> getRestrictionList |> shouldEqual [FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))] + requirement2.Settings.FrameworkRestrictions |> getExplicitRestriction |> shouldEqual (FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))) [] let ``#1217 should replace packages.config files in project``() = diff --git a/integrationtests/Paket.IntegrationTests/FrameworkRestrictionsSpecs.fs b/integrationtests/Paket.IntegrationTests/FrameworkRestrictionsSpecs.fs index d0b34b169d..c5df0125d7 100644 --- a/integrationtests/Paket.IntegrationTests/FrameworkRestrictionsSpecs.fs +++ b/integrationtests/Paket.IntegrationTests/FrameworkRestrictionsSpecs.fs @@ -1,4 +1,5 @@ module Paket.IntegrationTests.FrameworkRestrictionsSpecs + open Fake open Paket open System @@ -13,8 +14,8 @@ open Paket.Requirements let ``#140 windsor should resolve framework dependent dependencies``() = let lockFile = update "i000140-resolve-framework-restrictions" lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "TaskParallelLibrary"].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V3_5))] + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V3_5), DotNetFramework(FrameworkVersion.V4))) [] let ``#1182 framework restrictions overwrite each other``() = @@ -27,11 +28,10 @@ let ``#1182 framework restrictions overwrite each other``() = [] // PATH TOO LONG on Windows... let ``#1190 paket add nuget should handle transitive dependencies``() = paket "add nuget xunit version 2.1.0" "i001190-transitive-dependencies-with-restr" |> ignore - let lockFile = LockFile.LoadFrom(Path.Combine(scenarioTempPath "i001190-transitive-dependencies-with-restr","paket.lock")) lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "xunit.abstractions"].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldContain (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))) + |> getExplicitRestriction + |> fun res -> res.ToString() |> shouldEqual "|| (>= dnx451) (>= dnxcore50) (>= portable-net45+win8+wp8+wpa81)" [] let ``#1190 paket add nuget should handle transitive dependencies with restrictions``() = @@ -39,8 +39,8 @@ let ``#1190 paket add nuget should handle transitive dependencies with restricti let lockFile = LockFile.LoadFrom(Path.Combine(scenarioTempPath "i001190-transitive-deps","paket.lock")) lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "xunit.abstractions"].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual [] + |> getExplicitRestriction + |> shouldEqual FrameworkRestriction.NoRestriction [] @@ -56,24 +56,29 @@ let ``#1213 framework dependencies propagate``() = let lockFile = update "i001213-framework-propagation" lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "Newtonsoft.Json"].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual [] + |> getExplicitRestriction + |> shouldEqual FrameworkRestriction.NoRestriction [] let ``#1215 framework dependencies propagate``() = let lockFile = update "i001215-framework-propagation-no-restriction" lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "Microsoft.Bcl.Async"].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual [] + |> getExplicitRestriction + |> shouldEqual FrameworkRestriction.NoRestriction [] let ``#1232 framework dependencies propagate``() = let lockFile = update "i001232-sql-lite" - - lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "System.Data.SQLite.Core"].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldContain (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_Client))) + let restriction = + lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "System.Data.SQLite.Core"].Settings.FrameworkRestrictions + |> getExplicitRestriction + (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4), DotNetFramework(FrameworkVersion.V4_5))).IsSubsetOf restriction + |> shouldEqual true + (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4_5), DotNetFramework(FrameworkVersion.V4_5_1))).IsSubsetOf restriction + |> shouldEqual true + (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_6))).IsSubsetOf restriction + |> shouldEqual true [] let ``#1494 detect platform 5.0``() = diff --git a/integrationtests/Paket.IntegrationTests/PackSpecs.fs b/integrationtests/Paket.IntegrationTests/PackSpecs.fs index 4103adfb6a..23cbd95df7 100644 --- a/integrationtests/Paket.IntegrationTests/PackSpecs.fs +++ b/integrationtests/Paket.IntegrationTests/PackSpecs.fs @@ -11,6 +11,8 @@ open System.IO.Compression open Paket.Domain open Paket +let getDependencies = Paket.NuGet.NuGetPackageCache.getDependencies + [] let ``#1234 empty assembly name``() = let outPath = Path.Combine(scenarioTempPath "i001234-missing-assemblyname","out") @@ -96,9 +98,9 @@ let ``#1429 pack deps from template``() = NuGetV2.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0") |> Async.RunSynchronously - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldNotContain (PackageName "PaketBug2") // it's not packed in same round - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldNotContain (PackageName "PaketBug") + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldNotContain (PackageName "PaketBug2") // it's not packed in same round + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldNotContain (PackageName "PaketBug") File.Delete(Path.Combine(scenarioTempPath "i001429-pack-deps","PaketBug","paket.template")) @@ -112,9 +114,9 @@ let ``#1429 pack deps``() = NuGetV2.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0") |> Async.RunSynchronously - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "PaketBug2") - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldNotContain (PackageName "PaketBug") + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "PaketBug2") + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldNotContain (PackageName "PaketBug") File.Delete(Path.Combine(scenarioTempPath "i001429-pack-deps","PaketBug","paket.template")) @@ -128,8 +130,8 @@ let ``#1429 pack deps using minimum-from-lock-file``() = NuGetV2.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0") |> Async.RunSynchronously - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") - let packageName, versionRequirement, restrictions = details.Dependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") + let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head versionRequirement |> shouldNotEqual (VersionRequirement.AllReleases) File.Delete(Path.Combine(scenarioTempPath "i001429-pack-deps-minimum-from-lock","PaketBug","paket.template")) @@ -144,8 +146,8 @@ let ``#1429 pack deps without minimum-from-lock-file uses dependencies file rang NuGetV2.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0") |> Async.RunSynchronously - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") - let packageName, versionRequirement, restrictions = details.Dependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") + let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head versionRequirement |> shouldEqual (VersionRequirement.Parse "1.2.3") File.Delete(Path.Combine(scenarioTempPath "i001429-pack-deps-minimum-from-lock","PaketBug","paket.template")) @@ -160,8 +162,8 @@ let ``#1429 pack deps without minimum-from-lock-file uses specifc dependencies f NuGetV2.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0") |> Async.RunSynchronously - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") - let packageName, versionRequirement, restrictions = details.Dependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") + let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head versionRequirement |> shouldEqual (VersionRequirement.Parse "[2.3.4]") File.Delete(Path.Combine(scenarioTempPath "i001429-pack-deps-specific","PaketBug","paket.template")) @@ -176,8 +178,8 @@ let ``#1429 pack deps with minimum-from-lock-file uses specifc dependencies file NuGetV2.getDetailsFromLocalNuGetPackage false None outPath "" (PackageName "PaketBug") (SemVer.Parse "1.0.0.0") |> Async.RunSynchronously - details.Dependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") - let packageName, versionRequirement, restrictions = details.Dependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head + details |> getDependencies |> List.map (fun (x,_,_) -> x) |> shouldContain (PackageName "MySql.Data") + let packageName, versionRequirement, restrictions = details |> getDependencies |> List.filter (fun (x,_,_) -> x = PackageName "MySql.Data") |> List.head versionRequirement |> shouldEqual (VersionRequirement.Parse "[2.3.4]") File.Delete(Path.Combine(scenarioTempPath "i001429-pack-deps-specific","PaketBug","paket.template")) diff --git a/integrationtests/Paket.IntegrationTests/TestHelper.fs b/integrationtests/Paket.IntegrationTests/TestHelper.fs index bf0ecfc27f..28481e7647 100644 --- a/integrationtests/Paket.IntegrationTests/TestHelper.fs +++ b/integrationtests/Paket.IntegrationTests/TestHelper.fs @@ -10,6 +10,7 @@ open System open System.IO let scenarios = System.Collections.Generic.List<_>() +let isLiveUnitTesting = AppDomain.CurrentDomain.GetAssemblies() |> Seq.exists (fun a -> a.GetName().Name = "Microsoft.CodeAnalysis.LiveUnitTesting.Runtime") let paketToolPath = FullName(__SOURCE_DIRECTORY__ + "../../../bin/paket.exe") let integrationTestPath = FullName(__SOURCE_DIRECTORY__ + "../../../integrationtests/scenarios") @@ -26,6 +27,7 @@ let cleanupAllScenarios() = scenarios.Clear() let prepare scenario = + if isLiveUnitTesting then Assert.Inconclusive("Integration tests are disabled when in a Live-Unit-Session") if scenarios.Count > 10 then cleanupAllScenarios() diff --git a/integrationtests/Paket.IntegrationTests/UpdatePackageSpecs.fs b/integrationtests/Paket.IntegrationTests/UpdatePackageSpecs.fs index 077fc06a4c..6effa1c446 100644 --- a/integrationtests/Paket.IntegrationTests/UpdatePackageSpecs.fs +++ b/integrationtests/Paket.IntegrationTests/UpdatePackageSpecs.fs @@ -87,12 +87,12 @@ let ``#1117 can understand portable``() = let lockFile = LockFile.LoadFrom(Path.Combine(scenarioTempPath "i001117-aws","paket.lock")) let restrictions = lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "PCLStorage"].Settings.FrameworkRestrictions match restrictions with - | FrameworkRestrictionList l -> l.ToString() |> shouldEqual ("[portable-net45+win8+wp8+wpa81]") + | ExplicitRestriction l -> l.ToString() |> shouldEqual ("&& (< net45) (>= portable-net45+win8+wp8+wpa81)") | _ -> failwith "wrong" let restrictions = lockFile.Groups.[Constants.MainDependencyGroup].Resolution.[PackageName "Microsoft.Bcl.Async"].Settings.FrameworkRestrictions match restrictions with - | FrameworkRestrictionList l -> l.ToString() |> shouldEqual ("[portable-net45+win8+wp8+wpa81]") + | ExplicitRestriction l -> l.ToString() |> shouldEqual ("&& (< portable-net45+monoandroid+monotouch+xamarinios+xamarinmac+win8+wp8+wpa81) (>= portable-net45+win8+wp8+wpa81)") | _ -> failwith "wrong" [] diff --git a/integrationtests/scenarios/i000346-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i000346-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate index cb43b7b0d2..8773240f20 100644 --- a/integrationtests/scenarios/i000346-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i000346-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate @@ -62,7 +62,7 @@ - + ..\..\packages\Dapper\lib\net40\Dapper.dll diff --git a/integrationtests/scenarios/i001145-excludes/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i001145-excludes/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate index 168a732d47..400212ae02 100644 --- a/integrationtests/scenarios/i001145-excludes/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i001145-excludes/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate @@ -62,7 +62,7 @@ - + ..\..\packages\Dapper\lib\net40\Dapper.dll diff --git a/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate index 1a20be9070..f73653c2e1 100644 --- a/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate @@ -62,7 +62,7 @@ - + ..\..\packages\Dapper\lib\net40\Dapper.dll diff --git a/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary.csprojtemplate index d7878977ed..12b9a45723 100644 --- a/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary.csprojtemplate @@ -282,7 +282,7 @@ - + ..\..\packages\Dapper\lib\net40\Dapper.dll diff --git a/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary3/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary3/MyClassLibrary.csprojtemplate index cd3e3a1ded..1cab8d97a5 100644 --- a/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary3/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i001219-props-files/before/MyClassLibrary/MyClassLibrary3/MyClassLibrary.csprojtemplate @@ -282,7 +282,7 @@ - + ..\..\packages\Dapper\lib\net40\Dapper.dll diff --git a/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate index 4eecdc10f7..15f4fc9b27 100644 --- a/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate @@ -76,7 +76,7 @@ - + ..\..\packages\AlphaFS\lib\net40\AlphaFS.dll diff --git a/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary2.csprojtemplate b/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary2.csprojtemplate index 4eecdc10f7..15f4fc9b27 100644 --- a/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary2.csprojtemplate +++ b/integrationtests/scenarios/i001270-force-redirects/before/MyClassLibrary/MyClassLibrary2/MyClassLibrary2.csprojtemplate @@ -76,7 +76,7 @@ - + ..\..\packages\AlphaFS\lib\net40\AlphaFS.dll diff --git a/integrationtests/scenarios/i001270-net461/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i001270-net461/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate index 197efe975c..6fb3d8bc09 100644 --- a/integrationtests/scenarios/i001270-net461/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i001270-net461/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate @@ -64,7 +64,7 @@ - + True diff --git a/integrationtests/scenarios/i001333-dup-refs/before/ConsoleApplication1/ConsoleApplication1.fsprojtemplate b/integrationtests/scenarios/i001333-dup-refs/before/ConsoleApplication1/ConsoleApplication1.fsprojtemplate index 42282c2618..965dc7f76f 100644 --- a/integrationtests/scenarios/i001333-dup-refs/before/ConsoleApplication1/ConsoleApplication1.fsprojtemplate +++ b/integrationtests/scenarios/i001333-dup-refs/before/ConsoleApplication1/ConsoleApplication1.fsprojtemplate @@ -80,7 +80,7 @@ - + ..\packages\FSharp.Core\lib\net40\FSharp.Core.dll @@ -89,16 +89,7 @@ - - - - ..\packages\FSharp.Core\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll - True - True - - - - + ..\packages\FSharp.Core\lib\portable-net45+netcore45\FSharp.Core.dll @@ -116,7 +107,7 @@ - + ..\packages\FSharp.Core\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Core.dll @@ -136,7 +127,7 @@ - + True @@ -157,7 +148,7 @@ - + ..\packages\FSharp.Data\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Data.dll @@ -177,7 +168,7 @@ - + ..\packages\Microsoft.Azure.KeyVault.Core\lib\net40\Microsoft.Azure.KeyVault.Core.dll @@ -186,7 +177,7 @@ - + ..\packages\Microsoft.Azure.KeyVault.Core\lib\portable-net45+wp8+wpa81+win\Microsoft.Azure.KeyVault.Core.dll @@ -197,7 +188,7 @@ - + ..\packages\Microsoft.Data.Edm\lib\net40\Microsoft.Data.Edm.dll @@ -206,7 +197,7 @@ - + ..\packages\Microsoft.Data.Edm\lib\portable-net45+wp8+win8+wpa\Microsoft.Data.Edm.dll @@ -217,7 +208,7 @@ - + ..\packages\Microsoft.Data.OData\lib\net40\Microsoft.Data.OData.dll @@ -226,7 +217,7 @@ - + ..\packages\Microsoft.Data.OData\lib\portable-net45+wp8+win8+wpa\Microsoft.Data.OData.dll @@ -237,7 +228,7 @@ - + ..\packages\Microsoft.Data.Services.Client\lib\net40\Microsoft.Data.Services.Client.dll @@ -248,7 +239,7 @@ - + ..\packages\Newtonsoft.Json\lib\net40\Newtonsoft.Json.dll @@ -266,7 +257,7 @@ - + ..\packages\Newtonsoft.Json\lib\netstandard1.0\Newtonsoft.Json.dll @@ -286,7 +277,7 @@ - + ..\packages\System.Spatial\lib\net40\System.Spatial.dll @@ -295,7 +286,7 @@ - + ..\packages\System.Spatial\lib\portable-net45+wp8+win8+wpa\System.Spatial.dll @@ -306,7 +297,7 @@ - + True @@ -351,7 +342,7 @@ - + True @@ -368,7 +359,7 @@ - + ..\packages\Zlib.Portable\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll diff --git a/integrationtests/scenarios/i001467-cpp/before/MyClassLibrary/ConsoleApplication1/ConsoleApplication1.vcxprojtemplate b/integrationtests/scenarios/i001467-cpp/before/MyClassLibrary/ConsoleApplication1/ConsoleApplication1.vcxprojtemplate index 15bd38f125..be36d7a5b2 100644 --- a/integrationtests/scenarios/i001467-cpp/before/MyClassLibrary/ConsoleApplication1/ConsoleApplication1.vcxprojtemplate +++ b/integrationtests/scenarios/i001467-cpp/before/MyClassLibrary/ConsoleApplication1/ConsoleApplication1.vcxprojtemplate @@ -119,7 +119,7 @@ - + ..\..\packages\Newtonsoft.Json\lib\net40\Newtonsoft.Json.dll @@ -137,7 +137,7 @@ - + ..\..\packages\Newtonsoft.Json\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll @@ -146,7 +146,7 @@ - + ..\..\packages\Newtonsoft.Json\lib\portable-net45+wp80+win8+wpa81+dnxcore50\Newtonsoft.Json.dll diff --git a/integrationtests/scenarios/i001578-transitive-ref/before/TestPaketDotNet/TestPaketDotNet.csprojtemplate b/integrationtests/scenarios/i001578-transitive-ref/before/TestPaketDotNet/TestPaketDotNet.csprojtemplate index 7c044282de..6d73c4ef24 100644 --- a/integrationtests/scenarios/i001578-transitive-ref/before/TestPaketDotNet/TestPaketDotNet.csprojtemplate +++ b/integrationtests/scenarios/i001578-transitive-ref/before/TestPaketDotNet/TestPaketDotNet.csprojtemplate @@ -113,7 +113,7 @@ - + ..\packages\Octokit\lib\netcore451\Octokit.dll @@ -122,7 +122,7 @@ - + ..\packages\Octokit\lib\portable-net45+wp80+win+wpa81\Octokit.dll diff --git a/integrationtests/scenarios/i001732-lowercase-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i001732-lowercase-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate index cb43b7b0d2..8773240f20 100644 --- a/integrationtests/scenarios/i001732-lowercase-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i001732-lowercase-aliases/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate @@ -62,7 +62,7 @@ - + ..\..\packages\Dapper\lib\net40\Dapper.dll diff --git a/integrationtests/scenarios/i002335-razorengine/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate b/integrationtests/scenarios/i002335-razorengine/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate index 48fbab50a0..ea303a1e1f 100644 --- a/integrationtests/scenarios/i002335-razorengine/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate +++ b/integrationtests/scenarios/i002335-razorengine/before/MyClassLibrary/MyClassLibrary/MyClassLibrary.csprojtemplate @@ -396,7 +396,7 @@ - + ..\..\packages\razor4\Microsoft.AspNetCore.Razor\lib\netstandard1.3\Microsoft.AspNetCore.Razor.dll @@ -419,7 +419,7 @@ - + ..\..\packages\razor4\Microsoft.Win32.Primitives\ref\netstandard1.3\Microsoft.Win32.Primitives.dll @@ -469,7 +469,7 @@ - + ..\..\packages\razor4\System.AppContext\ref\netstandard\_._ @@ -492,7 +492,7 @@ - + ..\..\packages\razor4\System.AppContext\lib\netstandard1.6\System.AppContext.dll @@ -503,7 +503,7 @@ - + ..\..\packages\razor4\System.Buffers\lib\netstandard1.1\System.Buffers.dll @@ -514,7 +514,7 @@ - + ..\..\packages\razor4\System.Collections\ref\netstandard1.3\System.Collections.dll @@ -530,7 +530,7 @@ - + ..\..\packages\razor4\System.Collections.Concurrent\lib\netstandard1.3\System.Collections.Concurrent.dll @@ -539,7 +539,7 @@ - + ..\..\packages\razor4\System.Collections.Concurrent\ref\netstandard1.3\System.Collections.Concurrent.dll @@ -573,7 +573,7 @@ - + ..\..\packages\razor4\System.Console\ref\netstandard1.3\System.Console.dll @@ -589,7 +589,7 @@ - + ..\..\packages\razor4\System.Diagnostics.Debug\ref\netstandard1.3\System.Diagnostics.Debug.dll @@ -623,7 +623,7 @@ - + ..\..\packages\razor4\System.Diagnostics.DiagnosticSource\lib\netstandard1.3\System.Diagnostics.DiagnosticSource.dll @@ -634,7 +634,7 @@ - + ..\..\packages\razor4\System.Diagnostics.Tools\ref\netstandard1.0\System.Diagnostics.Tools.dll @@ -682,7 +682,7 @@ - + ..\..\packages\razor4\System.Diagnostics.Tracing\ref\netstandard1.5\System.Diagnostics.Tracing.dll @@ -698,7 +698,7 @@ - + ..\..\packages\razor4\System.Globalization\ref\netstandard1.3\System.Globalization.dll @@ -732,7 +732,7 @@ - + ..\..\packages\razor4\System.Globalization.Calendars\ref\netstandard1.3\System.Globalization.Calendars.dll @@ -766,7 +766,7 @@ - + ..\..\packages\razor4\System.Globalization.Extensions\ref\netstandard1.3\System.Globalization.Extensions.dll @@ -814,7 +814,7 @@ - + ..\..\packages\razor4\System.IO\ref\netstandard1.5\System.IO.dll @@ -855,7 +855,7 @@ - + ..\..\packages\razor4\System.IO.Compression\ref\netstandard1.3\System.IO.Compression.dll @@ -892,7 +892,7 @@ - + ..\..\packages\razor4\System.IO.Compression.ZipFile\lib\netstandard1.3\System.IO.Compression.ZipFile.dll @@ -901,7 +901,7 @@ - + ..\..\packages\razor4\System.IO.Compression.ZipFile\ref\netstandard1.3\System.IO.Compression.ZipFile.dll @@ -935,7 +935,7 @@ - + ..\..\packages\razor4\System.IO.FileSystem\ref\netstandard1.3\System.IO.FileSystem.dll @@ -969,7 +969,7 @@ - + ..\..\packages\razor4\System.IO.FileSystem.Primitives\lib\netstandard1.3\System.IO.FileSystem.Primitives.dll @@ -978,7 +978,7 @@ - + ..\..\packages\razor4\System.IO.FileSystem.Primitives\ref\netstandard1.3\System.IO.FileSystem.Primitives.dll @@ -1026,7 +1026,7 @@ - + ..\..\packages\razor4\System.Linq\lib\netstandard1.6\System.Linq.dll @@ -1035,7 +1035,7 @@ - + ..\..\packages\razor4\System.Linq\ref\netstandard1.6\System.Linq.dll @@ -1083,7 +1083,7 @@ - + ..\..\packages\razor4\System.Linq.Expressions\lib\netstandard1.6\System.Linq.Expressions.dll @@ -1092,7 +1092,7 @@ - + ..\..\packages\razor4\System.Linq.Expressions\ref\netstandard1.6\System.Linq.Expressions.dll @@ -1133,7 +1133,7 @@ - + ..\..\packages\razor4\System.Net.Http\ref\netstandard1.3\System.Net.Http.dll @@ -1144,7 +1144,7 @@ - + ..\..\packages\razor4\System.Net.Primitives\ref\netstandard1.3\System.Net.Primitives.dll @@ -1178,7 +1178,7 @@ - + ..\..\packages\razor4\System.Net.Sockets\ref\netstandard1.3\System.Net.Sockets.dll @@ -1194,7 +1194,7 @@ - + ..\..\packages\razor4\System.ObjectModel\lib\netstandard1.3\System.ObjectModel.dll @@ -1203,7 +1203,7 @@ - + ..\..\packages\razor4\System.ObjectModel\ref\netstandard1.3\System.ObjectModel.dll @@ -1251,7 +1251,7 @@ - + ..\..\packages\razor4\System.Reflection\ref\netstandard1.5\System.Reflection.dll @@ -1267,7 +1267,7 @@ - + ..\..\packages\razor4\System.Reflection.Emit\ref\netstandard1.1\System.Reflection.Emit.dll @@ -1281,7 +1281,7 @@ - + ..\..\packages\razor4\System.Reflection.Emit\lib\netstandard1.3\System.Reflection.Emit.dll @@ -1292,7 +1292,7 @@ - + ..\..\packages\razor4\System.Reflection.Emit.ILGeneration\ref\netstandard1.0\System.Reflection.Emit.ILGeneration.dll @@ -1306,7 +1306,7 @@ - + ..\..\packages\razor4\System.Reflection.Emit.ILGeneration\lib\netstandard1.3\System.Reflection.Emit.ILGeneration.dll @@ -1317,7 +1317,7 @@ - + ..\..\packages\razor4\System.Reflection.Emit.Lightweight\ref\netstandard1.0\System.Reflection.Emit.Lightweight.dll @@ -1331,7 +1331,7 @@ - + ..\..\packages\razor4\System.Reflection.Emit.Lightweight\lib\netstandard1.3\System.Reflection.Emit.Lightweight.dll @@ -1342,7 +1342,7 @@ - + ..\..\packages\razor4\System.Reflection.Extensions\ref\netstandard1.0\System.Reflection.Extensions.dll @@ -1358,7 +1358,7 @@ - + ..\..\packages\razor4\System.Reflection.Primitives\ref\netstandard1.0\System.Reflection.Primitives.dll @@ -1408,7 +1408,7 @@ - + ..\..\packages\razor4\System.Reflection.TypeExtensions\lib\netstandard1.5\System.Reflection.TypeExtensions.dll @@ -1417,7 +1417,7 @@ - + ..\..\packages\razor4\System.Reflection.TypeExtensions\ref\netstandard1.5\System.Reflection.TypeExtensions.dll @@ -1433,7 +1433,7 @@ - + ..\..\packages\razor4\System.Resources.ResourceManager\ref\netstandard1.0\System.Resources.ResourceManager.dll @@ -1491,7 +1491,7 @@ - + ..\..\packages\razor4\System.Runtime\ref\netstandard1.5\System.Runtime.dll @@ -1539,7 +1539,7 @@ - + ..\..\packages\razor4\System.Runtime.Extensions\ref\netstandard1.5\System.Runtime.Extensions.dll @@ -1555,7 +1555,7 @@ - + ..\..\packages\razor4\System.Runtime.Handles\ref\netstandard1.3\System.Runtime.Handles.dll @@ -1605,6 +1605,15 @@ + + + + ..\..\packages\razor4\System.Runtime.InteropServices\ref\netcoreapp1.1\System.Runtime.InteropServices.dll + False + True + + + @@ -1619,7 +1628,7 @@ - + ..\..\packages\razor4\System.Runtime.InteropServices\ref\netstandard1.5\System.Runtime.InteropServices.dll @@ -1644,7 +1653,7 @@ - + ..\..\packages\razor4\System.Runtime.InteropServices.RuntimeInformation\lib\netstandard1.1\System.Runtime.InteropServices.RuntimeInformation.dll @@ -1653,7 +1662,7 @@ - + ..\..\packages\razor4\System.Runtime.InteropServices.RuntimeInformation\ref\netstandard1.1\System.Runtime.InteropServices.RuntimeInformation.dll @@ -1662,6 +1671,15 @@ + + + + ..\..\packages\razor4\System.Runtime.InteropServices.RuntimeInformation\lib\wpa81\System.Runtime.InteropServices.RuntimeInformation.dll + True + True + + + @@ -1671,7 +1689,7 @@ - + ..\..\packages\razor4\System.Runtime.Numerics\ref\netstandard1.1\System.Runtime.Numerics.dll @@ -1685,7 +1703,7 @@ - + ..\..\packages\razor4\System.Runtime.Numerics\lib\netstandard1.3\System.Runtime.Numerics.dll @@ -1764,7 +1782,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.Algorithms\ref\netstandard1.6\System.Security.Cryptography.Algorithms.dll @@ -1825,7 +1843,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.Cng\ref\netstandard1.6\System.Security.Cryptography.Cng.dll @@ -1854,7 +1872,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.Csp\ref\netstandard1.3\System.Security.Cryptography.Csp.dll @@ -1883,7 +1901,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.Encoding\ref\netstandard1.3\System.Security.Cryptography.Encoding.dll @@ -1899,7 +1917,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.OpenSsl\lib\netstandard1.6\System.Security.Cryptography.OpenSsl.dll @@ -1908,7 +1926,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.OpenSsl\ref\netstandard1.6\System.Security.Cryptography.OpenSsl.dll @@ -1937,7 +1955,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.Primitives\lib\netstandard1.3\System.Security.Cryptography.Primitives.dll @@ -1946,7 +1964,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.Primitives\ref\netstandard1.3\System.Security.Cryptography.Primitives.dll @@ -2005,7 +2023,7 @@ - + ..\..\packages\razor4\System.Security.Cryptography.X509Certificates\ref\netstandard1.4\System.Security.Cryptography.X509Certificates.dll @@ -2021,7 +2039,7 @@ - + ..\..\packages\razor4\System.Text.Encoding\ref\netstandard1.3\System.Text.Encoding.dll @@ -2037,7 +2055,7 @@ - + ..\..\packages\razor4\System.Text.Encoding.Extensions\ref\netstandard1.3\System.Text.Encoding.Extensions.dll @@ -2071,6 +2089,15 @@ + + + + ..\..\packages\razor4\System.Text.RegularExpressions\ref\netcoreapp1.1\System.Text.RegularExpressions.dll + False + True + + + @@ -2085,7 +2112,7 @@ - + ..\..\packages\razor4\System.Text.RegularExpressions\lib\netstandard1.6\System.Text.RegularExpressions.dll @@ -2094,7 +2121,7 @@ - + ..\..\packages\razor4\System.Text.RegularExpressions\ref\netstandard1.6\System.Text.RegularExpressions.dll @@ -2110,7 +2137,7 @@ - + ..\..\packages\razor4\System.Threading\lib\netstandard1.3\System.Threading.dll @@ -2119,7 +2146,7 @@ - + ..\..\packages\razor4\System.Threading\ref\netstandard1.3\System.Threading.dll @@ -2135,7 +2162,7 @@ - + ..\..\packages\razor4\System.Threading.Tasks\ref\netstandard1.3\System.Threading.Tasks.dll @@ -2151,7 +2178,7 @@ - + ..\..\packages\razor4\System.Threading.Tasks.Extensions\lib\netstandard1.0\System.Threading.Tasks.Extensions.dll @@ -2162,7 +2189,25 @@ - + + + + True + + + + + + + + + ..\..\packages\razor4\System.Threading.Thread\lib\net46\System.Threading.Thread.dll + True + True + + + + ..\..\packages\razor4\System.Threading.Thread\lib\netstandard1.3\System.Threading.Thread.dll @@ -2171,7 +2216,7 @@ - + ..\..\packages\razor4\System.Threading.Thread\ref\netstandard1.3\System.Threading.Thread.dll @@ -2187,7 +2232,7 @@ - + ..\..\packages\razor4\System.Threading.Timer\ref\netstandard1.2\System.Threading.Timer.dll @@ -2231,7 +2276,7 @@ - + ..\..\packages\razor4\System.Xml.ReaderWriter\lib\netstandard1.3\System.Xml.ReaderWriter.dll @@ -2240,7 +2285,7 @@ - + ..\..\packages\razor4\System.Xml.ReaderWriter\ref\netstandard1.3\System.Xml.ReaderWriter.dll @@ -2263,7 +2308,7 @@ - + ..\..\packages\razor4\System.Xml.XDocument\lib\netstandard1.3\System.Xml.XDocument.dll @@ -2272,7 +2317,7 @@ - + ..\..\packages\razor4\System.Xml.XDocument\ref\netstandard1.3\System.Xml.XDocument.dll diff --git a/src/Paket.Core.preview3/Paket.Core.fsproj b/src/Paket.Core.preview3/Paket.Core.fsproj index 6fd54b35d9..88b35f50e1 100644 --- a/src/Paket.Core.preview3/Paket.Core.fsproj +++ b/src/Paket.Core.preview3/Paket.Core.fsproj @@ -19,6 +19,7 @@ + diff --git a/src/Paket.Core/Common/Async.fs b/src/Paket.Core/Common/Async.fs index 0a313d76fa..220dbcd6b0 100644 --- a/src/Paket.Core/Common/Async.fs +++ b/src/Paket.Core/Common/Async.fs @@ -47,4 +47,4 @@ module AsyncExtensions = for task in tasks do ignore <| System.Threading.Tasks.Task.Factory.StartNew(fun () -> Async.StartWithContinuations(task, scont, econt, ccont, innerCts.Token)) - } \ No newline at end of file + } diff --git a/src/Paket.Core/Common/Profile.fs b/src/Paket.Core/Common/Profile.fs new file mode 100644 index 0000000000..64b343e356 --- /dev/null +++ b/src/Paket.Core/Common/Profile.fs @@ -0,0 +1,35 @@ +module Paket.Profile + +open System.Diagnostics +open System + +type BlockReason = + | PackageDetails + | GetVersion + +type Category = + | ResolverAlgorithm + | ResolverAlgorithmBlocked of BlockReason + | NuGetRequest + | NuGetDownload + | FileIO + | Other +type Event = { Category: Category; Duration : TimeSpan } +let events = + System.Collections.Concurrent.ConcurrentBag() + +let startCategory cat = + let cw = Stopwatch.StartNew() + let mutable wasDisposed = false + { new System.IDisposable with + member x.Dispose () = + if not wasDisposed then + wasDisposed <- true + cw.Stop(); events.Add({ Category = cat; Duration = cw.Elapsed }) } + +let startCategoryF cat f = + let cw = Stopwatch.StartNew() + let res = f() + cw.Stop() + events.Add({ Category = cat; Duration = cw.Elapsed }) + res diff --git a/src/Paket.Core/Common/Utils.fs b/src/Paket.Core/Common/Utils.fs index 88ed2738c1..c85371bdf7 100644 --- a/src/Paket.Core/Common/Utils.fs +++ b/src/Paket.Core/Common/Utils.fs @@ -70,12 +70,15 @@ let TimeSpanToReadableString(span:TimeSpan) = let hours = notZero (span.Duration().Hours) <| String.Format("{0:0} hour{1}, ", span.Hours, pluralize span.Hours) let minutes = notZero (span.Duration().Minutes) <| String.Format("{0:0} minute{1}, ", span.Minutes, pluralize span.Minutes) let seconds = notZero (span.Duration().Seconds) <| String.Format("{0:0} second{1}", span.Seconds, pluralize span.Seconds) + let milliseconds = notZero (span.Duration().Milliseconds) <| String.Format("{0:0} millisecond{1}", span.Milliseconds, pluralize span.Milliseconds) let formatted = String.Format("{0}{1}{2}{3}", days, hours, minutes, seconds) let formatted = if formatted.EndsWith ", " then formatted.Substring(0, formatted.Length - 2) else formatted - if String.IsNullOrEmpty formatted then "0 seconds" else formatted + if not (String.IsNullOrEmpty formatted) then formatted + elif not (String.IsNullOrEmpty milliseconds) then milliseconds + else "0 milliseconds" let GetHomeDirectory() = #if DOTNETCORE @@ -552,6 +555,7 @@ let downloadFromUrl (auth:Auth option, url : string) (filePath: string) = async { try use client = createWebClient (url,auth) + use _ = Profile.startCategory Profile.Category.NuGetDownload let task = client.DownloadFileTaskAsync (Uri url, filePath) |> Async.AwaitTask do! task with @@ -566,7 +570,8 @@ let getFromUrl (auth:Auth option, url : string, contentType : string) = use client = createWebClient(url,auth) if notNullOrEmpty contentType then addAcceptHeader client contentType - + + use _ = Profile.startCategory Profile.Category.NuGetRequest return! client.DownloadStringTaskAsync (Uri url) |> Async.AwaitTask with | exn -> @@ -584,6 +589,7 @@ let getXmlFromUrl (auth:Auth option, url : string) = addHeader client "DataServiceVersion" "1.0;NetFx" addHeader client "MaxDataServiceVersion" "2.0;NetFx" + use _ = Profile.startCategory Profile.Category.NuGetRequest return! client.DownloadStringTaskAsync (Uri url) |> Async.AwaitTask with | exn -> @@ -604,6 +610,7 @@ let safeGetFromUrl (auth:Auth option, url : string, contentType : string) = #else client.Encoding <- Encoding.UTF8 #endif + use _ = Profile.startCategory Profile.Category.NuGetRequest let! raw = client.DownloadStringTaskAsync(uri) |> Async.AwaitTask return Some raw with e -> diff --git a/src/Paket.Core/Dependencies/DependenciesFileParser.fs b/src/Paket.Core/Dependencies/DependenciesFileParser.fs index f8d65d67ae..15fad4c285 100644 --- a/src/Paket.Core/Dependencies/DependenciesFileParser.fs +++ b/src/Paket.Core/Dependencies/DependenciesFileParser.fs @@ -289,13 +289,24 @@ module DependenciesFileParser = if text = "auto-detect" then Some (ParserOptions (ParserOption.AutodetectFrameworkRestrictions)) else - let restrictions = Requirements.parseRestrictions true text - if String.IsNullOrWhiteSpace text |> not && List.isEmpty restrictions then + let restrictions = Requirements.parseRestrictionsLegacy true text + if String.IsNullOrWhiteSpace text |> not && restrictions = FrameworkRestriction.NoRestriction then failwithf "Could not parse framework restriction \"%s\"" text - let options = ParserOption.FrameworkRestrictions (FrameworkRestrictionList restrictions) + let options = ParserOption.FrameworkRestrictions (ExplicitRestriction restrictions) Some (ParserOptions options) + | String.RemovePrefix "restriction" trimmed -> + let text = trimmed.Replace(":", "").Trim() + + if text = "auto-detect" then + Some (ParserOptions (ParserOption.AutodetectFrameworkRestrictions)) + else + let restrictions = Requirements.parseRestrictions true text + if String.IsNullOrWhiteSpace text |> not && restrictions = FrameworkRestriction.NoRestriction then + failwithf "Could not parse framework restriction \"%s\"" text + let options = ParserOption.FrameworkRestrictions (ExplicitRestriction restrictions) + Some (ParserOptions options) | String.RemovePrefix "content" trimmed -> let setting = match trimmed.Replace(":","").Trim() with @@ -387,7 +398,7 @@ module DependenciesFileParser = | _ -> None else None Parent = parent - Graph = [] + Graph = Set.empty Sources = sources Settings = InstallSettings.Parse(optionsText).AdjustWithSpecialCases packageName VersionRequirement = versionRequirement diff --git a/src/Paket.Core/Dependencies/NuGetV2.fs b/src/Paket.Core/Dependencies/NuGetV2.fs index f54f14da98..8446b99fd0 100644 --- a/src/Paket.Core/Dependencies/NuGetV2.fs +++ b/src/Paket.Core/Dependencies/NuGetV2.fs @@ -179,75 +179,42 @@ let parseODataDetails(url,nugetURL,packageName:PackageName,version:SemVerInfo,ra | Some node -> node.InnerText | None -> failwithf "unable to find dependencies for package %O %O" packageName version - let packages = + let rawPackages = let split (d : string) = let a = d.Split ':' - PackageName a.[0], - VersionRequirement.Parse(if a.Length > 1 then a.[1] else "0"), + let name = PackageName a.[0] + let version = VersionRequirement.Parse(if a.Length > 1 then a.[1] else "0") (if a.Length > 2 && a.[2] <> "" then - let restriction = a.[2] - if String.startsWithIgnoreCase "portable" restriction then - Some [ yield FrameworkRestriction.Portable restriction ] - else - match FrameworkDetection.Extract restriction with - | Some x -> Some [ FrameworkRestriction.Exactly x ] - | None -> - if verbose then - verbosefn "Unable to parse framework restriction '%s' for package '%s' in package '%s'" restriction a.[0] (packageName.ToString()) - None - else Some []) + let restriction = a.[2] + PlatformMatching.extractPlatforms restriction + else Some PlatformMatching.ParsedPlatformPath.Empty) + |> Option.map (fun pp -> name, version, pp) dependencies |> fun s -> s.Split([| '|' |], System.StringSplitOptions.RemoveEmptyEntries) - |> Array.map split - |> Array.choose (fun (name, version, restrictions) -> - match restrictions with - | Some(restrictions) -> Some (name, version, restrictions) - | None -> None) - - let expandedPackages = - let isMatch (n',v',r') = - r' - |> List.exists (fun r -> - match r with - | FrameworkRestriction.Exactly(DotNetFramework _) -> true - | FrameworkRestriction.Exactly(DotNetStandard _) -> true - |_ -> false) - - packages - |> Seq.collect (fun (n,v,r) -> - match r with - | [ FrameworkRestriction.Portable p ] -> - [yield n,v,r - let standardAliases = KnownTargetProfiles.portableStandards p - for alias in standardAliases do - let s = FrameworkRestriction.Exactly(DotNetStandard alias) - let s2 = FrameworkRestriction.AtLeast(DotNetStandard alias) - if packages |> Array.exists (fun (n,v,r) -> r |> List.exists (fun r -> r = s || r = s2)) |> not then - yield n,v,[s2] - - if standardAliases = [] && not <| Array.exists isMatch packages then - for p in p.Split([|'+'; '-'|]) do - match FrameworkDetection.Extract p with - | Some(DotNetFramework _ as r) -> - yield n,v,[FrameworkRestriction.Exactly r] - | Some(DotNetStandard _ as r) -> - yield n,v,[FrameworkRestriction.Exactly r] - | _ -> () ] - | _ -> [n,v,r]) - |> Seq.toList + |> Array.choose split - let dependencies = Requirements.optimizeDependencies expandedPackages + let frameworks = + rawPackages + |> Seq.map (fun (_,_,pp) -> pp) + |> Seq.distinctBy (fun pp -> pp.Platforms |> List.sort) + |> Seq.toList + let cleanedPackages = + rawPackages + |> Seq.filter (fun (n,_,_) -> System.String.IsNullOrEmpty (n.ToString()) |> not) + |> Seq.toList + let dependencies = + addFrameworkRestrictionsToDependencies cleanedPackages frameworks { PackageName = officialName DownloadUrl = downloadLink - Dependencies = dependencies + SerializedDependencies = [] SourceUrl = nugetURL CacheVersion = NuGetPackageCache.CurrentCacheVersion LicenseUrl = licenseUrl Version = (SemVer.Parse v).Normalize() Unlisted = publishDate = Constants.MagicUnlistingDate } - + |> NuGet.NuGetPackageCache.withDependencies dependencies let getDetailsFromNuGetViaODataFast auth nugetURL (packageName:PackageName) (version:SemVerInfo) = async { @@ -300,7 +267,7 @@ let getDetailsFromNuGetViaOData auth nugetURL (packageName:PackageName) (version async { try let! result = getDetailsFromNuGetViaODataFast auth nugetURL packageName version - if urlSimilarToTfsOrVsts nugetURL && result.Dependencies.IsEmpty then + if urlSimilarToTfsOrVsts nugetURL && result |> NuGet.NuGetPackageCache.getDependencies |> List.isEmpty then // TODO: There is a bug in VSTS, so we can't trust this protocol. Remvoe when VSTS is fixed // TODO: TFS has the same bug return! queryPackagesProtocol packageName @@ -366,6 +333,7 @@ let findLocalPackage directory (packageName:PackageName) (version:SemVerInfo) = /// Reads package name from a nupkg file let getPackageNameFromLocalFile fileName = + use __ = Profile.startCategory Profile.Category.FileIO fixArchive fileName use zipToCreate = new FileStream(fileName, FileMode.Open, FileAccess.Read) use zip = new ZipArchive(zipToCreate, ZipArchiveMode.Read) @@ -382,7 +350,8 @@ let getDetailsFromLocalNuGetPackage isCache alternativeProjectRoot root localNuG let localNugetPath = Utils.normalizeLocalPath localNuGetPath let di = getDirectoryInfoForLocalNuGetFeed localNugetPath alternativeProjectRoot root let nupkg = findLocalPackage di.FullName packageName version - + + use _ = Profile.startCategory Profile.Category.FileIO fixArchive nupkg.FullName use zipToCreate = new FileStream(nupkg.FullName, FileMode.Open, FileAccess.Read) use zip = new ZipArchive(zipToCreate,ZipArchiveMode.Read) @@ -399,12 +368,13 @@ let getDetailsFromLocalNuGetPackage isCache alternativeProjectRoot root localNuG return { PackageName = nuspec.OfficialName DownloadUrl = packageName.ToString() - Dependencies = nuspec.Dependencies + SerializedDependencies = [] SourceUrl = di.FullName CacheVersion = NuGetPackageCache.CurrentCacheVersion LicenseUrl = nuspec.LicenseUrl Version = version.Normalize() Unlisted = isCache } + |> NuGet.NuGetPackageCache.withDependencies nuspec.Dependencies } @@ -456,7 +426,8 @@ let rec private cleanup (dir : DirectoryInfo) = let ExtractPackageToUserFolder(fileName:string, packageName:PackageName, version:SemVerInfo, detailed) = async { let targetFolder = DirectoryInfo(Path.Combine(Constants.UserNuGetPackagesFolder,packageName.ToString(),version.Normalize())) - + + use _ = Profile.startCategory Profile.Category.FileIO if isExtracted targetFolder fileName |> not then Directory.CreateDirectory(targetFolder.FullName) |> ignore let fi = FileInfo fileName @@ -481,6 +452,7 @@ let ExtractPackageToUserFolder(fileName:string, packageName:PackageName, version /// Extracts the given package to the ./packages folder let ExtractPackage(fileName:string, targetFolder, packageName:PackageName, version:SemVerInfo, detailed) = async { + use _ = Profile.startCategory Profile.Category.FileIO let directory = DirectoryInfo(targetFolder) if isExtracted directory fileName then if verbose then @@ -516,6 +488,7 @@ let CopyLicenseFromCache(root, groupName, cacheFileName, packageName:PackageName if verbose then verbosefn "License %O %O already copied" packageName version else + use _ = Profile.startCategory Profile.Category.FileIO File.Copy(cacheFile.FullName, targetFile.FullName, true) with | exn -> traceWarnfn "Could not copy license for %O %O from %s.%s %s" packageName version cacheFileName Environment.NewLine exn.Message @@ -531,6 +504,7 @@ let CopyFromCache(root, groupName, cacheFileName, licenseCacheFile, packageName: if verbose then verbosefn "%O %O already copied" packageName version else + use _ = Profile.startCategory Profile.Category.FileIO CleanDir targetFolder File.Copy(cacheFileName, targetFile.FullName) try @@ -539,6 +513,7 @@ let CopyFromCache(root, groupName, cacheFileName, licenseCacheFile, packageName: return extracted with | exn -> + use _ = Profile.startCategory Profile.Category.FileIO File.Delete targetFile.FullName Directory.Delete(targetFolder,true) return! raise exn @@ -547,6 +522,7 @@ let CopyFromCache(root, groupName, cacheFileName, licenseCacheFile, packageName: /// Puts the package into the cache let CopyToCache(cache:Cache, fileName, force) = try + use __ = Profile.startCategory Profile.Category.FileIO if Cache.isInaccessible cache then if verbose then verbosefn "Cache %s is inaccessible, skipping" cache.Location @@ -596,6 +572,7 @@ let DownloadLicense(root,force,packageName:PackageName,version:SemVerInfo,licens request.UseDefaultCredentials <- true request.Proxy <- Utils.getDefaultProxyFor licenseUrl + use _ = Profile.startCategory Profile.Category.NuGetRequest use! httpResponse = request.AsyncGetResponse() use httpResponseStream = httpResponse.GetResponseStream() @@ -661,62 +638,60 @@ let GetTargetsFiles(targetFolder) = /// Finds all analyzer files in a nuget package. let GetAnalyzerFiles(targetFolder) = getFilesMatching targetFolder "*.dll" "analyzers" "analyzer dlls" -let rec private getPackageDetails alternativeProjectRoot root force (sources:PackageSource list) packageName (version:SemVerInfo) : PackageResolver.PackageDetails = - - let tryV2 source (nugetSource:NugetSource) force = async { - let! result = - getDetailsFromNuGet - force - (nugetSource.Authentication |> Option.map toBasicAuth) - nugetSource.Url - packageName - version - return Some(source,result) } - - let tryV3 source nugetSource force = async { - if nugetSource.Url.Contains("myget.org") || nugetSource.Url.Contains("nuget.org") || nugetSource.Url.Contains("visualstudio.com") || nugetSource.Url.Contains("/nuget/v3/") then - match NuGetV3.calculateNuGet2Path nugetSource.Url with - | Some url -> - let! result = - getDetailsFromNuGet - force - (nugetSource.Authentication |> Option.map toBasicAuth) - url - packageName - version - return Some(source,result) - | _ -> +let rec private getPackageDetails alternativeProjectRoot root force (sources:PackageSource list) packageName (version:SemVerInfo) : Async = + async { + let tryV2 source (nugetSource:NugetSource) force = async { + let! result = + getDetailsFromNuGet + force + (nugetSource.Authentication |> Option.map toBasicAuth) + nugetSource.Url + packageName + version + return Some(source,result) } + + let tryV3 source nugetSource force = async { + if nugetSource.Url.Contains("myget.org") || nugetSource.Url.Contains("nuget.org") || nugetSource.Url.Contains("visualstudio.com") || nugetSource.Url.Contains("/nuget/v3/") then + match NuGetV3.calculateNuGet2Path nugetSource.Url with + | Some url -> + let! result = + getDetailsFromNuGet + force + (nugetSource.Authentication |> Option.map toBasicAuth) + url + packageName + version + return Some(source,result) + | _ -> + let! result = NuGetV3.GetPackageDetails force nugetSource packageName version + return Some(source,result) + else let! result = NuGetV3.GetPackageDetails force nugetSource packageName version - return Some(source,result) - else - let! result = NuGetV3.GetPackageDetails force nugetSource packageName version - return Some(source,result) } - - let getPackageDetails force = - sources - |> List.sortBy (fun source -> - match source with // put local caches to the end - | LocalNuGet(_,Some _) -> true - | _ -> false) - |> List.map (fun source -> async { - try - match source with - | NuGetV2 nugetSource -> - return! tryV2 source nugetSource force - | NuGetV3 nugetSource when urlSimilarToTfsOrVsts nugetSource.Url -> - match NuGetV3.calculateNuGet2Path nugetSource.Url with - | Some url -> - let nugetSource : NugetSource = - { Url = url - Authentication = nugetSource.Authentication } + return Some(source,result) } + + let getPackageDetails force = + // helper to work through the list sequentially + let rec trySelectFirst workLeft = + async { + match workLeft with + | work :: rest -> + let! r = work + match r with + | Some result -> return Some result + | None -> return! trySelectFirst rest + | [] -> return None + } + sources + |> List.sortBy (fun source -> + match source with // put local caches to the end + | LocalNuGet(_,Some _) -> true + | _ -> false) + |> List.map (fun source -> async { + try + match source with + | NuGetV2 nugetSource -> return! tryV2 source nugetSource force - | _ -> - return! tryV3 source nugetSource force - | NuGetV3 nugetSource -> - try - return! tryV3 source nugetSource force - with - | exn -> + | NuGetV3 nugetSource when urlSimilarToTfsOrVsts nugetSource.Url -> match NuGetV3.calculateNuGet2Path nugetSource.Url with | Some url -> let nugetSource : NugetSource = @@ -724,60 +699,84 @@ let rec private getPackageDetails alternativeProjectRoot root force (sources:Pac Authentication = nugetSource.Authentication } return! tryV2 source nugetSource force | _ -> - raise exn return! tryV3 source nugetSource force - - | LocalNuGet(path,Some _) -> - let! result = getDetailsFromLocalNuGetPackage true alternativeProjectRoot root path packageName version - return Some(source,result) - | LocalNuGet(path,None) -> - let! result = getDetailsFromLocalNuGetPackage false alternativeProjectRoot root path packageName version - return Some(source,result) - with e -> - if verbose then - verbosefn "Source '%O' exception: %O" source e - return None }) - |> List.tryPick Async.RunSynchronously - - let source,nugetObject = - match getPackageDetails force with - | None -> - match getPackageDetails true with - | None -> - match sources |> List.map (fun (s:PackageSource) -> s.ToString()) with - | [source] -> - failwithf "Couldn't get package details for package %O %O on %O." packageName version source - | [] -> - failwithf "Couldn't get package details for package %O %O, because no sources were specified." packageName version - | sources -> - failwithf "Couldn't get package details for package %O %O on any of %A." packageName version sources - | Some packageDetails -> packageDetails - | Some packageDetails -> packageDetails - - let encodeURL (url:string) = - if String.IsNullOrWhiteSpace url then url else - let segments = url.Split [|'?'|] - let baseUrl = segments.[0] - Array.set segments 0 (baseUrl.Replace("+", "%2B")) - System.String.Join("?", segments) - - let newName = PackageName nugetObject.PackageName - if packageName <> newName then - failwithf "Package details for %O are not matching requested package %O." newName packageName - - { Name = PackageName nugetObject.PackageName - Source = source - DownloadLink = encodeURL nugetObject.DownloadUrl - Unlisted = nugetObject.Unlisted - LicenseUrl = nugetObject.LicenseUrl - DirectDependencies = nugetObject.Dependencies |> Set.ofList } - -let rec GetPackageDetails alternativeProjectRoot root force (sources:PackageSource list) groupName packageName (version:SemVerInfo) : PackageResolver.PackageDetails = - try - getPackageDetails alternativeProjectRoot root force sources packageName version - with - | _ -> getPackageDetails alternativeProjectRoot root true sources packageName version - + | NuGetV3 nugetSource -> + try + return! tryV3 source nugetSource force + with + | exn -> + match NuGetV3.calculateNuGet2Path nugetSource.Url with + | Some url -> + let nugetSource : NugetSource = + { Url = url + Authentication = nugetSource.Authentication } + return! tryV2 source nugetSource force + | _ -> + raise exn + return! tryV3 source nugetSource force + + | LocalNuGet(path,Some _) -> + let! result = getDetailsFromLocalNuGetPackage true alternativeProjectRoot root path packageName version + return Some(source,result) + | LocalNuGet(path,None) -> + let! result = getDetailsFromLocalNuGetPackage false alternativeProjectRoot root path packageName version + return Some(source,result) + with e -> + if verbose then + verbosefn "Source '%O' exception: %O" source e + return None }) + |> trySelectFirst + + let! maybePackageDetails = getPackageDetails force + let! source,nugetObject = + async { + match maybePackageDetails with + | None -> + let! m = getPackageDetails true + match m with + | None -> + match sources |> List.map (fun (s:PackageSource) -> s.ToString()) with + | [source] -> + return failwithf "Couldn't get package details for package %O %O on %O." packageName version source + | [] -> + return failwithf "Couldn't get package details for package %O %O, because no sources were specified." packageName version + | sources -> + return failwithf "Couldn't get package details for package %O %O on any of %A." packageName version sources + | Some packageDetails -> return packageDetails + | Some packageDetails -> return packageDetails + } + + let encodeURL (url:string) = + if String.IsNullOrWhiteSpace url then url else + let segments = url.Split [|'?'|] + let baseUrl = segments.[0] + Array.set segments 0 (baseUrl.Replace("+", "%2B")) + System.String.Join("?", segments) + + let newName = PackageName nugetObject.PackageName + if packageName <> newName then + failwithf "Package details for %O are not matching requested package %O." newName packageName + + return + { Name = PackageName nugetObject.PackageName + Source = source + DownloadLink = encodeURL nugetObject.DownloadUrl + Unlisted = nugetObject.Unlisted + LicenseUrl = nugetObject.LicenseUrl + DirectDependencies = NuGet.NuGetPackageCache.getDependencies nugetObject |> Set.ofList } } + +let rec GetPackageDetails alternativeProjectRoot root force (sources:PackageSource list) groupName packageName (version:SemVerInfo) : Async = + async { + try + return! getPackageDetails alternativeProjectRoot root force sources packageName version + with + | exn -> + if verbose then + traceWarnfn "GetPackageDetails failed: %O" exn + else + traceWarnfn "Something failed in GetPackageDetails, trying again with force: %s" exn.Message + return! getPackageDetails alternativeProjectRoot root true sources packageName version + } let protocolCache = System.Collections.Concurrent.ConcurrentDictionary<_,_>() let getVersionsCached key f (source, auth, nugetURL, package) = @@ -818,8 +817,8 @@ let FindPackages(auth, nugetURL, packageNamePrefix, maxResults) = } /// Allows to retrieve all version no. for a package from the given sources. -let GetVersions force alternativeProjectRoot root (sources, packageName:PackageName) = - let trial force = +let GetVersions force alternativeProjectRoot root (sources, packageName:PackageName) = async { + let trial force = async { let getVersionsFailedCacheFileName (source:PackageSource) = let h = source.Url |> normalizeUrl |> hash |> abs let packageUrl = sprintf "Versions.%O.s%d.failed" packageName h @@ -877,53 +876,55 @@ let GetVersions force alternativeProjectRoot root (sources, packageName:PackageN |> Seq.toArray |> Array.map Async.Choice |> Async.Parallel - |> Async.RunSynchronously - versionResponse - |> Array.zip sources - |> Array.choose (fun ((_,s),v) -> - match v with - | Some v when Array.isEmpty v |> not -> - try - let errorFile = getVersionsFailedCacheFileName s - if errorFile.Exists then - File.Delete(errorFile.FullName) - with _ -> () - Some (s,v) - | _ -> - try - let errorFile = getVersionsFailedCacheFileName s - if errorFile.Exists |> not then - File.WriteAllText(errorFile.FullName,DateTime.Now.ToString()) - with _ -> () - None) - |> Array.map (fun (s,versions) -> versions |> Array.map (fun v -> v,s)) - |> Array.concat - - let versions = - match trial force with - | versions when Array.isEmpty versions |> not -> versions + let! result = versionResponse + return + result + |> Array.zip sources + |> Array.choose (fun ((_,s),v) -> + match v with + | Some v when Array.isEmpty v |> not -> + try + let errorFile = getVersionsFailedCacheFileName s + if errorFile.Exists then + File.Delete(errorFile.FullName) + with _ -> () + Some (s,v) + | _ -> + try + let errorFile = getVersionsFailedCacheFileName s + if errorFile.Exists |> not then + File.WriteAllText(errorFile.FullName,DateTime.Now.ToString()) + with _ -> () + None) + |> Array.map (fun (s,versions) -> versions |> Array.map (fun v -> v,s)) + |> Array.concat } + let! versions = async { + let! trial1 = trial force + match trial1 with + | versions when Array.isEmpty versions |> not -> return versions | _ -> - match trial true with - | versions when Array.isEmpty versions |> not -> versions + let! trial2 = trial true + match trial2 with + | versions when Array.isEmpty versions |> not -> return versions | _ -> match sources |> Seq.map (fun s -> s.ToString()) |> List.ofSeq with | [source] -> - failwithf "Could not find versions for package %O on %O." packageName source + return failwithf "Could not find versions for package %O on %O." packageName source | [] -> - failwithf "Could not find versions for package %O, because no sources were specified." packageName + return failwithf "Could not find versions for package %O, because no sources were specified." packageName | sources -> - failwithf "Could not find versions for package %O on any of %A." packageName sources - - versions - |> Seq.toList - |> List.map (fun (v,s) -> SemVer.Parse v,v,s) - |> List.groupBy (fun (v,_,_) -> v.Normalize()) - |> List.map (fun (_,s) -> - let sorted = s |> List.sortByDescending (fun (_,_,s) -> s.IsLocalFeed) + return failwithf "Could not find versions for package %O on any of %A." packageName sources } + return + versions + |> Seq.toList + |> List.map (fun (v,s) -> SemVer.Parse v,v,s) + |> List.groupBy (fun (v,_,_) -> v.Normalize()) + |> List.map (fun (_,s) -> + let sorted = s |> List.sortByDescending (fun (_,_,s) -> s.IsLocalFeed) - let _,v,_ = List.head sorted - SemVer.Parse v,sorted |> List.map (fun (_,_,x) -> x)) + let _,v,_ = List.head sorted + SemVer.Parse v,sorted |> List.map (fun (_,_,x) -> x)) } /// Downloads the given package to the NuGet Cache folder @@ -969,7 +970,8 @@ let DownloadPackage(alternativeProjectRoot, root, (source : PackageSource), cach let path = Utils.normalizeLocalPath path let di = Utils.getDirectoryInfoForLocalNuGetFeed path alternativeProjectRoot root let nupkg = findLocalPackage di.FullName packageName version - + + use _ = Profile.startCategory Profile.Category.FileIO File.Copy(nupkg.FullName,targetFileName) | _ -> // discover the link on the fly @@ -977,7 +979,7 @@ let DownloadPackage(alternativeProjectRoot, root, (source : PackageSource), cach try if authenticated then tracefn "Downloading %O %O%s" packageName version (if groupName = Constants.MainDependencyGroup then "" else sprintf " (%O)" groupName) - let nugetPackage = GetPackageDetails alternativeProjectRoot root force [source] groupName packageName version + let! nugetPackage = GetPackageDetails alternativeProjectRoot root force [source] groupName packageName version let encodeURL (url:string) = url.Replace("+","%2B") let downloadUri = @@ -994,7 +996,8 @@ let DownloadPackage(alternativeProjectRoot, root, (source : PackageSource), cach if authenticated && verbose then tracefn " from %O" !downloadUrl tracefn " to %s" targetFileName - + + use trackDownload = Profile.startCategory Profile.Category.NuGetDownload let! license = Async.StartChild(DownloadLicense(root,force,packageName,version,nugetPackage.LicenseUrl,licenseFileName), 5000) let request = HttpWebRequest.Create(downloadUri) :?> HttpWebRequest @@ -1040,7 +1043,7 @@ let DownloadPackage(alternativeProjectRoot, root, (source : PackageSource), cach let! bytes = httpResponseStream.AsyncRead(buffer, 0, bufferSize) bytesRead := bytes do! fileStream.AsyncWrite(buffer, 0, !bytesRead) - + match (httpResponse :?> HttpWebResponse).StatusCode with | HttpStatusCode.OK -> () | statusCode -> failwithf "HTTP status code was %d - %O" (int statusCode) statusCode diff --git a/src/Paket.Core/Dependencies/NuGetV3.fs b/src/Paket.Core/Dependencies/NuGetV3.fs index ae20914dc3..be5d7af049 100644 --- a/src/Paket.Core/Dependencies/NuGetV3.fs +++ b/src/Paket.Core/Dependencies/NuGetV3.fs @@ -244,8 +244,8 @@ let getPackageDetails (source:NugetV3Source) (packageName:PackageName) (version: |> Seq.map(fun (dep, targetFramework) -> let targetFramework = match targetFramework with - | null -> [] - | x -> Requirements.parseRestrictions false x + | null -> FrameworkRestriction.NoRestriction + | x -> Requirements.parseRestrictionsLegacy false x (PackageName dep.Id), (VersionRequirement.Parse dep.Range), targetFramework) |> Seq.toList let unlisted = @@ -253,10 +253,11 @@ let getPackageDetails (source:NugetV3Source) (packageName:PackageName) (version: not catalogData.Listed.Value else false - - let optimized = Requirements.optimizeDependencies dependencies + // TODO: We probably need our new restriction logic here because I guess what nuget gives us is not enough... + let optimized = + dependencies |> List.map (fun (m,v,r) -> m,v, ExplicitRestriction r) return - { Dependencies = optimized + { SerializedDependencies = [] PackageName = packageName.ToString() SourceUrl = source.Url Unlisted = unlisted @@ -264,6 +265,7 @@ let getPackageDetails (source:NugetV3Source) (packageName:PackageName) (version: LicenseUrl = catalogData.LicenseUrl Version = version.Normalize() CacheVersion = NuGet.NuGetPackageCache.CurrentCacheVersion } + |> NuGet.NuGetPackageCache.withDependencies optimized } let loadFromCacheOrGetDetails (force:bool) diff --git a/src/Paket.Core/Dependencies/Nuget.fs b/src/Paket.Core/Dependencies/Nuget.fs index 7a8e9c7420..c38814cac3 100644 --- a/src/Paket.Core/Dependencies/Nuget.fs +++ b/src/Paket.Core/Dependencies/Nuget.fs @@ -44,10 +44,10 @@ module NuGetConfig = if File.ReadAllText(fileName) <> text then File.WriteAllText(fileName,text) - +type FrameworkRestrictionsCache = string type NuGetPackageCache = - { Dependencies : (PackageName * VersionRequirement * FrameworkRestrictions) list + { SerializedDependencies : (PackageName * VersionRequirement * FrameworkRestrictionsCache) list PackageName : string SourceUrl: string Unlisted : bool @@ -56,19 +56,47 @@ type NuGetPackageCache = Version: string CacheVersion: string } - static member CurrentCacheVersion = "3.37" + static member CurrentCacheVersion = "4.0" + +module NuGetPackageCache = + let withDependencies (l:(PackageName * VersionRequirement * FrameworkRestrictions) list) d = + { d with + SerializedDependencies = + l + |> List.map (fun (n,v, restrictions) -> + let restrictionString = + match restrictions with + | FrameworkRestrictions.AutoDetectFramework -> "AUTO" + | FrameworkRestrictions.ExplicitRestriction re -> + re.ToString() + n, v, restrictionString) } + let getDependencies (x:NuGetPackageCache) : (PackageName * VersionRequirement * FrameworkRestrictions) list = + x.SerializedDependencies + |> List.map (fun (n,v,restrictionString) -> + let restrictions = + if restrictionString = "AUTO" then + FrameworkRestrictions.AutoDetectFramework + else FrameworkRestrictions.ExplicitRestriction(Requirements.parseRestrictions true restrictionString) + n, v, restrictions) let inline normalizeUrl(url:string) = url.Replace("https://","http://").Replace("www.","") -let getCacheFileName nugetURL (packageName:PackageName) (version:SemVerInfo) = +let getCacheFiles cacheVersion nugetURL (packageName:PackageName) (version:SemVerInfo) = let h = nugetURL |> normalizeUrl |> hash |> abs + let prefix = + sprintf "%O.%s.s%d" packageName (version.Normalize()) h let packageUrl = - sprintf "%O.%s.s%d.json" - packageName (version.Normalize()) h - FileInfo(Path.Combine(Constants.NuGetCacheFolder,packageUrl)) - + sprintf "%s_v%s.json" + prefix cacheVersion + let newFile = Path.Combine(Constants.NuGetCacheFolder,packageUrl) + let oldFiles = + Directory.EnumerateFiles(Constants.NuGetCacheFolder, sprintf "%s*.json" prefix) + |> Seq.filter (fun p -> Path.GetFileName p <> packageUrl) + |> Seq.toList + FileInfo(newFile), oldFiles let getDetailsFromCacheOr force nugetURL (packageName:PackageName) (version:SemVerInfo) (get : unit -> NuGetPackageCache Async) : NuGetPackageCache Async = - let cacheFile = getCacheFileName nugetURL packageName version + let cacheFile, oldFiles = getCacheFiles NuGetPackageCache.CurrentCacheVersion nugetURL packageName version + oldFiles |> Seq.iter (fun f -> File.Delete f) let get() = async { let! result = get() @@ -81,16 +109,22 @@ let getDetailsFromCacheOr force nugetURL (packageName:PackageName) (version:SemV try let cachedObject = JsonConvert.DeserializeObject json - if (cachedObject.CacheVersion <> NuGetPackageCache.CurrentCacheVersion) || - (PackageName cachedObject.PackageName <> packageName) || + if (PackageName cachedObject.PackageName <> packageName) || (cachedObject.Version <> version.Normalize()) then + traceVerbose (sprintf "Invalidating Cache '%s:%s' <> '%s:%s'" cachedObject.PackageName cachedObject.Version packageName.Name (version.Normalize())) cacheFile.Delete() return! get() else return cachedObject with - | exn -> return! get() + | exn -> + cacheFile.Delete() + if verbose then + traceWarnfn "Error while loading cache: %O" exn + else + traceWarnfn "Error while loading cache: %s" exn.Message + return! get() else return! get() } \ No newline at end of file diff --git a/src/Paket.Core/Dependencies/Nuspec.fs b/src/Paket.Core/Dependencies/Nuspec.fs index c181461c93..6f96c12e87 100644 --- a/src/Paket.Core/Dependencies/Nuspec.fs +++ b/src/Paket.Core/Dependencies/Nuspec.fs @@ -33,26 +33,22 @@ module internal NuSpecParserHelper = match parent.Name, parent |> getAttribute "targetFramework" with | n , Some framework when String.equalsIgnoreCase n "group" -> let framework = framework.Replace(".NETPortable0.0","portable") - if String.startsWithIgnoreCase "portable" framework then - Some(name,version,[FrameworkRestriction.Portable framework]) - else - match FrameworkDetection.Extract framework with - | Some x -> Some(name,version,[FrameworkRestriction.Exactly x]) - | None -> None - | _ -> Some(name,version,[]) + PlatformMatching.extractPlatforms framework + |> Option.map (fun pp -> name, version, pp) + | _ -> Some(name,version, PlatformMatching.ParsedPlatformPath.Empty) let getAssemblyRefs node = let name = node |> getAttribute "assemblyName" let targetFrameworks = node |> getAttribute "targetFramework" match name,targetFrameworks with | Some name, Some targetFrameworks when targetFrameworks = "" -> - [{ AssemblyName = name; FrameworkRestrictions = FrameworkRestrictionList [] }] + [{ AssemblyName = name; FrameworkRestrictions = ExplicitRestriction FrameworkRestriction.NoRestriction }] | Some name, None -> - [{ AssemblyName = name; FrameworkRestrictions = FrameworkRestrictionList [] }] + [{ AssemblyName = name; FrameworkRestrictions = ExplicitRestriction FrameworkRestriction.NoRestriction }] | Some name, Some targetFrameworks -> targetFrameworks.Split([|','; ' '|],System.StringSplitOptions.RemoveEmptyEntries) |> Array.choose FrameworkDetection.Extract - |> Array.map (fun fw -> { AssemblyName = name; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly fw] }) + |> Array.map (fun fw -> { AssemblyName = name; FrameworkRestrictions = ExplicitRestriction (FrameworkRestriction.Exactly fw) }) |> Array.toList | _ -> [] @@ -78,63 +74,19 @@ type Nuspec = let frameworks = doc |> getDescendants "group" - |> List.map (fun node -> + |> List.choose (fun node -> match node |> getAttribute "targetFramework" with - | Some framework when framework.ToLower().Replace(".netportable","portable").Replace("netportable","portable").StartsWith "portable" -> - let framework = framework.ToLower().Replace(".netportable","portable").Replace("netportable","portable") - [PackageName "", - VersionRequirement.NoRestriction, - [ yield FrameworkRestriction.Portable framework]] - | Some framework -> - match FrameworkDetection.Extract framework with - | Some x -> [PackageName "",VersionRequirement.NoRestriction, [FrameworkRestriction.Exactly x]] - | None -> [] - | _ -> []) - |> List.concat - - let framworks = - let isMatch (n',v',r') = - r' - |> List.exists (fun r -> - match r with - | FrameworkRestriction.Exactly(DotNetFramework _) -> true - | FrameworkRestriction.Exactly(DotNetStandard _) -> true - |_ -> false) - - frameworks - |> Seq.collect (fun (n,v,r) -> - match r with - | [ FrameworkRestriction.Portable p ] -> - [ yield n,v,r - let standardAliases = KnownTargetProfiles.portableStandards p - for alias in standardAliases do - let s = FrameworkRestriction.Exactly(DotNetStandard alias) - let s2 = FrameworkRestriction.AtLeast(DotNetStandard alias) - if frameworks |> List.exists (fun (n,v,r) -> r |> List.exists (fun r -> r = s || r = s2)) |> not then - yield n,v,[s2] - - if standardAliases = [] && not <| List.exists isMatch frameworks then - for p in p.Split([|'+'; '-'|]) do - match FrameworkDetection.Extract p with - | Some(DotNetFramework _ as r) -> - yield n,v,[FrameworkRestriction.Exactly r] - | Some(DotNetStandard _ as r) -> - yield n,v,[FrameworkRestriction.Exactly r] - | _ -> () ] - | _ -> [n,v,r]) - |> Seq.toList + let framework = framework.ToLower().Replace(".netportable","portable").Replace("netportable","portable") + PlatformMatching.extractPlatforms framework + | _ -> Some PlatformMatching.ParsedPlatformPath.Empty) - let depsTags = + let rawDependencies = doc |> getDescendants "dependency" - - let referenced = - depsTags |> List.choose (NuSpecParserHelper.getDependency fileName) - |> List.append frameworks - let dependencies = Requirements.optimizeDependencies referenced + let dependencies = addFrameworkRestrictionsToDependencies rawDependencies frameworks let references = doc @@ -168,7 +120,11 @@ type Nuspec = [for name,restrictions in grouped do yield { AssemblyName = name - FrameworkRestrictions = FrameworkRestrictionList(List.collect (fun x -> x.FrameworkRestrictions |> getRestrictionList) restrictions) } ] } + FrameworkRestrictions = + ExplicitRestriction( + restrictions + |> List.map (fun x -> x.FrameworkRestrictions |> getExplicitRestriction) + |> List.fold FrameworkRestriction.combineRestrictionsWithOr FrameworkRestriction.EmptySet) } ] } /// load the file from an nuspec text stream. The fileName is only used for error reporting. static member internal Load(fileName:string, f:Stream) = diff --git a/src/Paket.Core/Dependencies/PackageResolver.fs b/src/Paket.Core/Dependencies/PackageResolver.fs index c3f5f2c33b..c55545ce98 100644 --- a/src/Paket.Core/Dependencies/PackageResolver.fs +++ b/src/Paket.Core/Dependencies/PackageResolver.fs @@ -37,7 +37,7 @@ type ResolvedPackage = { override this.ToString () = sprintf "%O %O" this.Name this.Version member self.HasFrameworkRestrictions = - not (getRestrictionList self.Settings.FrameworkRestrictions = []) + getExplicitRestriction self.Settings.FrameworkRestrictions <> FrameworkRestriction.NoRestriction member private self.Display with get() = @@ -54,46 +54,27 @@ type PackageResolution = Map module DependencySetFilter = let isIncluded (restriction:FrameworkRestriction) (dependency:PackageName * VersionRequirement * FrameworkRestrictions) = - let _,_,restrictions = dependency - let restrictions = restrictions |> getRestrictionList - if Seq.isEmpty restrictions then true else - 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 - | FrameworkRestriction.AtLeast v2 when v1 >= v2 -> true - | FrameworkRestriction.Between(v2,v3) when v1 >= v2 && v1 < v3 -> true - | _ -> 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 - | FrameworkRestriction.AtLeast v2 -> true - | FrameworkRestriction.Between(v2,v3) when v1 < v3 -> true - | _ -> false) - | FrameworkRestriction.Between (min, max) -> - restrictions - |> Seq.filter (fun r2 -> restriction.IsSameCategoryAs(r2) = Some(true)) - |> Seq.exists (fun r2 -> - match r2 with - | FrameworkRestriction.Exactly v when v >= min && v < max -> true - | FrameworkRestriction.AtLeast v when v < max -> true - | FrameworkRestriction.Between(min',max') when max' >= min && min' < max -> true - | _ -> false) - | _ -> true + let _,_,dependencyRestrictions = dependency + let dependencyRestrictions = dependencyRestrictions |> getExplicitRestriction + if dependencyRestrictions = FrameworkRestriction.NoRestriction then true else + // While the dependency specifies the framework restrictions of the dependency ([ >= netstandard13 ]) + // we need to take the dependency, when the combination still contains packages. + // NOTE: This is not forwards compatible... + //let combined = FrameworkRestriction.And [ restriction; dependencyRestrictions ] + //not combined.RepresentedFrameworks.IsEmpty + + // "And" is not cheap therefore we use this, + // because we don't want to pay the price of calculating a "simplified" formula + Set.intersect restriction.RepresentedFrameworks dependencyRestrictions.RepresentedFrameworks + |> Set.isEmpty + |> not let filterByRestrictions (restrictions:FrameworkRestrictions) (dependencies:DependencySet) : DependencySet = - match getRestrictionList restrictions with - | [] -> dependencies + match getExplicitRestriction restrictions with + | FrameworkRestriction.HasNoRestriction -> dependencies | restrictions -> dependencies - |> Set.filter (fun dependency -> - restrictions |> List.exists (fun r -> isIncluded r dependency)) + |> Set.filter (isIncluded restrictions) let isPackageCompatible (dependencies:DependencySet) (package:ResolvedPackage) : bool = dependencies @@ -147,16 +128,14 @@ module Resolution = let getConflicts (res:Resolution) = match res with - | Resolution.Ok _ -> [] + | Resolution.Ok _ -> Set.empty | Resolution.Conflict (currentStep,_,lastPackageRequirement,_) -> currentStep.ClosedRequirements |> Set.union currentStep.OpenRequirements |> Set.add lastPackageRequirement - |> Seq.filter (fun x -> x.Name = lastPackageRequirement.Name) - |> Seq.sortBy (fun x -> x.Parent) - |> Seq.toList + |> Set.filter (fun x -> x.Name = lastPackageRequirement.Name) - let buildConflictReport (errorReport:StringBuilder) (conflicts:PackageRequirement list) = + let buildConflictReport (errorReport:StringBuilder) (conflicts:PackageRequirement Set) = let formatVR (vr:VersionRequirement) = vr.ToString () |> fun s -> if String.IsNullOrWhiteSpace s then ">= 0" else s @@ -169,9 +148,9 @@ module Resolution = | _ -> "" match conflicts with - | [] -> errorReport + | s when s.IsEmpty -> errorReport | conflicts -> - let hasPrereleases = List.exists (fun r -> r.VersionRequirement.PreReleases <> PreReleaseStatus.No) conflicts + let hasPrereleases = Seq.exists (fun r -> r.VersionRequirement.PreReleases <> PreReleaseStatus.No) conflicts errorReport.AddLine (sprintf " Conflict detected:") @@ -183,13 +162,10 @@ module Resolution = sprintf " - Dependencies file requested package %O: %s%s" req.Name vr pr | Package (parentName,version,_) -> sprintf " - %O %O requested package %O: %s%s" parentName version req.Name vr pr - - let rec loop conflicts (errorReport:StringBuilder) = - match conflicts with - | [] -> errorReport - | hd::tl -> loop tl (errorReport.AppendLine (getConflictMessage hd)) - loop conflicts errorReport - + + conflicts + |> Seq.fold (fun (errorReport:StringBuilder) conflict -> + errorReport.AppendLine (getConflictMessage conflict)) errorReport let getErrorText showResolvedPackages = function | Resolution.Ok _ -> "" @@ -203,12 +179,13 @@ module Resolution = else StringBuilder() match getConflicts res with - | [] -> + | c when c.IsEmpty -> errorText.AppendLinef " Could not resolve package %O. Unknown resolution error." (Seq.head currentStep.OpenRequirements) - | [c] -> - let errorText = buildConflictReport errorText [c] + | cfs when cfs.Count = 1 -> + let c = cfs.MinimumElement + let errorText = buildConflictReport errorText cfs match getVersionF c.Name |> Seq.toList with | [] -> errorText.AppendLinef " - No versions available." | avalaibleVersions -> @@ -251,11 +228,11 @@ let calcOpenRequirements (exploredPackage:ResolvedPackage,globalFrameworkRestric | VersionRequirement(ra1,p1),VersionRequirement(ra2,p2) when p1 = p2 -> let newRestrictions = match r with - | FrameworkRestrictionList r -> + | ExplicitRestriction r -> match r2 with - | FrameworkRestrictionList r2 -> - FrameworkRestrictionList (r @ r2) - | AutoDetectFramework -> FrameworkRestrictionList r + | ExplicitRestriction r2 -> + FrameworkRestriction.combineRestrictionsWithOr r r2 |> ExplicitRestriction + | AutoDetectFramework -> ExplicitRestriction r | AutoDetectFramework -> r if ra1.IsIncludedIn ra2 then @@ -278,13 +255,13 @@ let calcOpenRequirements (exploredPackage:ResolvedPackage,globalFrameworkRestric let newRestrictions = filterRestrictions restriction exploredPackage.Settings.FrameworkRestrictions |> filterRestrictions globalFrameworkRestrictions - |> fun xs -> if xs = FrameworkRestrictionList [] then exploredPackage.Settings.FrameworkRestrictions else xs + |> fun xs -> if xs = ExplicitRestriction FrameworkRestriction.NoRestriction then exploredPackage.Settings.FrameworkRestrictions else xs { dependency with Name = n VersionRequirement = v Parent = Package(dependency.Name, versionToExplore, exploredPackage.Source) - Graph = [dependency] @ dependency.Graph + Graph = Set.add dependency dependency.Graph Settings = { dependency.Settings with FrameworkRestrictions = newRestrictions } }) |> Set.filter (fun d -> resolverStep.ClosedRequirements @@ -339,31 +316,49 @@ type private PackageConfig = { UpdateMode : UpdateMode } with member self.HasGlobalRestrictions = - not(getRestrictionList self.GlobalRestrictions = []) + not(getExplicitRestriction self.GlobalRestrictions = FrameworkRestriction.NoRestriction) member self.HasDependencyRestrictions = - not(getRestrictionList self.Dependency.Settings.FrameworkRestrictions = []) + not(getExplicitRestriction self.Dependency.Settings.FrameworkRestrictions = FrameworkRestriction.NoRestriction) let private updateRestrictions (pkgConfig:PackageConfig) (package:ResolvedPackage) = let newRestrictions = if not pkgConfig.HasGlobalRestrictions - && (List.isEmpty (package.Settings.FrameworkRestrictions |> getRestrictionList) + && (FrameworkRestriction.NoRestriction = (package.Settings.FrameworkRestrictions |> getExplicitRestriction) || not pkgConfig.HasDependencyRestrictions ) then - [] + FrameworkRestriction.NoRestriction else - let packageSettings = package.Settings.FrameworkRestrictions |> getRestrictionList - let dependencySettings = pkgConfig.Dependency.Settings.FrameworkRestrictions |> getRestrictionList - let globalSettings = pkgConfig.GlobalRestrictions |> getRestrictionList - optimizeRestrictions (List.concat[packageSettings;dependencySettings;globalSettings]) + // Setting in the dependencies file + let globalPackageSettings = + match pkgConfig.RootSettings.TryGetValue package.Name with + | true, s -> + match s.FrameworkRestrictions with + | ExplicitRestriction r -> r + | _ -> FrameworkRestriction.NoRestriction + | _ -> FrameworkRestriction.NoRestriction + // Settings required for the current resolution + let packageSettings = package.Settings.FrameworkRestrictions |> getExplicitRestriction + // Settings required for this current dependency + let dependencySettings = pkgConfig.Dependency.Settings.FrameworkRestrictions |> getExplicitRestriction + // Settings defined globally + let globalSettings = pkgConfig.GlobalRestrictions |> getExplicitRestriction + let isRequired = + FrameworkRestriction.Or + [ packageSettings + FrameworkRestriction.And [dependencySettings;globalSettings]] + + // We assume the user knows what he is doing + FrameworkRestriction.And [ globalPackageSettings;isRequired ] + { package with - Settings = { package.Settings with FrameworkRestrictions = FrameworkRestrictionList newRestrictions } + Settings = { package.Settings with FrameworkRestrictions = ExplicitRestriction newRestrictions } } -let private explorePackageConfig getPackageDetailsF (pkgConfig:PackageConfig) = +let private explorePackageConfig getPackageDetailsBlock (pkgConfig:PackageConfig) = let dependency, version = pkgConfig.Dependency, pkgConfig.Version let packageSources = pkgConfig.Sources @@ -380,7 +375,7 @@ let private explorePackageConfig getPackageDetailsF (pkgConfig:PackageConfig) = filterRestrictions dependency.Settings.FrameworkRestrictions pkgConfig.GlobalRestrictions try let packageDetails : PackageDetails = - getPackageDetailsF packageSources pkgConfig.GroupName dependency.Name version + getPackageDetailsBlock packageSources pkgConfig.GroupName dependency.Name version let filteredDependencies = DependencySetFilter.filterByRestrictions newRestrictions packageDetails.DirectDependencies let settings = @@ -413,7 +408,7 @@ type StackPack = { } -let private getExploredPackage (pkgConfig:PackageConfig) getPackageDetailsF (stackpack:StackPack) = +let private getExploredPackage (pkgConfig:PackageConfig) getPackageDetailsBlock (stackpack:StackPack) = let key = (pkgConfig.Dependency.Name, pkgConfig.Version) match stackpack.ExploredPackages.TryGetValue key with @@ -424,7 +419,7 @@ let private getExploredPackage (pkgConfig:PackageConfig) getPackageDetailsF (sta verbosefn " Retrieved Explored Package %O" package stackpack, Some(true, package) | false,_ -> - match explorePackageConfig getPackageDetailsF pkgConfig with + match explorePackageConfig getPackageDetailsBlock pkgConfig with | Some explored -> if verbose then verbosefn " Found Explored Package %O" explored @@ -518,19 +513,19 @@ let private getCompatibleVersions let private getConflicts (currentStep:ResolverStep) (currentRequirement:PackageRequirement) (knownConflicts:HashSet * ((SemVerInfo * PackageSource list) list * bool) option>) = let allRequirements = - Set.toSeq currentStep.OpenRequirements - |> Seq.filter (fun r -> r.Graph |> List.contains currentRequirement |> not) - |> Seq.append currentStep.ClosedRequirements - |> HashSet + currentStep.OpenRequirements + |> Set.filter (fun r -> r.Graph |> Set.contains currentRequirement |> not) + |> Set.union currentStep.ClosedRequirements knownConflicts |> Seq.map (fun (conflicts,selectedVersion) -> + let isSubset = conflicts.IsSubsetOf allRequirements match selectedVersion with - | None when conflicts.IsSubsetOf allRequirements -> conflicts + | None when isSubset -> conflicts | Some(selectedVersion,_) -> let n = (Seq.head conflicts).Name match currentStep.FilteredVersions |> Map.tryFind n with - | Some(v,_) when v = selectedVersion && conflicts.IsSubsetOf allRequirements -> conflicts + | Some(v,_) when v = selectedVersion && isSubset -> conflicts | _ -> HashSet() | _ -> HashSet()) |> Seq.collect id @@ -597,7 +592,8 @@ let private boostConflicts let conflicts = conflictStatus.GetConflicts() let lastConflictReported = match conflicts with - | c::_ -> + | _ when not conflicts.IsEmpty -> + let c = conflicts |> Seq.minBy (fun c -> c.Parent) let selectedVersion = Map.tryFind c.Name filteredVersions let key = conflicts |> HashSet,selectedVersion stackpack.KnownConflicts.Add key |> ignore @@ -646,8 +642,40 @@ type private Stage = | Inner of currentConflict : (ConflictState * ResolverStep * PackageRequirement) * priorConflictSteps : (ConflictState * ResolverStep * PackageRequirement * seq * StepFlags) list /// Resolves all direct and transitive dependencies -let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrategyForDirectDependencies, globalStrategyForTransitives, globalFrameworkRestrictions, (rootDependencies:PackageRequirement Set), updateMode : UpdateMode) = +let Resolve (getVersionsRaw, getPreferredVersionsRaw, getPackageDetailsRaw, groupName:GroupName, globalStrategyForDirectDependencies, globalStrategyForTransitives, globalFrameworkRestrictions, (rootDependencies:PackageRequirement Set), updateMode : UpdateMode) = tracefn "Resolving packages for group %O:" groupName + + use d = Profile.startCategory Profile.Category.ResolverAlgorithm + + let startedGetPackageDetailsRequests = System.Collections.Concurrent.ConcurrentDictionary<_,System.Threading.Tasks.Task<_>>() + let startRequestGetPackageDetails sources groupName packageName semVer = + let key = (sources, packageName, semVer) + startedGetPackageDetailsRequests.GetOrAdd (key, fun _ -> + (getPackageDetailsRaw sources groupName packageName semVer : Async) + |> Async.StartAsTask) + let getPackageDetailsBlock sources groupName packageName semVer = + use d = Profile.startCategory (Profile.Category.ResolverAlgorithmBlocked Profile.BlockReason.PackageDetails) + let result = (startRequestGetPackageDetails sources groupName packageName semVer).GetAwaiter().GetResult() + d.Dispose() + result + + + let startedGetVersionsRequests = System.Collections.Concurrent.ConcurrentDictionary<_,System.Threading.Tasks.Task<_>>() + let startRequestGetVersions sources groupName packageName = + let key = (sources, packageName) + startedGetVersionsRequests.GetOrAdd (key, fun _ -> + getVersionsRaw sources groupName packageName + |> Async.StartAsTask) + let getVersionsBlock sources resolverStrategy groupName packageName = + use d = Profile.startCategory (Profile.Category.ResolverAlgorithmBlocked Profile.BlockReason.GetVersion) + let versions = (startRequestGetVersions sources groupName packageName).GetAwaiter().GetResult() |> Seq.toList + d.Dispose() + let sorted = + match resolverStrategy with + | ResolverStrategy.Max -> List.sortDescending versions + | ResolverStrategy.Min -> List.sort versions + let pref = getPreferredVersionsRaw sources resolverStrategy groupName packageName + pref @ sorted |> List.toSeq let packageFilter = match updateMode with @@ -684,14 +712,14 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate let findMatchingStep priorConflictSteps = let currentNames = conflicts - |> Seq.collect (fun c -> - let graphNameList = - c.Graph |> List.map (fun (pr:PackageRequirement) -> pr.Name) - c.Name :: graphNameList) - |> Seq.toArray + |> Seq.map (fun c -> + c.Graph + |> Set.map (fun (pr:PackageRequirement) -> pr.Name) + |> Set.add c.Name) + |> Set.unionMany priorConflictSteps |> List.tryExtractOne (fun (_,_,lastRequirement:PackageRequirement,_,_) -> - currentNames |> Array.contains lastRequirement.Name) + currentNames |> Set.contains lastRequirement.Name) match findMatchingStep priorConflictSteps with | None, [] -> currentConflict @@ -727,7 +755,7 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate && currentStep.CurrentResolution.Count > 1 && not (conflicts |> Set.exists (fun r -> r = lastRequirement - || r.Graph |> List.contains lastRequirement)) -> + || r.Graph |> Set.contains lastRequirement)) -> step (Inner((continueConflict,lastStep,lastRequirement),priorConflictSteps)) stackpack lastCompatibleVersions { flags with ForceBreak = true } | _ -> @@ -750,7 +778,8 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate getConflicts currentStep currentRequirement stackpack.KnownConflicts let currentConflict = - let getVersionsF = getVersionsF currentRequirement.Sources ResolverStrategy.Max groupName + let getVersionsF = + getVersionsBlock currentRequirement.Sources ResolverStrategy.Max groupName if Seq.isEmpty conflicts then { currentConflict with Status = Resolution.Conflict (currentStep,Set.empty,currentRequirement,getVersionsF)} @@ -762,7 +791,7 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate fuseConflicts currentConflict priorConflictSteps conflicts else let compatibleVersions,globalOverride,tryRelaxed = - getCompatibleVersions currentStep groupName currentRequirement getVersionsF + getCompatibleVersions currentStep groupName currentRequirement getVersionsBlock currentConflict.GlobalOverride globalStrategyForDirectDependencies globalStrategyForTransitives @@ -839,7 +868,7 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate UpdateMode = updateMode } - match getExploredPackage packageDetails getPackageDetailsF stackpack with + match getExploredPackage packageDetails getPackageDetailsBlock stackpack with | stackpack, None -> step (Inner((currentConflict,currentStep,currentRequirement), priorConflictSteps)) stackpack compatibleVersions flags @@ -847,6 +876,19 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate let hasUnlisted = exploredPackage.Unlisted || flags.HasUnlisted let flags = { flags with HasUnlisted = hasUnlisted } + // Start pre-loading infos about dependencies. + for (pack,verReq,restr) in exploredPackage.Dependencies do + async { + let! versions = startRequestGetVersions currentRequirement.Sources groupName pack |> Async.AwaitTask + // Preload the first version in range of this requirement + match versions |> Seq.map fst |> Seq.tryFind (verReq.IsInRange) with + | Some verToPreload -> + let! details = startRequestGetPackageDetails currentRequirement.Sources groupName pack verToPreload |> Async.AwaitTask + () + | None -> () + return () + } |> Async.Start + if exploredPackage.Unlisted && not flags.UseUnlisted then if not alreadyExplored then tracefn " %O %O was unlisted" exploredPackage.Name exploredPackage.Version @@ -885,10 +927,14 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate OpenRequirements = rootDependencies } + for openReq in startingStep.OpenRequirements do + startRequestGetVersions openReq.Sources groupName openReq.Name + |> ignore + let currentRequirement = getCurrentRequirement packageFilter startingStep.OpenRequirements (Dictionary()) let status = - let getVersionsF = getVersionsF currentRequirement.Sources ResolverStrategy.Max groupName + let getVersionsF = getVersionsBlock currentRequirement.Sources ResolverStrategy.Max groupName Resolution.Conflict(startingStep,Set.empty,currentRequirement,getVersionsF) @@ -916,7 +962,33 @@ let Resolve (getVersionsF, getPackageDetailsF, groupName:GroupName, globalStrate UnlistedSearch = false } - match step (Step((currentConflict,startingStep,currentRequirement),[])) stackpack Seq.empty flags with + let inline calculate () = step (Step((currentConflict,startingStep,currentRequirement),[])) stackpack Seq.empty flags +#if DEBUG + let mutable results = None + let mutable error = None + // Increase stack size, because we have no tail-call-elimination + let thread = new System.Threading.Thread((fun () -> + try + results <- Some (calculate()) + with e -> + // Prevent the application from crashing + error <- Some (System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture e) + ), 1024 * 1024 * 100) + thread.Name <- sprintf "Paket Resolver Thread (Debug) - %O" (System.Guid.NewGuid()) + thread.Start() + thread.Join() + match error with + | Some e -> e.Throw() + | _ -> () + let stepResult = + match results with + | Some s -> s + | None -> failwithf "Expected to get results from the resolver thread :/." +#else + let stepResult = calculate() +#endif + + match stepResult with | { Status = Resolution.Conflict _ } as conflict -> if conflict.TryRelaxed then stackpack.KnownConflicts.Clear() diff --git a/src/Paket.Core/Installation/RestoreProcess.fs b/src/Paket.Core/Installation/RestoreProcess.fs index 77ee846b85..9c55adde27 100644 --- a/src/Paket.Core/Installation/RestoreProcess.fs +++ b/src/Paket.Core/Installation/RestoreProcess.fs @@ -166,7 +166,7 @@ let CreateInstallModel(alternativeProjectRoot, root, groupName, sources, caches, let! (package, files, targetsFiles, analyzerFiles) = ExtractPackage(alternativeProjectRoot, root, groupName, sources, caches, force, package, false) let nuspec = Nuspec.Load(root,groupName,package.Version,defaultArg package.Settings.IncludeVersionInPath false,package.Name) let targetsFiles = targetsFiles |> Array.toList - let model = InstallModel.CreateFromLibs(package.Name, package.Version, package.Settings.FrameworkRestrictions |> Requirements.getRestrictionList, files, targetsFiles, analyzerFiles, nuspec) + let model = InstallModel.CreateFromLibs(package.Name, package.Version, package.Settings.FrameworkRestrictions |> Requirements.getExplicitRestriction, files, targetsFiles, analyzerFiles, nuspec) return (groupName,package.Name), (package,model) } @@ -276,7 +276,7 @@ let Restore(dependenciesFileName,projectFile,force,group,referencesFileNames,ign let resolvedPackage = resolved.Force().[key] match resolvedPackage.Settings.FrameworkRestrictions with - | Requirements.FrameworkRestrictionList restrictions -> + | Requirements.ExplicitRestriction restrictions -> Requirements.isTargetMatchingRestrictions(restrictions, SinglePlatform target) | _ -> true @@ -324,7 +324,7 @@ let Restore(dependenciesFileName,projectFile,force,group,referencesFileNames,ign let resolvedPackage = resolved.Force().[key] match resolvedPackage.Settings.FrameworkRestrictions with - | Requirements.FrameworkRestrictionList restrictions -> + | Requirements.ExplicitRestriction restrictions -> Requirements.isTargetMatchingRestrictions(restrictions, SinglePlatform target) | _ -> true) diff --git a/src/Paket.Core/Installation/UpdateProcess.fs b/src/Paket.Core/Installation/UpdateProcess.fs index 60b58bae94..cf83211f03 100644 --- a/src/Paket.Core/Installation/UpdateProcess.fs +++ b/src/Paket.Core/Installation/UpdateProcess.fs @@ -10,23 +10,15 @@ open Chessie.ErrorHandling open Paket.Logging open InstallProcess -let selectiveUpdate force getSha1 getSortedVersionsF getPackageDetailsF getRuntimeGraphFromPackage (lockFile:LockFile) (dependenciesFile:DependenciesFile) updateMode semVerUpdateMode = - let allVersions = Dictionary() - let getSortedAndCachedVersionsF sources resolverStrategy groupName packageName : seq = - let key = packageName,sources - match allVersions.TryGetValue key with - | false,_ -> - let versions = - if verbose then - verbosefn " - fetching versions for %O" packageName - getSortedVersionsF sources resolverStrategy groupName packageName - - if Seq.isEmpty versions then - failwithf "Couldn't retrieve versions for %O." packageName - allVersions.Add(key,versions) - versions - | true,versions -> versions - |> List.toSeq +let selectiveUpdate force getSha1 getVersionsF getPackageDetailsF getRuntimeGraphFromPackage (lockFile:LockFile) (dependenciesFile:DependenciesFile) updateMode semVerUpdateMode = + let getSortedVersionsF sources groupName packageName : Async> = async { + if verbose then + verbosefn " - fetching versions for %O" packageName + let! versions = + getVersionsF sources groupName packageName + if Seq.isEmpty versions then + failwithf "Couldn't retrieve versions for %O." packageName + return versions } let dependenciesFile = let processFile createRequirementF = @@ -57,7 +49,7 @@ let selectiveUpdate force getSha1 getSortedVersionsF getPackageDetailsF getRunti | SemVerUpdateMode.KeepMinor -> processFile (fun v -> sprintf "~> %d.%d.%d" v.Major v.Minor v.Patch + formatPrerelease v) | SemVerUpdateMode.KeepPatch -> processFile (fun v -> sprintf "~> %d.%d.%d.%s" v.Major v.Minor v.Patch v.Build + formatPrerelease v) - let getVersionsF,getPackageDetailsF,groupsToUpdate = + let getPreferredVersionsF,getPackageDetailsF,groupsToUpdate = let changes,groups = match updateMode with | UpdateAll -> @@ -122,26 +114,24 @@ let selectiveUpdate force getSha1 getSortedVersionsF getPackageDetailsF getRunti v,s :: (List.map PackageSources.PackageSource.FromCache caches)) - let getVersionsF sources resolverStrategy groupName packageName = - seq { - match preferredVersions |> Map.tryFind (groupName, packageName), resolverStrategy with - | Some x, ResolverStrategy.Min -> yield x - | Some x, _ -> - if not (changes |> Set.contains (groupName, packageName)) then - yield x - | _ -> () - yield! getSortedAndCachedVersionsF sources resolverStrategy groupName packageName - } |> Seq.cache - - let getPackageDetailsF sources groupName packageName version = - let exploredPackage:PackageDetails = getPackageDetailsF sources groupName packageName version + let getPreferredVersionsF sources resolverStrategy groupName packageName = + match preferredVersions |> Map.tryFind (groupName, packageName), resolverStrategy with + | Some x, ResolverStrategy.Min -> [x] + | Some x, _ -> + if not (changes |> Set.contains (groupName, packageName)) then + [x] + else [] + | _ -> [] + + let getPackageDetailsF sources groupName packageName version = async { + let! (exploredPackage:PackageDetails) = getPackageDetailsF sources groupName packageName version match preferredVersions |> Map.tryFind (groupName,packageName) with - | Some (preferedVersion,_) when version = preferedVersion -> { exploredPackage with Unlisted = false } - | _ -> exploredPackage + | Some (preferedVersion,_) when version = preferedVersion -> return { exploredPackage with Unlisted = false } + | _ -> return exploredPackage } - getVersionsF,getPackageDetailsF,groups - - let resolution = dependenciesFile.Resolve(force, getSha1, getVersionsF, getPackageDetailsF, getRuntimeGraphFromPackage, groupsToUpdate, updateMode) + getPreferredVersionsF,getPackageDetailsF,groups + + let resolution = dependenciesFile.Resolve(force, getSha1, getVersionsF, getPreferredVersionsF, getPackageDetailsF, getRuntimeGraphFromPackage, groupsToUpdate, updateMode) let groups = dependenciesFile.Groups @@ -165,19 +155,21 @@ let detectProjectFrameworksForDependenciesFile (dependenciesFile:DependenciesFil let root = Path.GetDirectoryName dependenciesFile.FileName let groups = let targetFrameworks = lazy ( - RestoreProcess.findAllReferencesFiles root |> returnOrFail - |> List.map (fun (p,_) -> - match p.GetTargetFramework() with - | Some fw -> Requirements.FrameworkRestriction.Exactly fw - | None -> failwithf "Could not detect target framework for project %s" p.FileName) - |> List.distinct) + let rawRestrictions = + RestoreProcess.findAllReferencesFiles root |> returnOrFail + |> List.map (fun (p,_) -> + p.GetTargetProfile() + |> Requirements.FrameworkRestriction.ExactlyPlatform) + |> List.distinct + if rawRestrictions.IsEmpty then Paket.Requirements.FrameworkRestriction.NoRestriction + else rawRestrictions |> Seq.fold Paket.Requirements.FrameworkRestriction.combineRestrictionsWithOr Paket.Requirements.FrameworkRestriction.EmptySet) dependenciesFile.Groups |> Map.map (fun groupName group -> let restrictions = match group.Options.Settings.FrameworkRestrictions with | Requirements.FrameworkRestrictions.AutoDetectFramework -> - Requirements.FrameworkRestrictions.FrameworkRestrictionList (targetFrameworks.Force()) + Requirements.FrameworkRestrictions.ExplicitRestriction (targetFrameworks.Force()) | x -> x let settings = { group.Options.Settings with FrameworkRestrictions = restrictions } @@ -196,11 +188,9 @@ let SelectiveUpdate(dependenciesFile : DependenciesFile, alternativeProjectRoot, let getSha1 origin owner repo branch auth = RemoteDownload.getSHA1OfBranch origin owner repo branch auth |> Async.RunSynchronously let root = Path.GetDirectoryName dependenciesFile.FileName - let inline getVersionsF sources resolverStrategy groupName packageName = - let versions = NuGetV2.GetVersions force alternativeProjectRoot root (sources, packageName) - match resolverStrategy with - | ResolverStrategy.Max -> List.sortDescending versions - | ResolverStrategy.Min -> List.sort versions + let inline getVersionsF sources groupName packageName = async { + let! result = NuGetV2.GetVersions force alternativeProjectRoot root (sources, packageName) + return result |> List.toSeq } let dependenciesFile = detectProjectFrameworksForDependenciesFile dependenciesFile diff --git a/src/Paket.Core/PackageAnalysis/FindOutdated.fs b/src/Paket.Core/PackageAnalysis/FindOutdated.fs index 83e93a9641..eb6d10556f 100644 --- a/src/Paket.Core/PackageAnalysis/FindOutdated.fs +++ b/src/Paket.Core/PackageAnalysis/FindOutdated.fs @@ -37,21 +37,17 @@ let FindOutdated strict includingPrereleases groupNameFilter environment = trial let root = Path.GetDirectoryName dependenciesFile.FileName let alternativeProjectRoot = None - let getVersionsF sources resolverStrategy groupName packageName = - let versions = NuGetV2.GetVersions force alternativeProjectRoot root (sources, packageName) - - match resolverStrategy with - | ResolverStrategy.Max -> List.sortDescending versions - | ResolverStrategy.Min -> List.sort versions - |> List.toSeq - + let getVersionsF sources groupName packageName = async { + let! versions = NuGetV2.GetVersions force alternativeProjectRoot root (sources, packageName) + return versions |> List.toSeq } + let getPreferredVersionsF sources resolverStrategy groupName packageName = [] let dependenciesFile = UpdateProcess.detectProjectFrameworksForDependenciesFile dependenciesFile let checkedDepsGroups = match groupNameFilter with | None -> dependenciesFile.Groups | Some gname -> dependenciesFile.Groups |> Map.filter(fun k g -> k.ToString() = gname) - let newResolution = dependenciesFile.Resolve(force, getSha1, getVersionsF, NuGetV2.GetPackageDetails alternativeProjectRoot root true, RuntimeGraph.getRuntimeGraphFromNugetCache root, checkedDepsGroups, PackageResolver.UpdateMode.UpdateAll) + let newResolution = dependenciesFile.Resolve(force, getSha1, getVersionsF, getPreferredVersionsF, NuGetV2.GetPackageDetails alternativeProjectRoot root true, RuntimeGraph.getRuntimeGraphFromNugetCache root, checkedDepsGroups, PackageResolver.UpdateMode.UpdateAll) let checkedLockGroups = match groupNameFilter with diff --git a/src/Paket.Core/PackageAnalysis/Queries.fs b/src/Paket.Core/PackageAnalysis/Queries.fs index 9243513569..785a3dde0e 100644 --- a/src/Paket.Core/PackageAnalysis/Queries.fs +++ b/src/Paket.Core/PackageAnalysis/Queries.fs @@ -32,7 +32,7 @@ let getInstalledPackageModel (lockFile: LockFile) (QualifiedPackageName(groupNam let nuspec = FileInfo(sprintf "%s/packages%s/%O/%O.nuspec" lockFile.RootPath groupFolder packageName packageName) let nuspec = Nuspec.Load nuspec.FullName let files = NuGetV2.GetLibFiles(folder.FullName) - InstallModel.CreateFromLibs(packageName, resolvedPackage.Version, [], files, [], [], nuspec) + InstallModel.CreateFromLibs(packageName, resolvedPackage.Version, Paket.Requirements.FrameworkRestriction.NoRestriction, files, [], [], nuspec) let getRuntimeGraph (lockFile: LockFile) (groupName:GroupName) = lockFile.Groups @@ -66,14 +66,7 @@ let resolveFrameworkForScriptGeneration (dependencies: DependenciesFile) = lazy |> Seq.map(fun restrictions -> match restrictions with | Paket.Requirements.AutoDetectFramework -> failwithf "couldn't detect framework" - | Paket.Requirements.FrameworkRestrictionList list -> - list |> Seq.collect ( - function - | Paket.Requirements.FrameworkRestriction.Exactly framework - | Paket.Requirements.FrameworkRestriction.AtLeast framework -> Seq.singleton framework - | Paket.Requirements.FrameworkRestriction.Between (bottom,top) -> [bottom; top] |> Seq.ofList //TODO: do we need to cap the list of generated frameworks based on this? also see todo in Requirements.fs for potential generation of range for 'between' - | Paket.Requirements.FrameworkRestriction.Portable portable -> failwithf "unhandled portable framework %s" portable - ) + | Paket.Requirements.ExplicitRestriction list -> list.RepresentedFrameworks ) |> Seq.concat ) diff --git a/src/Paket.Core/PackageAnalysis/Why.fs b/src/Paket.Core/PackageAnalysis/Why.fs index ce95929375..711b92f958 100644 --- a/src/Paket.Core/PackageAnalysis/Why.fs +++ b/src/Paket.Core/PackageAnalysis/Why.fs @@ -64,13 +64,8 @@ module DependencyChain = let formatFxReq (fr : FrameworkRestrictions) = match fr with | AutoDetectFramework - | FrameworkRestrictionList [] -> "" - | FrameworkRestrictionList [fx] -> sprintf " (%O)" fx - | FrameworkRestrictionList fxs -> - fxs - |> List.map string - |> String.concat "," - |> sprintf " (%s)" + | ExplicitRestriction Paket.Requirements.FrameworkRestriction.HasNoRestriction -> "" + | ExplicitRestriction fr -> sprintf " (%O)" fr let formatName name i = sprintf "%s-> %O" (String.replicate i " ") name let rec format' i (name,chain) = let rest = diff --git a/src/Paket.Core/PackageManagement/NugetConvert.fs b/src/Paket.Core/PackageManagement/NugetConvert.fs index 737c000c51..538017b139 100644 --- a/src/Paket.Core/PackageManagement/NugetConvert.fs +++ b/src/Paket.Core/PackageManagement/NugetConvert.fs @@ -222,7 +222,7 @@ let createPackageRequirement sources (packageName, versionRange, restrictions) d Settings = { InstallSettings.Default with FrameworkRestrictions = restrictions } Parent = PackageRequirementSource.DependenciesFile dependenciesFileName Sources = sources - Graph = [] } + Graph = Set.empty } let createDependenciesFileR (rootDirectory : DirectoryInfo) nugetEnv mode = @@ -259,20 +259,23 @@ let createDependenciesFileR (rootDirectory : DirectoryInfo) nugetEnv mode = let latestVersion, _ = versions |> List.maxBy fst let restrictions = match versions with - | [ version, targetFramework ] -> targetFramework |> Option.toList |> List.collect (Requirements.parseRestrictions false) + | [ version, targetFramework ] -> targetFramework |> Option.toList |> List.map (Requirements.parseRestrictionsLegacy false) | _ -> [] + let restrictions = + if restrictions = [] then FrameworkRestriction.NoRestriction + else restrictions |> Seq.fold FrameworkRestriction.combineRestrictionsWithOr FrameworkRestriction.EmptySet name, latestVersion, restrictions) let packages = match nugetEnv.NuGetExe with - | Some _ -> ("NuGet.CommandLine",VersionRange.AtLeast "0",[]) :: latestVersions + | Some _ -> ("NuGet.CommandLine",VersionRange.AtLeast "0",FrameworkRestriction.NoRestriction) :: latestVersions | _ -> latestVersions let read() = let addPackages dependenciesFile = packages |> List.map (fun (name, vr, restrictions) -> - Constants.MainDependencyGroup, PackageName name, vr, { InstallSettings.Default with FrameworkRestrictions = FrameworkRestrictionList restrictions}) + Constants.MainDependencyGroup, PackageName name, vr, { InstallSettings.Default with FrameworkRestrictions = ExplicitRestriction restrictions}) |> List.fold (fun (dependenciesFile:DependenciesFile) (groupName, packageName,versionRange,installSettings) -> dependenciesFile.Add(groupName, packageName,versionRange,installSettings)) dependenciesFile try @@ -305,7 +308,7 @@ let createDependenciesFileR (rootDirectory : DirectoryInfo) nugetEnv mode = let packageLines = packages |> List.map (fun (name,vr,restr) -> - let vr = createPackageRequirement sources (name, vr, FrameworkRestrictionList restr) dependenciesFileName + let vr = createPackageRequirement sources (name, vr, ExplicitRestriction restr) dependenciesFileName DependenciesFileSerializer.packageString vr.Name vr.VersionRequirement vr.ResolverStrategyForTransitives vr.Settings) let newLines = sourceLines @ [""] @ packageLines |> Seq.toArray diff --git a/src/Paket.Core/Paket.Core.fsproj b/src/Paket.Core/Paket.Core.fsproj index 873a9a1e29..829b5cb7e1 100644 --- a/src/Paket.Core/Paket.Core.fsproj +++ b/src/Paket.Core/Paket.Core.fsproj @@ -100,6 +100,7 @@ + diff --git a/src/Paket.Core/PaketConfigFiles/DependenciesFile.fs b/src/Paket.Core/PaketConfigFiles/DependenciesFile.fs index 80b7e16c8f..d314c6f427 100644 --- a/src/Paket.Core/PaketConfigFiles/DependenciesFile.fs +++ b/src/Paket.Core/PaketConfigFiles/DependenciesFile.fs @@ -142,36 +142,50 @@ type DependenciesFile(fileName,groups:Map, textRepr let lockFile = dependenciesFile.FindLockfile() let dir = (lockFile : FileInfo).DirectoryName let projects = ProjectFile.FindAllProjects dir - let frameworks = projects |> Array.choose ProjectFile.getTargetFramework |> Array.distinct - frameworks |> Array.map FrameworkRestriction.Exactly |> List.ofArray + let frameworks = projects |> Array.map ProjectFile.getTargetProfile |> Array.distinct + let restrictions = frameworks |> Array.map FrameworkRestriction.ExactlyPlatform + if restrictions |> Array.isEmpty then FrameworkRestriction.NoRestriction + else restrictions |> Array.fold FrameworkRestriction.combineRestrictionsWithOr FrameworkRestriction.EmptySet ) fun restrictions -> match restrictions with - | FrameworkRestrictionList l -> l + | ExplicitRestriction l -> l | AutoDetectFramework -> projectFrameworks.Force() - if group.Options.Settings.FrameworkRestrictions |> getRestrictionList <> [] then dependenciesFile else + if group.Options.Settings.FrameworkRestrictions |> getRestrictionList <> FrameworkRestriction.NoRestriction then dependenciesFile else match group.Packages with | [] -> dependenciesFile - | package::rest -> - let commonRestrictions = - package.Settings.FrameworkRestrictions - |> getRestrictionList - |> List.filter (fun r -> rest |> Seq.forall (fun p' -> p'.Settings.FrameworkRestrictions |> getRestrictionList |> List.contains r)) - - match commonRestrictions with - | [] -> dependenciesFile - | _ -> - let newDependenciesFile = dependenciesFile.AddFrameworkRestriction(group.Name,commonRestrictions) - group.Packages - |> List.fold (fun (d:DependenciesFile) package -> - let oldRestrictions = package.Settings.FrameworkRestrictions |> getRestrictionList - let newRestrictions = oldRestrictions |> List.filter (fun r -> commonRestrictions |> List.contains r |> not) - if oldRestrictions = newRestrictions then d else - let (d:DependenciesFile) = d.Remove(group.Name,package.Name) - let installSettings = { package.Settings with FrameworkRestrictions = FrameworkRestrictionList newRestrictions } - let vr = { VersionRequirement = package.VersionRequirement; ResolverStrategy = package.ResolverStrategyForDirectDependencies } - d.AddAdditionalPackage(group.Name, package.Name,vr,installSettings)) newDependenciesFile + | package::rest -> dependenciesFile + // TODO: Fix simplifier + //let commonRestrictions = + // group.Packages + // |> Seq.map (fun p' -> p'.Settings.FrameworkRestrictions) + // |> Seq.fold (fun a b -> FrameworkRestriction.And [a;b.GetExplicitRestriction()]) FrameworkRestriction.EmptySet + // //package.Settings.FrameworkRestrictions + // //|> getRestrictionList + // //|> List.filter (fun r -> + // // rest |> Seq.forall (fun p' -> p'.Settings.FrameworkRestrictions |> getRestrictionList |> List.contains r)) + // + //match commonRestrictions.RepresentedFrameworks with + //| [] -> dependenciesFile + //// Only take when our commonRestriction formula is actually "simple" + //| _ when commonRestrictions.OrFormulas |> List.forall (fun andFormula -> andFormula.Literals.Length <= 1) -> + // let newDependenciesFile = dependenciesFile.AddFrameworkRestriction(group.Name,commonRestrictions) + // let newNegatedLiterals = + // commonRestrictions.OrFormulas |> List.collect (fun andFormala -> andFormala.Literals) + // |> List.map (fun lit -> FrameworkRestriction.FromLiteral { lit with IsNegated = not lit.IsNegated }) + // |> List.fold (fun a b -> FrameworkRestriction.Or [ a; b]) FrameworkRestriction.EmptySet + // + // group.Packages + // |> List.fold (fun (d:DependenciesFile) package -> + // let oldRestrictions = package.Settings.FrameworkRestrictions |> getRestrictionList + // let newRestrictions = FrameworkRestriction.Or [ oldRestrictions; newNegatedLiterals ]// |> List.filter (fun r -> commonRestrictions |> List.contains r |> not) + // if oldRestrictions = newRestrictions then d else + // let (d:DependenciesFile) = d.Remove(group.Name,package.Name) + // let installSettings = { package.Settings with FrameworkRestrictions = ExplicitRestriction newRestrictions } + // let vr = { VersionRequirement = package.VersionRequirement; ResolverStrategy = package.ResolverStrategyForDirectDependencies } + // d.AddAdditionalPackage(group.Name, package.Name,vr,installSettings)) newDependenciesFile + //| _ -> dependenciesFile this.Groups |> Seq.map (fun kv -> kv.Value) @@ -193,7 +207,7 @@ type DependenciesFile(fileName,groups:Map, textRepr try self.GetPackage (groupName,name) |> Some with _ -> None - member this.Resolve(force, getSha1, getVersionF, getPackageDetailsF, getPackageRuntimeGraph, groupsToResolve:Map, updateMode) = + member this.Resolve(force, getSha1, getVersionF, getPreferredVersionF, getPackageDetailsF, getPackageRuntimeGraph, groupsToResolve:Map, updateMode) = let resolveGroup groupName _ = let group = this.GetGroup groupName @@ -218,7 +232,7 @@ type DependenciesFile(fileName,groups:Map, textRepr ResolverStrategyForDirectDependencies = Some ResolverStrategy.Max ResolverStrategyForTransitives = Some ResolverStrategy.Max Parent = PackageRequirementSource.DependenciesFile fileName - Graph = [] + Graph = Set.empty Sources = group.Sources Settings = group.Options.Settings }) |> Seq.toList @@ -231,6 +245,7 @@ type DependenciesFile(fileName,groups:Map, textRepr let resolution = PackageResolver.Resolve( getVersionF, + getPreferredVersionF, getPackageDetailsF, groupName, group.Options.ResolverStrategyForDirectDependencies, @@ -264,7 +279,7 @@ type DependenciesFile(fileName,groups:Map, textRepr ResolverStrategyForDirectDependencies = group.Options.ResolverStrategyForDirectDependencies ResolverStrategyForTransitives = group.Options.ResolverStrategyForTransitives Parent = PackageRequirementSource.DependenciesFile "runtimeresolution.dependencies" - Graph = [] + Graph = Set.empty Sources = group.Sources Settings = group.Options.Settings }) |> Seq.toList @@ -290,7 +305,7 @@ type DependenciesFile(fileName,groups:Map, textRepr | Some d -> d.ResolverStrategyForTransitives | None -> group.Options.ResolverStrategyForTransitives Parent = PackageRequirementSource.DependenciesFile "runtimeresolution.dependencies" - Graph = [] + Graph = Set.empty Sources = group.Sources Settings = match oldDepsInfo with @@ -301,10 +316,10 @@ type DependenciesFile(fileName,groups:Map, textRepr if Environment.GetEnvironmentVariable "PAKET_DEBUG_RUNTIME_DEPS" = "true" then tracefn "Runtime dependencies: " - let runtimeDepsFile = DependenciesFile.FromSource "" - let runtimeDepsFile = runtimeDepsFile.AddFrameworkRestriction(Constants.MainDependencyGroup, getRestrictionList group.Options.Settings.FrameworkRestrictions) - let runtimeDepsFile = runtimeDepsFile.AddResolverStrategyForTransitives(Constants.MainDependencyGroup, group.Options.ResolverStrategyForTransitives) - let runtimeDepsFile = (runtimeDepsFile:DependenciesFile).AddResolverStrategyForDirectDependencies(Constants.MainDependencyGroup, group.Options.ResolverStrategyForDirectDependencies) + let (runtimeDepsFile:DependenciesFile) = DependenciesFile.FromSource "" + let (runtimeDepsFile:DependenciesFile) = runtimeDepsFile.AddFrameworkRestriction(Constants.MainDependencyGroup, getExplicitRestriction group.Options.Settings.FrameworkRestrictions) + let (runtimeDepsFile:DependenciesFile) = runtimeDepsFile.AddResolverStrategyForTransitives(Constants.MainDependencyGroup, group.Options.ResolverStrategyForTransitives) + let (runtimeDepsFile:DependenciesFile) = runtimeDepsFile.AddResolverStrategyForDirectDependencies(Constants.MainDependencyGroup, group.Options.ResolverStrategyForDirectDependencies) let runtimeDepsFile = runtimeResolutionDeps |> Seq.fold (fun (deps:DependenciesFile) dep -> deps.AddAdditionalPackage(Constants.MainDependencyGroup, dep.Name, dep.VersionRequirement, dep.ResolverStrategyForTransitives, dep.Settings)) runtimeDepsFile @@ -314,6 +329,7 @@ type DependenciesFile(fileName,groups:Map, textRepr let runtimeResolution = PackageResolver.Resolve( getVersionF, + getPreferredVersionF, getPackageDetailsF, groupName, group.Options.ResolverStrategyForDirectDependencies, @@ -348,9 +364,9 @@ type DependenciesFile(fileName,groups:Map, textRepr |> Map.map resolveGroup - member private this.AddFrameworkRestriction(groupName, frameworkRestrictions:FrameworkRestriction list) = - if List.isEmpty frameworkRestrictions then this else - let restrictionString = sprintf "framework %s" (String.Join(", ",frameworkRestrictions)) + member private this.AddFrameworkRestriction(groupName, frameworkRestriction:FrameworkRestriction) = + if frameworkRestriction = FrameworkRestriction.NoRestriction then this else + let restrictionString = sprintf "restriction: %O" frameworkRestriction let list = new System.Collections.Generic.List<_>() list.AddRange textRepresentation @@ -689,13 +705,8 @@ type DependenciesFile(fileName,groups:Map, textRepr |> Seq.map(fun restrictions -> match restrictions with | Paket.Requirements.AutoDetectFramework -> failwithf "couldn't detect framework" - | Paket.Requirements.FrameworkRestrictionList list -> - list |> Seq.collect (function - | Paket.Requirements.FrameworkRestriction.Exactly framework - | Paket.Requirements.FrameworkRestriction.AtLeast framework -> Seq.singleton framework - | Paket.Requirements.FrameworkRestriction.Between (bottom,top) -> [bottom; top] |> Seq.ofList //TODO: do we need to cap the list of generated frameworks based on this? also see todo in Requirements.fs for potential generation of range for 'between' - | Paket.Requirements.FrameworkRestriction.Portable portable -> failwithf "unhandled portable framework %s" portable - ) + | Paket.Requirements.ExplicitRestriction list -> + list.RepresentedFrameworks |> Seq.choose (function SinglePlatform tf -> Some tf | _ -> None) ) |> Seq.concat ) diff --git a/src/Paket.Core/PaketConfigFiles/DependencyCache.fs b/src/Paket.Core/PaketConfigFiles/DependencyCache.fs index 5d8703bfe2..61fac1d20a 100644 --- a/src/Paket.Core/PaketConfigFiles/DependencyCache.fs +++ b/src/Paket.Core/PaketConfigFiles/DependencyCache.fs @@ -113,7 +113,7 @@ type DependencyCache (dependencyFile:DependenciesFile, lockFile:LockFile) = match tryGet (group,pack.Name) installModelCache with | None -> () | Some model -> - model.GetLibReferenceFiles framework |> Seq.iter (libs.Add >> ignore) + model.GetLibReferenceFiles (SinglePlatform framework) |> Seq.iter (libs.Add >> ignore) model.GetAllLegacyFrameworkReferences ()|> Seq.iter (sysLibs.Add >> ignore) ) @@ -202,7 +202,7 @@ type DependencyCache (dependencyFile:DependenciesFile, lockFile:LockFile) = let nuspec = Nuspec.Load nuspec.FullName nuspecCache.TryAdd((package.Name,package.Version),nuspec)|>ignore let files = NuGetV2.GetLibFiles(folder.FullName) - let model = InstallModel.CreateFromLibs(packageName, package.Version, [], files, [], [], nuspec) + let model = InstallModel.CreateFromLibs(packageName, package.Version, Paket.Requirements.FrameworkRestriction.NoRestriction, files, [], [], nuspec) installModelCache.TryAdd((groupName,package.Name) , model) |> ignore }) |> Array.ofSeq Async.Parallel exprs diff --git a/src/Paket.Core/PaketConfigFiles/InstallModel.fs b/src/Paket.Core/PaketConfigFiles/InstallModel.fs index dba3d05ffd..875a5f11c6 100644 --- a/src/Paket.Core/PaketConfigFiles/InstallModel.fs +++ b/src/Paket.Core/PaketConfigFiles/InstallModel.fs @@ -72,12 +72,12 @@ module ReferenceOrLibraryFolder = /// Represents a subfolder of a nuget package that provides files (content, references, etc) for one or more Target Profiles. This is a logical representation of the 'net45' folder in a NuGet package, for example. type FrameworkFolder<'T> = { Path : ParsedPlatformPath - Targets : TargetProfile list + Targets : TargetProfile Set FolderContents : 'T } with member this.GetSinglePlatforms() = this.Targets - |> List.choose (function SinglePlatform t -> Some t | _ -> None) + |> Seq.choose (function SinglePlatform t -> Some t | _ -> None) module FrameworkFolder = let map f (l:FrameworkFolder<_>) = { @@ -144,11 +144,16 @@ module FolderScanner = let toParseResult error (wasSuccess, result) = if wasSuccess then ParseSucceeded result else ParseError error - + let check errorMsg f x = if f x then ParseSucceeded x else ParseError (errorMsg) + let choose errorMsg f x = + match f x with + | Some y -> ParseSucceeded y + | None -> ParseError (errorMsg) + let parseDecimal x = Decimal.TryParse(x, Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture) let parsers = dict [ @@ -344,7 +349,7 @@ module InstallModel = [ { FolderScanner.AdvancedScanner.Name = "noSeperator"; FolderScanner.AdvancedScanner.Parser = FolderScanner.check "seperator not allowed" (fun s -> not (s.Contains "/" || s.Contains "\\")) >> FolderScanner.ParseResult.box } { FolderScanner.AdvancedScanner.Name = "tfm"; - FolderScanner.AdvancedScanner.Parser = PlatformMatching.extractPlatforms >> FolderScanner.ParseResult.ParseSucceeded >> FolderScanner.ParseResult.box } + FolderScanner.AdvancedScanner.Parser = FolderScanner.choose "invalid tfm" PlatformMatching.extractPlatforms >> FolderScanner.ParseResult.box } { FolderScanner.AdvancedScanner.Name = "rid"; FolderScanner.AdvancedScanner.Parser = (fun rid -> { Rid = rid }) >> FolderScanner.ParseResult.ParseSucceeded >> FolderScanner.ParseResult.box }] let trySscanf pf s = @@ -460,7 +465,7 @@ module InstallModel = /// This is for library references, which at the same time can be used for references (old world - pre dotnetcore) let getLegacyPlatformReferences frameworkIdentifier installModel = - getLegacyReferences (SinglePlatform frameworkIdentifier) installModel + getLegacyReferences frameworkIdentifier installModel let isEmpty (lib: FrameworkFolder> list) = lib @@ -671,27 +676,9 @@ module InstallModel = let addFrameworkAssemblyReference (installModel:InstallModel) (reference:FrameworkAssemblyReference) : InstallModel = let referenceApplies (folder : FrameworkFolder<_>) = - match reference.FrameworkRestrictions |> getRestrictionList with - | [] -> true - | restrictions -> - restrictions - |> List.exists (fun restriction -> - match restriction with - | FrameworkRestriction.Portable _ -> - folder.Targets - |> List.exists (fun target -> - match target with - | SinglePlatform _ -> false - | _ -> true) - | FrameworkRestriction.Exactly target -> - folder.GetSinglePlatforms() - |> List.exists ((=) target) - | FrameworkRestriction.AtLeast target -> - folder.GetSinglePlatforms() - |> List.exists (fun t -> t >= target && t.IsSameCategoryAs(target)) - | FrameworkRestriction.Between(min,max) -> - folder.GetSinglePlatforms() - |> List.exists (fun t -> t >= min && t < max && t.IsSameCategoryAs(min))) + applyRestrictionsToTargets (reference.FrameworkRestrictions |> getExplicitRestriction) (folder.Targets) + |> Seq.isEmpty + |> not let model = if List.isEmpty installModel.CompileLibFolders then @@ -733,33 +720,33 @@ module InstallModel = let targetsFile = t.Path (String.endsWithIgnoreCase ".props" targetsFile|| String.endsWithIgnoreCase ".targets" targetsFile))) - let applyFrameworkRestrictions (restrictions:FrameworkRestriction list) (installModel:InstallModel) = - match restrictions with - | [] -> installModel - | restrictions -> + let applyFrameworkRestrictions (restriction:FrameworkRestriction) (installModel:InstallModel) = + match restriction with + | FrameworkRestriction.HasNoRestriction -> installModel + | restriction -> let applyRestriction folder = - { folder with Targets = applyRestrictionsToTargets restrictions folder.Targets} + { folder with Targets = applyRestrictionsToTargets restriction folder.Targets} { installModel with CompileLibFolders = installModel.CompileLibFolders |> List.map applyRestriction - |> List.filter (fun folder -> folder.Targets <> []) + |> List.filter (fun folder -> not folder.Targets.IsEmpty) CompileRefFolders = installModel.CompileRefFolders |> List.map applyRestriction - |> List.filter (fun folder -> folder.Targets <> []) + |> List.filter (fun folder -> not folder.Targets.IsEmpty) RuntimeAssemblyFolders = installModel.RuntimeAssemblyFolders |> List.map applyRestriction - |> List.filter (fun folder -> folder.Targets <> []) + |> List.filter (fun folder -> not folder.Targets.IsEmpty) TargetsFileFolders = installModel.TargetsFileFolders |> List.map applyRestriction - |> List.filter (fun folder -> folder.Targets <> []) + |> List.filter (fun folder -> not folder.Targets.IsEmpty) } let rec addTargetsFiles (targetsFiles:UnparsedPackageFile list) (this:InstallModel) : InstallModel = @@ -869,5 +856,5 @@ type InstallModel with member this.RemoveIfCompletelyEmpty() = InstallModel.removeIfCompletelyEmpty this - static member CreateFromLibs(packageName, packageVersion, frameworkRestrictions:FrameworkRestriction list, libs : UnparsedPackageFile seq, targetsFiles, analyzerFiles, nuspec : Nuspec) = - InstallModel.createFromLibs packageName packageVersion frameworkRestrictions libs targetsFiles analyzerFiles nuspec \ No newline at end of file + static member CreateFromLibs(packageName, packageVersion, frameworkRestriction:FrameworkRestriction, libs : UnparsedPackageFile seq, targetsFiles, analyzerFiles, nuspec : Nuspec) = + InstallModel.createFromLibs packageName packageVersion frameworkRestriction libs targetsFiles analyzerFiles nuspec \ No newline at end of file diff --git a/src/Paket.Core/PaketConfigFiles/LockFile.fs b/src/Paket.Core/PaketConfigFiles/LockFile.fs index 1ddc8856d6..fa41bb1dc9 100644 --- a/src/Paket.Core/PaketConfigFiles/LockFile.fs +++ b/src/Paket.Core/PaketConfigFiles/LockFile.fs @@ -62,9 +62,9 @@ module LockFileSerializer = | Some condition -> yield "CONDITION: " + condition.ToUpper() | None -> () - match options.Settings.FrameworkRestrictions |> getRestrictionList with - | [] -> () - | list -> yield "FRAMEWORK: " + (String.Join(", ",list)).ToUpper()] + match options.Settings.FrameworkRestrictions |> getExplicitRestriction with + | FrameworkRestriction.HasNoRestriction -> () + | list -> yield "RESTRICTION: " + list.ToString() ] /// [omit] let serializePackages options (resolved : PackageResolution) = @@ -104,7 +104,7 @@ module LockFileSerializer = let settings = if package.Settings.FrameworkRestrictions = options.Settings.FrameworkRestrictions then - { package.Settings with FrameworkRestrictions = FrameworkRestrictionList [] } + { package.Settings with FrameworkRestrictions = ExplicitRestriction FrameworkRestriction.NoRestriction } else package.Settings let s = @@ -124,11 +124,11 @@ module LockFileSerializer = let s = v.ToString() if s = "" then s else "(" + s + ")" - let restrictions = filterRestrictions options.Settings.FrameworkRestrictions restrictions |> getRestrictionList - if List.isEmpty restrictions || restrictions = getRestrictionList options.Settings.FrameworkRestrictions then + let restrictions = filterRestrictions options.Settings.FrameworkRestrictions restrictions |> getExplicitRestriction + if FrameworkRestriction.NoRestriction = restrictions || restrictions = getExplicitRestriction options.Settings.FrameworkRestrictions then yield sprintf " %O %s" name versionStr else - yield sprintf " %O %s - framework: %s" name versionStr (String.Join(", ",restrictions).ToLower())] + yield sprintf " %O %s - restriction: %O" name versionStr restrictions] String.Join(Environment.NewLine, all |> List.map (fun s -> s.TrimEnd())) @@ -280,7 +280,8 @@ module LockFileParser = | x -> failwithf "Unknown copy_content_to_output_dir settings: %A" x InstallOption (CopyContentToOutputDir setting) - | _, String.RemovePrefix "FRAMEWORK:" trimmed -> InstallOption(FrameworkRestrictions(FrameworkRestrictionList (trimmed.Trim() |> Requirements.parseRestrictions true))) + | _, String.RemovePrefix "FRAMEWORK:" trimmed -> InstallOption(FrameworkRestrictions(ExplicitRestriction (trimmed.Trim() |> Requirements.parseRestrictionsLegacy true))) + | _, String.RemovePrefix "RESTRICTION:" trimmed -> InstallOption(FrameworkRestrictions(ExplicitRestriction (trimmed.Trim() |> Requirements.parseRestrictions true))) | _, String.RemovePrefix "CONDITION:" trimmed -> InstallOption(ReferenceCondition(trimmed.Trim().ToUpper())) | _, String.RemovePrefix "CONTENT:" trimmed -> let setting = @@ -313,24 +314,29 @@ module LockFileParser = | _, String.RemovePrefix "os: " trimmed -> InstallOption(OperatingSystemRestriction trimmed) | _, trimmed when line.StartsWith " " -> + let pos = trimmed.IndexOf " - " + let namePart, settingsPart = + if pos >= 0 then + trimmed.Substring(0, pos), trimmed.Substring (pos + 3) + else + trimmed, "" let frameworkSettings = - if trimmed.Contains " - " then - let pos = trimmed.LastIndexOf " - " + if not (String.IsNullOrEmpty settingsPart) then try - InstallSettings.Parse(trimmed.Substring(pos + 3)) + InstallSettings.Parse(settingsPart) with - | _ -> InstallSettings.Parse("framework: " + trimmed.Substring(pos + 3)) // backwards compatible + | _ -> InstallSettings.Parse("framework: " + settingsPart) // backwards compatible else InstallSettings.Default - if trimmed.Contains "(" then - let parts = trimmed.Split '(' - NugetDependency (parts.[0].Trim(),parts.[1].Replace("(", "").Replace(")", "").Trim(),frameworkSettings) + if namePart.Contains "(" then + let parts = namePart.Split '(' + let first = parts.[0] + let rest = String.Join ("(", parts |> Seq.skip 1) + let versionEndPos = rest.IndexOf(")") + if versionEndPos < 0 then failwithf "Missing matching ') in line '%s'" line + NugetDependency (parts.[0].Trim(),rest.Substring(0, versionEndPos).Trim(),frameworkSettings) else - if trimmed.Contains(" -") then - let pos = trimmed.IndexOf(" -") - NugetDependency (trimmed.Substring(0,pos),">= 0",frameworkSettings) - else - NugetDependency (trimmed,">= 0",frameworkSettings) + NugetDependency (namePart.Trim(),">= 0",frameworkSettings) | Some "NUGET", trimmed -> NugetPackage trimmed | Some "GITHUB", trimmed -> SourceFile(GitHubLink, trimmed) | Some "GIST", trimmed -> SourceFile(GistLink, trimmed) @@ -891,7 +897,7 @@ type LockFile (fileName:string, groups: Map) = let nuspec = FileInfo(sprintf "%s/packages%s/%O/%O.nuspec" this.RootPath groupFolder packageName packageName) let nuspec = Nuspec.Load nuspec.FullName let files = NuGetV2.GetLibFiles(folder.FullName) - InstallModel.CreateFromLibs(packageName, resolvedPackage.Version, [], files, [], [], nuspec) + InstallModel.CreateFromLibs(packageName, resolvedPackage.Version, FrameworkRestriction.NoRestriction, files, [], [], nuspec) /// Returns a list of packages inside the lockfile with their group and version number diff --git a/src/Paket.Core/PaketConfigFiles/ProjectFile.fs b/src/Paket.Core/PaketConfigFiles/ProjectFile.fs index 0a9b687af8..592ada8b74 100644 --- a/src/Paket.Core/PaketConfigFiles/ProjectFile.fs +++ b/src/Paket.Core/PaketConfigFiles/ProjectFile.fs @@ -670,7 +670,7 @@ module ProjectFile = |> Set.ofList let model = model.FilterReferences references - let createItemGroup (targets:TargetProfile list) (frameworkReferences:FrameworkReference list) (libraries:Library list) = + let createItemGroup (targets:TargetProfile Set) (frameworkReferences:FrameworkReference list) (libraries:Library list) = let itemGroup = createNode "ItemGroup" project for ref in frameworkReferences |> List.sortBy (fun f -> f.Name) do @@ -736,8 +736,9 @@ module ProjectFile = // I don't think there is anyone actually using this part, but it's there for backwards compat. let netCoreRestricted = model.ApplyFrameworkRestrictions - [ FrameworkRestriction.AtLeast (FrameworkIdentifier.DotNetStandard DotNetStandardVersion.V1_0); - FrameworkRestriction.AtLeast (FrameworkIdentifier.DotNetCore DotNetCoreVersion.V1_0) ] + ((List.map DotNetCore KnownTargetProfiles.DotNetCoreVersions @ List.map DotNetStandard KnownTargetProfiles.DotNetStandardVersions) + |> List.map FrameworkRestriction.Exactly + |> List.fold FrameworkRestriction.combineRestrictionsWithOr FrameworkRestriction.EmptySet) // handle legacy conditions let conditions = @@ -761,7 +762,7 @@ module ProjectFile = for frameworkAssembly in frameworkReferences do for t in libFolder.Targets do if not <| usedFrameworkLibs.Add(t,frameworkAssembly.Name) then - assemblyTargets := List.filter ((<>) t) !assemblyTargets + assemblyTargets := Set.remove t !assemblyTargets // List.filter ((<>) t) !assemblyTargets duplicates.Add frameworkAssembly.Name |> ignore if !assemblyTargets = libFolder.Targets then @@ -973,8 +974,6 @@ module ProjectFile = let getTargetProfile (project:ProjectFile) = match getTargetFrameworkProfile project with - | Some profile when profile = "Client" -> - SinglePlatform (DotNetFramework FrameworkVersion.V4_Client) | Some profile when String.IsNullOrWhiteSpace profile |> not -> KnownTargetProfiles.FindPortableProfile profile | _ -> @@ -991,12 +990,6 @@ module ProjectFile = | None -> defaultResult | Some x -> SinglePlatform x - let getTargetFramework (project:ProjectFile) = - match getTargetProfile project with - | SinglePlatform x -> Some x - | PortableProfile (_, x::_) -> Some x - | _ -> None - let updateReferences rootPath (completeModel: Map) @@ -1041,7 +1034,7 @@ module ProjectFile = |> Seq.map (fun kv -> deleteCustomModelNodes (snd kv.Value) project let installSettings = snd usedPackages.[kv.Key] - let restrictionList = installSettings.FrameworkRestrictions |> getRestrictionList + let restrictionList = installSettings.FrameworkRestrictions |> getExplicitRestriction let projectModel = (snd kv.Value) @@ -1050,17 +1043,15 @@ module ProjectFile = .RemoveIfCompletelyEmpty() if directPackages.ContainsKey kv.Key then - match getTargetFramework project with - | Some targetFramework -> - if isTargetMatchingRestrictions(restrictionList,SinglePlatform targetFramework) then - if projectModel.GetLibReferenceFiles targetFramework |> Seq.isEmpty then - let libReferences = - projectModel.GetAllLegacyReferences() - - if not (Seq.isEmpty libReferences) then - traceWarnfn "Package %O contains libraries, but not for the selected TargetFramework %O in project %s." - (snd kv.Key) targetFramework project.FileName - | _ -> () + let targetProfile = getTargetProfile project + if isTargetMatchingRestrictions(restrictionList,targetProfile) then + if projectModel.GetLibReferenceFiles targetProfile |> Seq.isEmpty then + let libReferences = + projectModel.GetAllLegacyReferences() + + if not (Seq.isEmpty libReferences) then + traceWarnfn "Package %O contains libraries, but not for the selected TargetFramework %O in project %s." + (snd kv.Key) targetProfile project.FileName let importTargets = defaultArg installSettings.ImportTargets true @@ -1499,8 +1490,6 @@ type ProjectFile with member this.GetTargetFrameworkIdentifier () = ProjectFile.getTargetFrameworkIdentifier this - member this.GetTargetFramework () = ProjectFile.getTargetFramework this - member this.GetTargetFrameworkProfile () = ProjectFile.getTargetFrameworkProfile this member this.GetTargetProfile () = ProjectFile.getTargetProfile this diff --git a/src/Paket.Core/PaketConfigFiles/ReferencesFile.fs b/src/Paket.Core/PaketConfigFiles/ReferencesFile.fs index 19abd51d95..fa7f3bdb99 100644 --- a/src/Paket.Core/PaketConfigFiles/ReferencesFile.fs +++ b/src/Paket.Core/PaketConfigFiles/ReferencesFile.fs @@ -168,7 +168,7 @@ type ReferencesFile = { this with Groups = newGroups } - member this.AddNuGetReference(groupName, packageName : PackageName) = this.AddNuGetReference(groupName, packageName, true, true, FrameworkRestrictionList [], false, false, None, null) + member this.AddNuGetReference(groupName, packageName : PackageName) = this.AddNuGetReference(groupName, packageName, true, true, ExplicitRestriction FrameworkRestriction.NoRestriction, false, false, None, null) member this.RemoveNuGetReference(groupName, packageName : PackageName) = let group = this.Groups.[groupName] diff --git a/src/Paket.Core/PublicAPI.fs b/src/Paket.Core/PublicAPI.fs index a116bb389f..7ab6186b1f 100644 --- a/src/Paket.Core/PublicAPI.fs +++ b/src/Paket.Core/PublicAPI.fs @@ -460,10 +460,10 @@ type Dependencies(dependenciesFileName: string) = let nuspec = FileInfo(sprintf "%s/packages%s/%O/%O.nuspec" this.RootPath groupFolder packageName packageName) let nuspec = Nuspec.Load nuspec.FullName let files = NuGetV2.GetLibFiles(folder.FullName) - InstallModel.CreateFromLibs(packageName, resolvedPackage.Version, [], files, [], [], nuspec) + InstallModel.CreateFromLibs(packageName, resolvedPackage.Version, Paket.Requirements.FrameworkRestriction.NoRestriction, files, [], [], nuspec) /// Returns all libraries for the given package and framework. - member this.GetLibraries(groupName,packageName,frameworkIdentifier:FrameworkIdentifier) = + member this.GetLibraries(groupName,packageName,frameworkIdentifier:TargetProfile) = this .GetInstalledPackageModel(groupName,packageName) .GetLibReferences(frameworkIdentifier) @@ -609,6 +609,7 @@ type Dependencies(dependenciesFileName: string) = let versions = NuGetV2.GetVersions true alternativeProjectRoot root (sources, PackageName name) + |> Async.RunSynchronously |> List.map (fun (v,_) -> v.ToString()) |> List.toArray |> SemVer.SortVersions diff --git a/src/Paket.Core/Versioning/FrameworkHandling.fs b/src/Paket.Core/Versioning/FrameworkHandling.fs index 52bdd945ad..8d7a767be3 100644 --- a/src/Paket.Core/Versioning/FrameworkHandling.fs +++ b/src/Paket.Core/Versioning/FrameworkHandling.fs @@ -3,6 +3,7 @@ open System.IO open System open System.Diagnostics +open Logging /// The .NET Standard version. @@ -47,8 +48,8 @@ type FrameworkVersion = | V2 | V3 | V3_5 - | V4_Client | V4 + | V4_0_3 | V4_5 | V4_5_1 | V4_5_2 @@ -66,8 +67,8 @@ type FrameworkVersion = | V2 -> "v2.0" | V3 -> "v3.0" | V3_5 -> "v3.5" - | V4_Client -> "v4.0" | V4 -> "v4.0" + | V4_0_3 -> "v4.0.3" | V4_5 -> "v4.5" | V4_5_1 -> "v4.5.1" | V4_5_2 -> "v4.5.2" @@ -86,8 +87,8 @@ type FrameworkVersion = | FrameworkVersion.V2 -> "20" | FrameworkVersion.V3 -> "30" | FrameworkVersion.V3_5 -> "35" - | FrameworkVersion.V4_Client -> "40" - | FrameworkVersion.V4 -> "40-full" + | FrameworkVersion.V4 -> "40" + | FrameworkVersion.V4_0_3 -> "403" | FrameworkVersion.V4_5 -> "45" | FrameworkVersion.V4_5_1 -> "451" | FrameworkVersion.V4_5_2 -> "452" @@ -112,6 +113,12 @@ type UAPVersion = match this with | UAPVersion.V10 -> "100" + member this.NetCoreVersion = + // WTF: https://github.com/onovotny/MSBuildSdkExtras/blob/8d2d4ad63b552481da06e646dbb6504abc415260/src/build/platforms/Windows.targets + match this with + // Assumed from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore + | UAPVersion.V10 -> "v5.0" + [] /// The .NET Standard version. @@ -178,9 +185,9 @@ module KnownAliases = "winrt", "netcore" "netcoreapp", "netcore" "silverlight", "sl" + "windowsPhoneApp", "wpa" "windowsphone", "wp" "windows", "win" - "windowsPhoneApp", "wpa" ".netportable", "portable" "netportable", "portable" "10.0", "100" @@ -217,6 +224,80 @@ type Platform = | UnknownPlatform s -> s override x.ToString() = x.AsString +[] +type WindowsPhoneVersion = + | V7 + | V7_1 + | V7_5 + | V8 + | V8_1 + member this.ShortString() = + match this with + | WindowsPhoneVersion.V7 -> "7" + | WindowsPhoneVersion.V7_1 -> "71" + | WindowsPhoneVersion.V7_5 -> "75" + | WindowsPhoneVersion.V8 -> "8" + | WindowsPhoneVersion.V8_1 -> "81" + override this.ToString() = + match this with + | WindowsPhoneVersion.V7 -> "v7.0" + | WindowsPhoneVersion.V7_1 -> "v7.1" + | WindowsPhoneVersion.V7_5 -> "v7.5" + | WindowsPhoneVersion.V8 -> "v8.0" + | WindowsPhoneVersion.V8_1 -> "v8.1" + +[] +type WindowsPhoneAppVersion = + | V8 + | V8_1 + member this.ShortString() = + match this with + | WindowsPhoneAppVersion.V8 -> "8" + | WindowsPhoneAppVersion.V8_1 -> "81" + override this.ToString() = + match this with + | WindowsPhoneAppVersion.V8 -> "v8.0" + | WindowsPhoneAppVersion.V8_1 -> "v8.1" + +[] +type SilverlightVersion = + | V3 + | V4 + | V5 + member this.ShortString() = + match this with + | SilverlightVersion.V3 -> "3" + | SilverlightVersion.V4 -> "4" + | SilverlightVersion.V5 -> "5" + override this.ToString() = + match this with + | SilverlightVersion.V3 -> "v3.0" + | SilverlightVersion.V4 -> "v4.0" + | SilverlightVersion.V5 -> "v5.0" + +[] +type WindowsVersion = + | V8 + | V8_1 + | V10 + member this.NetCoreVersion = + // WTF: https://github.com/onovotny/MSBuildSdkExtras/blob/8d2d4ad63b552481da06e646dbb6504abc415260/src/build/platforms/Windows.targets + match this with + | WindowsVersion.V8 -> "v4.5" + | WindowsVersion.V8_1 -> "v4.5.1" + // Assumed from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore + | WindowsVersion.V10 -> "v5.0" + member this.ShortString() = + match this with + | WindowsVersion.V8 -> "8" + | WindowsVersion.V8_1 -> "81" + | WindowsVersion.V10 -> "10" + override this.ToString() = + match this with + | WindowsVersion.V8 -> "v8.0" + | WindowsVersion.V8_1 -> "v8.1" + | WindowsVersion.V10 -> "v10.0" + /// Framework Identifier type. // Each time a new version is added NuGetPackageCache.CurrentCacheVersion should be bumped. type FrameworkIdentifier = @@ -233,12 +314,11 @@ type FrameworkIdentifier = | Native of BuildMode * Platform | XamariniOS | XamarinMac - | Windows of string - | WindowsPhoneSilverlight of string - | WindowsPhoneApp of string - | Silverlight of string + | Windows of WindowsVersion + | WindowsPhone of WindowsPhoneVersion + | WindowsPhoneApp of WindowsPhoneAppVersion + | Silverlight of SilverlightVersion - override x.ToString() = match x with | DotNetFramework v -> "net" + v.ShortString() @@ -254,14 +334,33 @@ type FrameworkIdentifier = | XamariniOS -> "xamarinios" | UAP v -> "uap" + v.ShortString() | XamarinMac -> "xamarinmac" - | Windows v -> "win" + v - | WindowsPhoneSilverlight v -> "wp" + v - | WindowsPhoneApp v -> "wpa" + v - | Silverlight v -> "sl" + v.Replace("v","").Replace(".","") + | Windows v -> "win" + v.ShortString() + | WindowsPhone v -> "wp" + v.ShortString() + | WindowsPhoneApp v -> "wpa" + v.ShortString() + | Silverlight v -> "sl" + v.ShortString() + member internal x.RawSupportedPlatformsTransitive = + let findNewPlats (known:FrameworkIdentifier list) (lastStep:FrameworkIdentifier list) = + lastStep + |> List.collect (fun k -> k.RawSupportedPlatforms) + |> List.filter (fun k -> known |> Seq.contains k |> not) + + Seq.initInfinite (fun _ -> 1) + |> Seq.scan (fun state _ -> + match state with + | Some (known, lastStep) -> + match findNewPlats known lastStep with + | [] -> None + | items -> Some (known @ items, items) + | None -> None) (Some ([x], [x])) + |> Seq.takeWhile (fun i -> i.IsSome) + |> Seq.choose id + |> Seq.last + |> fst + // returns a list of compatible platforms that this platform also supports - member x.SupportedPlatforms = + member internal x.RawSupportedPlatforms = match x with | MonoAndroid -> [ ] | MonoTouch -> [ ] @@ -269,15 +368,15 @@ type FrameworkIdentifier = | Native(_) -> [ ] | XamariniOS -> [ ] | XamarinMac -> [ ] - | UAP UAPVersion.V10 -> [ ] + | UAP UAPVersion.V10 -> [ Windows WindowsVersion.V8_1; WindowsPhoneApp WindowsPhoneAppVersion.V8_1; DotNetStandard DotNetStandardVersion.V1_4 ] | DotNetFramework FrameworkVersion.V1 -> [ ] | DotNetFramework FrameworkVersion.V1_1 -> [ DotNetFramework FrameworkVersion.V1 ] | DotNetFramework FrameworkVersion.V2 -> [ DotNetFramework FrameworkVersion.V1_1 ] | DotNetFramework FrameworkVersion.V3 -> [ DotNetFramework FrameworkVersion.V2 ] | DotNetFramework FrameworkVersion.V3_5 -> [ DotNetFramework FrameworkVersion.V3 ] - | DotNetFramework FrameworkVersion.V4_Client -> [ DotNetFramework FrameworkVersion.V3_5 ] - | DotNetFramework FrameworkVersion.V4 -> [ DotNetFramework FrameworkVersion.V4_Client ] - | DotNetFramework FrameworkVersion.V4_5 -> [ DotNetFramework FrameworkVersion.V4; DotNetStandard DotNetStandardVersion.V1_1 ] + | DotNetFramework FrameworkVersion.V4 -> [ DotNetFramework FrameworkVersion.V3_5 ] + | DotNetFramework FrameworkVersion.V4_0_3 -> [ DotNetFramework FrameworkVersion.V4 ] + | DotNetFramework FrameworkVersion.V4_5 -> [ DotNetFramework FrameworkVersion.V4_0_3; DotNetStandard DotNetStandardVersion.V1_1 ] | DotNetFramework FrameworkVersion.V4_5_1 -> [ DotNetFramework FrameworkVersion.V4_5; DotNetStandard DotNetStandardVersion.V1_2 ] | DotNetFramework FrameworkVersion.V4_5_2 -> [ DotNetFramework FrameworkVersion.V4_5_1; DotNetStandard DotNetStandardVersion.V1_2 ] | DotNetFramework FrameworkVersion.V4_5_3 -> [ DotNetFramework FrameworkVersion.V4_5_2; DotNetStandard DotNetStandardVersion.V1_2 ] @@ -304,79 +403,19 @@ type FrameworkIdentifier = | DotNetUnity DotNetUnityVersion.V3_5_Subset -> [ ] | DotNetUnity DotNetUnityVersion.V3_5_Micro -> [ ] | DotNetUnity DotNetUnityVersion.V3_5_Web -> [ ] - | Silverlight "v3.0" -> [ ] - | Silverlight "v4.0" -> [ Silverlight "v3.0" ] - | Silverlight "v5.0" -> [ Silverlight "v4.0" ] - | Windows "v4.5" -> [ ] - | Windows "v4.5.1" -> [ Windows "v4.5" ] - | WindowsPhoneApp "v8.1" -> [ DotNetStandard DotNetStandardVersion.V1_2 ] - | WindowsPhoneSilverlight "v7.0" -> [ ] - | WindowsPhoneSilverlight "v7.1" -> [ WindowsPhoneSilverlight "v7.0" ] - | WindowsPhoneSilverlight "v8.0" -> [ WindowsPhoneSilverlight "v7.1"; DotNetStandard DotNetStandardVersion.V1_0 ] - | WindowsPhoneSilverlight "v8.1" -> [ WindowsPhoneSilverlight "v8.0"; DotNetStandard DotNetStandardVersion.V1_0 ] - - // wildcards for future versions. new versions should be added above, though, so the penalty will be calculated correctly. - | Silverlight _ -> [ Silverlight "v5.0" ] - | Windows _ -> [ Windows "v4.5.1" ] - | 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 - | UAP _, UAP _ -> true - | DotNetFramework _, DotNetFramework _ -> true - | DotNetStandard _, DotNetStandard _ -> true - | DotNetCore _, DotNetCore _ -> true - | DotNetUnity _, DotNetUnity _ -> 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 - | Native _, Native _ -> true - | _ -> false - - /// TODO: some notion of an increasing/decreasing sequence of FrameworkIdentitifers, so that Between(bottom, top) constraints can enumerate the list - - member x.IsCompatible y = - x = y || - (x.SupportedPlatforms |> Seq.exists (fun x' -> x' = y && not (x'.IsSameCategoryAs x))) || - (y.SupportedPlatforms |> Seq.exists (fun y' -> y' = x && not (y'.IsSameCategoryAs y))) - - member x.IsAtLeast y = - if x.IsSameCategoryAs y then - x >= y - else - let isCompatible() = - y.SupportedPlatforms - |> Seq.exists x.IsAtLeast - - match x,y with - | DotNetStandard _, DotNetFramework _ -> isCompatible() - | DotNetFramework _, DotNetStandard _ -> isCompatible() - | _ -> false - - member x.IsAtMost y = - if x.IsSameCategoryAs y then - x < y - else - let isCompatible() = - y.SupportedPlatforms - |> Seq.exists x.IsAtMost - - match x,y with - | DotNetStandard _, DotNetFramework _ -> isCompatible() - | DotNetFramework _, DotNetStandard _ -> isCompatible() - | _ -> false - - - member x.IsBetween(a,b) = x.IsAtLeast a && x.IsAtMost b + | Silverlight SilverlightVersion.V3 -> [ ] + | Silverlight SilverlightVersion.V4 -> [ Silverlight SilverlightVersion.V3 ] + | Silverlight SilverlightVersion.V5 -> [ Silverlight SilverlightVersion.V4 ] + | Windows WindowsVersion.V8 -> [ ] + | Windows WindowsVersion.V8_1 -> [ Windows WindowsVersion.V8 ] + | Windows WindowsVersion.V10 -> [ Windows WindowsVersion.V8_1 ] + | WindowsPhoneApp WindowsPhoneAppVersion.V8 -> [ ] + | WindowsPhoneApp WindowsPhoneAppVersion.V8_1 -> [ DotNetStandard DotNetStandardVersion.V1_2 ] + | WindowsPhone WindowsPhoneVersion.V7 -> [ ] + | WindowsPhone WindowsPhoneVersion.V7_1 -> [ WindowsPhone WindowsPhoneVersion.V7 ] + | WindowsPhone WindowsPhoneVersion.V7_5 -> [ WindowsPhone WindowsPhoneVersion.V7_1 ] + | WindowsPhone WindowsPhoneVersion.V8 -> [ WindowsPhone WindowsPhoneVersion.V7_5; DotNetStandard DotNetStandardVersion.V1_0 ] + | WindowsPhone WindowsPhoneVersion.V8_1 -> [ WindowsPhone WindowsPhoneVersion.V8 ] module FrameworkDetection = @@ -400,6 +439,7 @@ module FrameworkDetection = open Logging /// parse a string to construct a Netframework, NetCore, NetStandard, or other dotnet identifier + [] let Extract = memoize (fun (path:string) -> @@ -410,6 +450,7 @@ module FrameworkDetection = sb.ToString() // Each time the parsing is changed, NuGetPackageCache.CurrentCacheVersion should be bumped. + // http://nugettoolsdev.azurewebsites.net/4.0.0/parse-framework?framework=.NETPortable%2CVersion%3Dv0.0%2CProfile%3DProfile2 let result = match path with | "net35-Unity Web v3.5" -> Some (DotNetUnity DotNetUnityVersion.V3_5_Web) @@ -421,8 +462,8 @@ module FrameworkDetection = | "net20" | "net2" | "net" | "net20-full" | "net20-client" | "20" -> Some (DotNetFramework FrameworkVersion.V2) | "net30" | "net3" | "30" -> Some (DotNetFramework FrameworkVersion.V3) | "net35" | "net35-client" | "net35-full" | "35" -> Some (DotNetFramework FrameworkVersion.V3_5) - | "net40" | "net4" | "40" | "net40-client" | "net4-client" -> Some (DotNetFramework FrameworkVersion.V4_Client) - | "net40-full" | "net403" -> Some (DotNetFramework FrameworkVersion.V4) + | "net40-full" | "net40" | "net4" | "40" | "net40-client" | "net4-client" -> Some (DotNetFramework FrameworkVersion.V4) + | "net403"| "net403-full"| "net403-client" -> Some (DotNetFramework FrameworkVersion.V4_0_3) | "net45" | "net45-full" | "45" -> Some (DotNetFramework FrameworkVersion.V4_5) | "net451" -> Some (DotNetFramework FrameworkVersion.V4_5_1) | "net452" -> Some (DotNetFramework FrameworkVersion.V4_5_2) @@ -447,16 +488,17 @@ module FrameworkDetection = | "native/address-model-32" -> Some(Native(NoBuildMode,Win32)) | "native/address-model-64" -> Some(Native(NoBuildMode,X64)) | "native" -> Some(Native(NoBuildMode,NoPlatform)) - | "sl" | "sl3" | "sl30" -> Some (Silverlight "v3.0") - | "sl4" | "sl40" -> Some (Silverlight "v4.0") - | "sl5" | "sl50" -> Some (Silverlight "v5.0") - | "win8" | "windows8" | "win80" | "netcore45" | "win" | "winv45" -> Some (Windows "v4.5") - | "win81" | "windows81" | "netcore46" | "netcore451" | "winv451" -> Some (Windows "v4.5.1") - | "wp7" | "wp70" | "wpv7" | "wpv70" | "sl4-wp7"| "sl4-wp70" -> Some (WindowsPhoneSilverlight "v7.0") - | "wp71" | "wpv71" | "sl4-wp71" | "sl4-wp" -> Some (WindowsPhoneSilverlight "v7.1") - | "wpa00" | "wpa" | "wpa81" | "wpav81" | "wpapp81" | "wpapp" -> Some (WindowsPhoneApp "v8.1") - | "wp8" | "wp80" | "wpv80" -> Some (WindowsPhoneSilverlight "v8.0") - | "wp81" | "wpv81" -> Some (WindowsPhoneSilverlight "v8.1") + | "sl" | "sl3" | "sl30" -> Some (Silverlight SilverlightVersion.V3) + | "sl4" | "sl40" -> Some (Silverlight SilverlightVersion.V4) + | "sl5" | "sl50" -> Some (Silverlight SilverlightVersion.V5) + | "win8" | "windows8" | "win80" | "netcore45" | "win" | "winv45" -> Some (Windows WindowsVersion.V8) + | "win81" | "windows81" | "netcore46" | "netcore451" | "winv451" -> Some (Windows WindowsVersion.V8_1) + | "wp7" | "wp70" | "wpv7" | "wpv70" | "sl4-wp7"| "sl4-wp70" -> Some (WindowsPhone WindowsPhoneVersion.V7) + | "wp71" | "wpv71" | "sl4-wp71" | "sl4-wp" -> Some (WindowsPhone WindowsPhoneVersion.V7_1) + | "wp75" | "wpv75" | "sl4-wp75" -> Some (WindowsPhone WindowsPhoneVersion.V7_5) + | "wp8" | "wp80" | "wpv80" -> Some (WindowsPhone WindowsPhoneVersion.V8) + | "wpa00" | "wpa" | "wpa81" | "wpav81" | "wpapp81" | "wpapp" -> Some (WindowsPhoneApp WindowsPhoneAppVersion.V8_1) + | "wp81" | "wpv81" -> Some (WindowsPhone WindowsPhoneVersion.V8_1) | "dnx451" -> Some(DNX FrameworkVersion.V4_5_1) | "dnxcore50" | "netplatform50" | "netcore50" | "aspnetcore50" | "aspnet50" | "dotnet" -> Some(DNXCore FrameworkVersion.V5_0) | v when v.StartsWith "dotnet" -> Some(DNXCore FrameworkVersion.V5_0) @@ -487,87 +529,206 @@ module FrameworkDetection = else Extract(path.Substring(startPos + 4, endPos - startPos - 5)) + +type PortableProfileType = + | UnsupportedProfile of FrameworkIdentifier list + /// portable-net40+sl4+win8+wp7 + | Profile2 + /// portable-net40+sl4 + | Profile3 + /// portable-net45+sl4+win8+wp7 + | Profile4 + /// portable-net40+win8 + | Profile5 + /// portable-net403+win8 + | Profile6 + /// portable-net45+win8 + | Profile7 + /// portable-net40+sl5 + | Profile14 + /// portable-net403+sl4 + | Profile18 + /// portable-net403+sl5 + | Profile19 + /// portable-net45+sl4 + | Profile23 + /// portable-net45+sl5 + | Profile24 + /// portable-win81+wp81 + | Profile31 + /// portable-win81+wpa81 + | Profile32 + /// portable-net40+sl4+win8+wp8 + | Profile36 + /// portable-net40+sl5+win8 + | Profile37 + /// portable-net403+sl4+win8 + | Profile41 + /// portable-net403+sl5+win8 + | Profile42 + /// portable-net451+win81 + | Profile44 + /// portable-net45+sl4+win8 + | Profile46 + /// portable-net45+sl5+win8 + | Profile47 + /// portable-net45+wp8 + | Profile49 + /// portable-net45+win8+wp8 + | Profile78 + /// portable-wp81+wpa81 + | Profile84 + /// portable-net40+sl4+win8+wp75 + | Profile88 + /// portable-net40+win8+wpa81 + | Profile92 + /// portable-net403+sl4+win8+wp7 + | Profile95 + /// portable-net403+sl4+win8+wp75 + | Profile96 + /// portable-net403+win8+wpa81 + | Profile102 + /// portable-net45+sl4+win8+wp75 + | Profile104 + /// portable-net45+win8+wpa81 + | Profile111 + /// portable-net40+sl5+win8+wp8 + | Profile136 + /// portable-net403+sl4+win8+wp8 + | Profile143 + /// portable-net403+sl5+win8+wp8 + | Profile147 + /// portable-net451+win81+wpa81 + | Profile151 + /// portable-net45+sl4+win8+wp8 + | Profile154 + /// portable-win81+wp81+wpa81 + | Profile157 + /// portable-net45+sl5+win8+wp8 + | Profile158 + /// portable-net40+sl5+win8+wpa81 + | Profile225 + /// portable-net403+sl5+win8+wpa81 + | Profile240 + /// portable-net45+sl5+win8+wpa81 + | Profile255 + /// portable-net45+win8+wp8+wpa81 + | Profile259 + /// portable-net40+sl5+win8+wp8+wpa81 + | Profile328 + /// portable-net403+sl5+win8+wp8+wpa81 + | Profile336 + /// portable-net45+sl5+win8+wp8+wpa81 + | Profile344 + member x.ProfileName = + match x with + | UnsupportedProfile fws -> x.FolderName + | Profile2 -> "Profile2" + | Profile3 -> "Profile3" + | Profile4 -> "Profile4" + | Profile5 -> "Profile5" + | Profile6 -> "Profile6" + | Profile7 -> "Profile7" + | Profile14 -> "Profile14" + | Profile18 -> "Profile18" + | Profile19 -> "Profile19" + | Profile23 -> "Profile23" + | Profile24 -> "Profile24" + | Profile31 -> "Profile31" + | Profile32 -> "Profile32" + | Profile36 -> "Profile36" + | Profile37 -> "Profile37" + | Profile41 -> "Profile41" + | Profile42 -> "Profile42" + | Profile44 -> "Profile44" + | Profile46 -> "Profile46" + | Profile47 -> "Profile47" + | Profile49 -> "Profile49" + | Profile78 -> "Profile78" + | Profile84 -> "Profile84" + | Profile88 -> "Profile88" + | Profile92 -> "Profile92" + | Profile95 -> "Profile95" + | Profile96 -> "Profile96" + | Profile102 -> "Profile102" + | Profile104 -> "Profile104" + | Profile111 -> "Profile111" + | Profile136 -> "Profile136" + | Profile143 -> "Profile143" + | Profile147 -> "Profile147" + | Profile151 -> "Profile151" + | Profile154 -> "Profile154" + | Profile157 -> "Profile157" + | Profile158 -> "Profile158" + | Profile225 -> "Profile225" + | Profile240 -> "Profile240" + | Profile255 -> "Profile255" + | Profile259 -> "Profile259" + | Profile328 -> "Profile328" + | Profile336 -> "Profile336" + | Profile344 -> "Profile344" + + member x.Frameworks = + // http://nugettoolsdev.azurewebsites.net/4.0.0/parse-framework?framework=.NETPortable%2CVersion%3Dv0.0%2CProfile%3DProfile3 + match x with + | UnsupportedProfile fws -> fws + | Profile2 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V7 ] + | Profile3 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V4 ] + | Profile4 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V7 ] + | Profile5 -> [ DotNetFramework FrameworkVersion.V4; Windows WindowsVersion.V8 ] + | Profile6 -> [ DotNetFramework FrameworkVersion.V4_0_3; Windows WindowsVersion.V8 ] + | Profile7 -> [ DotNetFramework FrameworkVersion.V4_5; Windows WindowsVersion.V8 ] + | Profile14 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V5 ] + | Profile18 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V4 ] + | Profile19 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V5 ] + | Profile23 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V4 ] + | Profile24 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V5 ] + | Profile31 -> [ Windows WindowsVersion.V8_1; WindowsPhone WindowsPhoneVersion.V8_1 ] + | Profile32 -> [ Windows WindowsVersion.V8_1; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile36 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile37 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8 ] + | Profile41 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8 ] + | Profile42 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8 ] + | Profile44 -> [ DotNetFramework FrameworkVersion.V4_5_1; Windows WindowsVersion.V8_1 ] + | Profile46 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8 ] + | Profile47 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8 ] + | Profile49 -> [ DotNetFramework FrameworkVersion.V4_5; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile78 -> [ DotNetFramework FrameworkVersion.V4_5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile84 -> [ WindowsPhone WindowsPhoneVersion.V8_1; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile88 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V7_5 ] + | Profile92 -> [ DotNetFramework FrameworkVersion.V4; Windows WindowsVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile95 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V7 ] + | Profile96 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V7_5 ] + | Profile102 -> [ DotNetFramework FrameworkVersion.V4_0_3; Windows WindowsVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile104 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V7_5 ] + | Profile111 -> [ DotNetFramework FrameworkVersion.V4_5; Windows WindowsVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile136 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile143 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile147 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile151 -> [ DotNetFramework FrameworkVersion.V4_5_1; Windows WindowsVersion.V8_1; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile154 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V4; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile157 -> [ Windows WindowsVersion.V8_1; WindowsPhoneApp WindowsPhoneAppVersion.V8_1; WindowsPhone WindowsPhoneVersion.V8_1 ] + | Profile158 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8 ] + | Profile225 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile240 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile255 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile259 -> [ DotNetFramework FrameworkVersion.V4_5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile328 -> [ DotNetFramework FrameworkVersion.V4; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile336 -> [ DotNetFramework FrameworkVersion.V4_0_3; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + | Profile344 -> [ DotNetFramework FrameworkVersion.V4_5; Silverlight SilverlightVersion.V5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + member x.FolderName = + "portable-" + + String.Join ("+", + x.Frameworks + |> List.sort + |> List.map (fun fw -> fw.ToString())) type TargetProfile = | SinglePlatform of FrameworkIdentifier - | PortableProfile of string * FrameworkIdentifier list - - member this.ProfilesCompatibleWithPortableProfile = - match this with - | SinglePlatform _ -> [ ] - | PortableProfile(name,required) -> - let netstandard = - // See https://github.com/dotnet/corefx/blob/master/Documentation/architecture/net-platform-standard.md#portable-profiles - match name with - | "Profile7" -> [ DotNetStandard DotNetStandardVersion.V1_1 ] - | "Profile31" -> [ DotNetStandard DotNetStandardVersion.V1_0 ] - | "Profile32" -> [ DotNetStandard DotNetStandardVersion.V1_2 ] - | "Profile44" -> [ DotNetStandard DotNetStandardVersion.V1_2 ] - | "Profile49" -> [ DotNetStandard DotNetStandardVersion.V1_0 ] - | "Profile78" -> [ DotNetStandard DotNetStandardVersion.V1_0 ] - | "Profile84" -> [ DotNetStandard DotNetStandardVersion.V1_0 ] - | "Profile111" -> [ DotNetStandard DotNetStandardVersion.V1_1 ] - | "Profile151" -> [ DotNetStandard DotNetStandardVersion.V1_2 ] - | "Profile157" -> [ DotNetStandard DotNetStandardVersion.V1_0 ] - | "Profile259" -> [ DotNetStandard DotNetStandardVersion.V1_0 ] - | _ -> [ ] - required - |> List.map (function - | DotNetFramework FrameworkVersion.V4_5 - | DotNetFramework FrameworkVersion.V4_5_1 - | DotNetFramework FrameworkVersion.V4_5_2 - | DotNetFramework FrameworkVersion.V4_5_3 - | DotNetFramework FrameworkVersion.V4_6 - | DotNetFramework FrameworkVersion.V4_6_1 - | DotNetFramework FrameworkVersion.V4_6_2 - | DotNetFramework FrameworkVersion.V4_6_3 -> - [ - MonoTouch - MonoAndroid - XamariniOS - XamarinMac - ] - | _ -> [ ] - ) - |> List.reduce (@) - |> (@) netstandard - |> List.distinct - + | PortableProfile of PortableProfileType override this.ToString() = match this with | SinglePlatform x -> x.ToString() - | PortableProfile(name,_) -> - match name with - | "Profile5" -> "portable-net4+netcore45+MonoAndroid1+MonoTouch1" - | "Profile6" -> "portable-net403+netcore45+MonoAndroid1+MonoTouch1" - | "Profile7" -> "portable-net45+netcore45+MonoAndroid1+MonoTouch1" - | "Profile14" -> "portable-net4+sl5+MonoAndroid1+MonoTouch1" - | "Profile19" -> "portable-net403+sl5+MonoAndroid1+MonoTouch1" - | "Profile24" -> "portable-net45+sl5+MonoAndroid1+MonoTouch1" - | "Profile31" -> "portable-netcore451+wp81" - | "Profile32" -> "portable-netcore451+wpa81" - | "Profile37" -> "portable-net4+sl5+netcore45+MonoAndroid1+MonoTouch1" - | "Profile42" -> "portable-net403+sl5+netcore45+MonoAndroid1+MonoTouch1" - | "Profile44" -> "portable-net451+netcore451" - | "Profile47" -> "portable-net45+sl5+netcore45+MonoAndroid1+MonoTouch1" - | "Profile49" -> "portable-net45+wp8+MonoAndroid1+MonoTouch1" - | "Profile78" -> "portable-net45+netcore45+wp8+MonoAndroid1+MonoTouch1" - | "Profile84" -> "portable-wpa81+wp81" - | "Profile92" -> "portable-net4+netcore45+wpa81+MonoAndroid1+MonoTouch1" - | "Profile102" -> "portable-net403+netcore45+wpa81+MonoAndroid1+MonoTouch1" - | "Profile111" -> "portable-net45+netcore45+wpa81+MonoAndroid1+MonoTouch1" - | "Profile136" -> "portable-net4+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1" - | "Profile147" -> "portable-net403+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1" - | "Profile151" -> "portable-net451+netcore451+wpa81" - | "Profile157" -> "portable-netcore451+wpa81+wp81" - | "Profile158" -> "portable-net45+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1" - | "Profile225" -> "portable-net4+sl5+netcore45+wpa81+MonoAndroid1+MonoTouch1" - | "Profile240" -> "portable-net403+sl5+netcore45+wpa81" - | "Profile255" -> "portable-net45+sl5+netcore45+wpa81+MonoAndroid1+MonoTouch1" - | "Profile259" -> "portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1" - | "Profile328" -> "portable-net4+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1" - | "Profile336" -> "portable-net403+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1" - | "Profile344" -> "portable-net45+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1" - | _ -> "portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1" // Use Portable259 as default + | PortableProfile p -> p.FolderName module KnownTargetProfiles = let DotNetFrameworkVersions = [ @@ -576,8 +737,8 @@ module KnownTargetProfiles = FrameworkVersion.V2 FrameworkVersion.V3 FrameworkVersion.V3_5 - FrameworkVersion.V4_Client FrameworkVersion.V4 + FrameworkVersion.V4_0_3 FrameworkVersion.V4_5 FrameworkVersion.V4_5_1 FrameworkVersion.V4_5_2 @@ -630,88 +791,91 @@ module KnownTargetProfiles = DotNetCoreVersions |> List.map (DotNetCore >> SinglePlatform) + let WindowsVersions = [ + WindowsVersion.V8 + WindowsVersion.V8_1 + WindowsVersion.V10 + ] + let WindowsProfiles = - [SinglePlatform(Windows "v4.5") - SinglePlatform(Windows "v4.5.1")] + WindowsVersions + |> List.map (Windows >> SinglePlatform) let DotNetUnityProfiles = DotNetUnityVersions |> List.map (DotNetUnity >> SinglePlatform) + + let SilverlightVersions = [ + SilverlightVersion.V3 + SilverlightVersion.V4 + SilverlightVersion.V5 + ] let SilverlightProfiles = - [SinglePlatform(Silverlight "v3.0") - SinglePlatform(Silverlight "v4.0") - SinglePlatform(Silverlight "v5.0")] + SilverlightVersions + |> List.map (Silverlight >> SinglePlatform) let UAPProfiles = [SinglePlatform(UAP UAPVersion.V10)] - let WindowsPhoneSilverlightProfiles = - [SinglePlatform(WindowsPhoneSilverlight "v7.0") - SinglePlatform(WindowsPhoneSilverlight "v7.1") - SinglePlatform(WindowsPhoneSilverlight "v8.0") - SinglePlatform(WindowsPhoneSilverlight "v8.1")] + let WindowsPhoneVersions = [ + WindowsPhoneVersion.V7 + WindowsPhoneVersion.V7_1 + WindowsPhoneVersion.V7_5 + WindowsPhoneVersion.V8 + WindowsPhoneVersion.V8_1 + ] - let portableStandards p = - match p with - | "portable-net45+win8" -> [DotNetStandardVersion.V1_1] - | "portable-win81+wp81" -> [DotNetStandardVersion.V1_0] - | "portable-win81+wpa81" -> [DotNetStandardVersion.V1_2] - | "portable-net451+win81" -> [DotNetStandardVersion.V1_2] - | "portable-net45+wp8" -> [DotNetStandardVersion.V1_0] - | "portable-net45+win8+wp8" -> [DotNetStandardVersion.V1_0] - | "portable-wp81+wpa81" -> [DotNetStandardVersion.V1_0] - | "portable-net45+win8+wpa81" -> [DotNetStandardVersion.V1_1] - | "portable-net451+win81+wpa81" -> [DotNetStandardVersion.V1_2] - | "portable-win81+wp81+wpa81" -> [DotNetStandardVersion.V1_0] - | "portable-net45+win8+wpa81+wp8" -> [DotNetStandardVersion.V1_0] - | _ -> [] + let WindowsPhoneSilverlightProfiles = + WindowsPhoneVersions + |> List.map (WindowsPhone >> SinglePlatform) + // http://nugettoolsdev.azurewebsites.net/4.0.0/parse-framework?framework=.NETPortable%2CVersion%3Dv0.0%2CProfile%3DProfile3 let AllPortableProfiles = - [("Profile2", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v7.0" ]) - ("Profile3", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0" ]) - ("Profile4", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v7.0" ]) - ("Profile5", [ DotNetFramework FrameworkVersion.V4; Windows "v4.5" ]) - ("Profile6", [ DotNetFramework FrameworkVersion.V4; Windows "v4.5" ]) - ("Profile7" , [ DotNetFramework FrameworkVersion.V4_5; Windows "v4.5" ]) - ("Profile14", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0" ]) - ("Profile18", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0" ]) - ("Profile19", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0" ]) - ("Profile23", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v4.0" ]) - ("Profile24", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v5.0" ]) - ("Profile31", [ Windows "v4.5.1"; WindowsPhoneSilverlight "v8.1" ]) - ("Profile32", [ Windows "v4.5.1"; WindowsPhoneApp "v8.1" ]) - ("Profile36", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v8.0" ]) - ("Profile37", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; Windows "v4.5" ]) - ("Profile41", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0"; Windows "v4.5" ]) - ("Profile42", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; Windows "v4.5" ]) - ("Profile44", [ DotNetFramework FrameworkVersion.V4_5_1; Windows "v4.5.1" ]) - ("Profile46", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v4.0"; Windows "v4.5" ]) - ("Profile47", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v5.0"; Windows "v4.5" ]) - ("Profile49", [ DotNetFramework FrameworkVersion.V4_5; WindowsPhoneSilverlight "v8.0" ]) - ("Profile78", [ DotNetFramework FrameworkVersion.V4_5; Windows "v4.5"; WindowsPhoneSilverlight "v8.0" ]) - ("Profile84", [ WindowsPhoneApp "v8.1"; WindowsPhoneSilverlight "v8.1" ]) - ("Profile88", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v7.1" ]) - ("Profile92", [ DotNetFramework FrameworkVersion.V4; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile95", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v7.0" ]) - ("Profile96", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v7.1" ]) - ("Profile102", [ DotNetFramework FrameworkVersion.V4; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile104", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v7.1" ]) - ("Profile111", [ DotNetFramework FrameworkVersion.V4_5; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile136", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; WindowsPhoneSilverlight "v8.0"; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile143", [ DotNetFramework FrameworkVersion.V4; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v8.0" ]) - ("Profile147", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; Windows "v4.5"; WindowsPhoneSilverlight "v8.0" ]) - ("Profile151", [ DotNetFramework FrameworkVersion.V4_5_1; Windows "v4.5.1"; WindowsPhoneApp "v8.1" ]) - ("Profile154", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v4.0"; Windows "v4.5"; WindowsPhoneSilverlight "v8.0" ]) - ("Profile157", [ Windows "v4.5.1"; WindowsPhoneApp "v8.1"; WindowsPhoneSilverlight "v8.1" ]) - ("Profile158", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v5.0"; Windows "v4.5"; WindowsPhoneSilverlight "v8.0" ]) - ("Profile225", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile240", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile255", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v5.0"; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile259", [ DotNetFramework FrameworkVersion.V4_5; Windows "v4.5"; WindowsPhoneSilverlight "v8.0"; WindowsPhoneApp "v8.1" ]) - ("Profile328", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; WindowsPhoneSilverlight "v8.0"; Windows "v4.5"; WindowsPhoneApp "v8.1" ]) - ("Profile336", [ DotNetFramework FrameworkVersion.V4; Silverlight "v5.0"; Windows "v4.5"; WindowsPhoneApp "v8.1"; WindowsPhoneSilverlight "v8.0" ]) - ("Profile344", [ DotNetFramework FrameworkVersion.V4_5; Silverlight "v5.0"; Windows "v4.5"; WindowsPhoneApp "v8.1"; WindowsPhoneSilverlight "v8.0" ]) ] + [PortableProfileType.Profile2 + PortableProfileType.Profile3 + PortableProfileType.Profile4 + PortableProfileType.Profile5 + PortableProfileType.Profile6 + PortableProfileType.Profile7 + PortableProfileType.Profile14 + PortableProfileType.Profile18 + PortableProfileType.Profile19 + PortableProfileType.Profile23 + PortableProfileType.Profile24 + PortableProfileType.Profile31 + PortableProfileType.Profile32 + PortableProfileType.Profile36 + PortableProfileType.Profile37 + PortableProfileType.Profile41 + PortableProfileType.Profile42 + PortableProfileType.Profile44 + PortableProfileType.Profile46 + PortableProfileType.Profile47 + PortableProfileType.Profile49 + PortableProfileType.Profile78 + PortableProfileType.Profile84 + PortableProfileType.Profile88 + PortableProfileType.Profile92 + PortableProfileType.Profile95 + PortableProfileType.Profile96 + PortableProfileType.Profile102 + PortableProfileType.Profile104 + PortableProfileType.Profile111 + PortableProfileType.Profile136 + PortableProfileType.Profile143 + PortableProfileType.Profile147 + PortableProfileType.Profile151 + PortableProfileType.Profile154 + PortableProfileType.Profile157 + PortableProfileType.Profile158 + PortableProfileType.Profile225 + PortableProfileType.Profile240 + PortableProfileType.Profile255 + PortableProfileType.Profile259 + PortableProfileType.Profile328 + PortableProfileType.Profile336 + PortableProfileType.Profile344 ] let AllDotNetProfiles = DotNetFrameworkProfiles @ @@ -724,10 +888,10 @@ module KnownTargetProfiles = SinglePlatform(MonoTouch) SinglePlatform(XamariniOS) SinglePlatform(XamarinMac) - SinglePlatform(WindowsPhoneApp "v8.1")] @ + SinglePlatform(WindowsPhoneApp WindowsPhoneAppVersion.V8_1)] @ (AllPortableProfiles |> List.map PortableProfile) - let AllDotNetStandardProfiles = + let AllDotNetStandardAndCoreProfiles = DotNetStandardProfiles @ DotNetCoreProfiles // only used in "should understand aot in runtimes" test @@ -749,11 +913,293 @@ module KnownTargetProfiles = let AllProfiles = (AllNativeProfiles |> List.map SinglePlatform) @ - AllDotNetStandardProfiles @ + AllDotNetStandardAndCoreProfiles @ AllDotNetProfiles + |> Set.ofList - let FindPortableProfile name = + let TryFindPortableProfile (name:string) = + let lowerName = name.ToLowerInvariant() AllProfiles - |> List.pick (function - | PortableProfile(n, _) as p when n = name -> Some p - | _ -> None) + |> Set.toSeq + |> Seq.tryPick (function + | PortableProfile p when p.ProfileName.ToLowerInvariant() = lowerName -> Some (PortableProfile p) + | _ -> None) + let FindPortableProfile name = + match TryFindPortableProfile name with + | Some s -> s + | None -> failwithf "tried to find portable profile '%s' but it is unknown to paket" name + +module SupportCalculation = + let isSupportedNotEqual (portable:PortableProfileType) (other:PortableProfileType) = + let name, tfs = portable.ProfileName, portable.Frameworks + + let otherName, otherfws = other.ProfileName, other.Frameworks + let weSupport = + tfs + |> List.collect (fun tf -> tf.RawSupportedPlatformsTransitive) + + let relevantFrameworks = + otherfws + |> Seq.filter (fun fw -> + weSupport |> List.exists ((=) fw)) + |> Seq.length + relevantFrameworks >= tfs.Length && portable <> other + + let getSupported (portable:PortableProfileType) = + let name, tfs = portable.ProfileName, portable.Frameworks + KnownTargetProfiles.AllPortableProfiles + |> List.filter (fun p -> p.ProfileName <> name) + |> List.filter (fun other -> isSupportedNotEqual portable other) + |> List.map PortableProfile + type SupportMap = System.Collections.Concurrent.ConcurrentDictionary + let ofSeq s = s|> dict |> System.Collections.Concurrent.ConcurrentDictionary + let toSeq s = s|> Seq.map (fun (kv:System.Collections.Generic.KeyValuePair<_,_>) -> kv.Key, kv.Value) + let rec buildSupportMap (supportMap:SupportMap) p = + let directMap = supportMap.[p] + directMap + |> List.append (directMap |> List.collect (buildSupportMap supportMap)) + + let filterMap pos (supportMap:SupportMap) : SupportMap = + supportMap + |> toSeq + |> Seq.map (fun (profile, supported) -> + profile, + if supported.Length < pos + 1 then + supported + else + // try to optimize on the 'pos' position + let curPos = supported.[pos] + let supportList = buildSupportMap supportMap curPos // supportMap.[curPos] // + (supported |> List.take pos |> List.filter (fun s -> supportList |> List.contains s |> not)) + @ [curPos] @ + (supported + |> List.skip (pos + 1) + |> List.filter (fun s -> supportList |> List.contains s |> not)) + ) + |> ofSeq + + // Optimize support map, ie remove entries which are not needed + let optimizeSupportMap (supportMap:SupportMap) = + let mutable sup = supportMap + let mutable hasChanged = true + while hasChanged do + hasChanged <- false + let maxNum = sup.Values |> Seq.map (fun l -> l.Length) |> Seq.max + for i in 0 .. maxNum - 1 do + let old = sup + sup <- filterMap i sup + if old.Count <> sup.Count then + hasChanged <- true + sup + let private getSupportedPortables p = + getSupported p + |> List.choose (function PortableProfile p -> Some p | _ -> failwithf "Expected portable") + + let createInitialSupportMap () = + KnownTargetProfiles.AllPortableProfiles + |> List.map (fun p -> p, getSupportedPortables p) + |> ofSeq + + let mutable private supportMap = optimizeSupportMap (createInitialSupportMap()) + + let getSupportedPreCalculated (p:PortableProfileType) = + match supportMap.TryGetValue p with + | true, v -> v + | _ -> + match p with + | UnsupportedProfile tfs -> + match supportMap.TryGetValue p with + | true, v -> v + | _ -> + let clone = supportMap |> toSeq |> ofSeq + clone.[p] <- getSupportedPortables p + let opt = optimizeSupportMap clone + let result = opt.[p] + supportMap <- opt + result + | _ -> failwithf "Expected that default profiles are already created." + + let findPortable = + memoize (fun (fws: _ list) -> + if fws.Length = 0 then failwithf "can not find portable for an empty list (Details: Empty lists need to be handled earlier with a warning)!" + let fallback = PortableProfile (UnsupportedProfile (fws |> List.sort)) + let minimal = + fws + |> List.filter (function + | MonoTouch + | DNXCore _ + | UAP _ + | MonoAndroid -> false + | DotNetCore _ + | DotNetStandard _ -> failwithf "Unexpected famework while trying to resolve PCL Profile" + | _ -> true) + if minimal.Length > 0 then + let matches = + KnownTargetProfiles.AllPortableProfiles + |> List.filter (fun p -> + let otherFws = p.Frameworks + minimal |> List.forall(fun mfw -> otherFws |> Seq.contains mfw)) + |> List.sortBy (fun p -> p.Frameworks.Length) + |> Seq.toArray // Debug + let firstMatch = + KnownTargetProfiles.AllPortableProfiles + |> List.filter (fun p -> + let otherFws = p.Frameworks + minimal |> List.forall(fun mfw -> otherFws |> Seq.contains mfw)) + |> List.sortBy (fun p -> p.Frameworks.Length) + |> List.tryHead + match firstMatch with + | Some p -> PortableProfile p + | None -> + traceWarnfn "The profile '%O' is not a known profile. Please tell the package author." fallback + fallback + else + traceWarnfn "The profile '%O' is not a known profile. Please tell the package author." fallback + fallback) + + let getSupportedPlatforms x = + match x with + | SinglePlatform tf -> + let rawSupported = + tf.RawSupportedPlatforms + |> List.map SinglePlatform + let profilesSupported = + // See https://docs.microsoft.com/en-us/dotnet/articles/standard/library + match tf with + | DotNetStandard DotNetStandardVersion.V1_0 -> + [ Profile31 + Profile49 + Profile78 + Profile84 + Profile157 + Profile259 ] + | DotNetStandard DotNetStandardVersion.V1_1 -> + [ Profile7 + Profile111 ] + | DotNetStandard DotNetStandardVersion.V1_2 -> + [ Profile32 + Profile44 + Profile151 ] + | MonoTouch + | MonoAndroid + | XamariniOS + | XamarinMac -> + // http://danrigby.com/2014/05/14/supported-pcl-profiles-xamarin-for-visual-studio-2/ + [ Profile5 + Profile6 + Profile7 + Profile14 + Profile19 + Profile24 + Profile37 + Profile42 + Profile44 + Profile47 + Profile49 + Profile78 + Profile92 + Profile102 + Profile111 + Profile136 + Profile147 + Profile151 + Profile158 + Profile225 + Profile259 + Profile328 + Profile336 + Profile344 ] + | _ -> + // Regular supported logic is to enumerate all profiles and select compatible ones + let profiles = + KnownTargetProfiles.AllPortableProfiles + |> List.filter (fun (p) -> + // Portable profile is compatible as soon as if contains us + p.Frameworks + |> List.exists (fun fw -> fw = tf)) + profiles + |> List.map PortableProfile + rawSupported @ profilesSupported + | PortableProfile p -> + getSupportedPreCalculated p + |> List.map PortableProfile + |> Set.ofList + + let getSupportedPlatformsTransitive = + let findNewPlats (known:TargetProfile Set) (lastStep:TargetProfile Set) = + lastStep + |> Seq.map (fun k -> Set.difference (getSupportedPlatforms k) known) + |> Set.unionMany + + memoize (fun x -> + Seq.initInfinite (fun _ -> 1) + |> Seq.scan (fun state _ -> + match state with + | Some (known, lastStep) -> + match findNewPlats known lastStep with + | s when s.IsEmpty -> None + | items -> Some (Set.union known items, items) + | None -> None) (Some (Set.singleton x, Set.singleton x)) + |> Seq.takeWhile (fun i -> i.IsSome) + |> Seq.choose id + |> Seq.last + |> fst + ) + + /// true when x is supported by y, for example netstandard15 is supported by netcore10 + let isSupportedBy x y = + match x with + | PortableProfile (PortableProfileType.UnsupportedProfile xs' as x') -> + // custom profiles are not in our lists -> custom logic + match y with + | PortableProfile y' -> + x' = y' || + isSupportedNotEqual y' x' + | SinglePlatform y' -> + y'.RawSupportedPlatformsTransitive |> Seq.exists (fun y'' -> + xs' |> Seq.contains y'') + | _ -> + x = y || + (getSupportedPlatformsTransitive y |> Set.contains x) + + let getPlatformsSupporting = + // http://nugettoolsdev.azurewebsites.net + let calculate (x:TargetProfile) = + KnownTargetProfiles.AllProfiles + |> Set.filter (fun plat -> isSupportedBy x plat) + memoize calculate + +type TargetProfile with + member p.Frameworks = + match p with + | SinglePlatform fw -> [fw] + | PortableProfile p -> p.Frameworks + static member FindPortable (fws: _ list) = SupportCalculation.findPortable fws + + member inline x.PlatformsSupporting = SupportCalculation.getPlatformsSupporting x + + /// true when x is supported by y, for example netstandard15 is supported by netcore10 + member inline x.IsSupportedBy y = + SupportCalculation.isSupportedBy x y + /// true when x is at least (>=) y ie when y is supported by x, for example netcore10 >= netstandard15 as netstandard15 is supported by netcore10. + /// Note that this relation is not complete, for example for WindowsPhoneSilverlightv7.0 and Windowsv4.5 both <= and >= are false from this definition as + /// no platform supports the other. + member inline x.IsAtLeast (y:TargetProfile) = + y.IsSupportedBy x + + /// Get all platforms y for which x >= y holds + member inline x.SupportedPlatformsTransitive = + SupportCalculation.getSupportedPlatformsTransitive x + + member inline x.SupportedPlatforms : TargetProfile Set = + SupportCalculation.getSupportedPlatforms x + + /// x < y, see y >= x && x <> y + member inline x.IsSmallerThan y = + x.IsSupportedBy y && x <> y + + member inline x.IsSmallerThanOrEqual y = + x.IsSupportedBy y + + /// Note that this returns true only when a >= x and x < b holds. + member x.IsBetween(a,b) = x.IsAtLeast a && x.IsSmallerThan b \ No newline at end of file diff --git a/src/Paket.Core/Versioning/PlatformMatching.fs b/src/Paket.Core/Versioning/PlatformMatching.fs index bcad68c3f2..e48d04e626 100644 --- a/src/Paket.Core/Versioning/PlatformMatching.fs +++ b/src/Paket.Core/Versioning/PlatformMatching.fs @@ -2,6 +2,7 @@ open System open ProviderImplementation.AssemblyReader.Utils.SHA1 +open Logging [] let MaxPenalty = 1000000 @@ -9,65 +10,100 @@ let MaxPenalty = 1000000 type ParsedPlatformPath = { Name : string Platforms : FrameworkIdentifier list } - static member Empty = { Name = ""; Platforms = [] } + static member Empty = { Name = ""; Platforms = [] } + static member FromTargetProfile (p:TargetProfile) = + { Name = p.ToString(); Platforms = p.Frameworks } + member x.ToTargetProfile = + match x.Platforms with + | _ when System.String.IsNullOrEmpty x.Name -> None + | [] -> None // Not detected earlier. + | [p] -> Some (SinglePlatform p) + | plats -> Some (TargetProfile.FindPortable plats) + member pp.IsEmpty = String.IsNullOrEmpty pp.Name || pp.Platforms.IsEmpty let inline split (path : string) = path.Split('+') - |> Array.map (fun s -> System.Text.RegularExpressions.Regex.Replace(s, "portable\\d*-","")) + |> Array.map (fun s -> System.Text.RegularExpressions.Regex.Replace(s, @"portable[\d\.]*-","")) -let extractPlatforms = memoize (fun path -> { Name = path; Platforms = split path |> Array.choose FrameworkDetection.Extract |> Array.toList }) - -let knownInPortable = - KnownTargetProfiles.AllPortableProfiles - |> List.collect snd - |> List.distinct - -let tryGetProfile platforms = - let filtered = - platforms.Platforms - |> List.filter (fun p -> knownInPortable |> Seq.exists ((=) p)) - |> List.sort - - KnownTargetProfiles.AllPortableProfiles |> Seq.tryFind (snd >> (=) filtered) - |> Option.map PortableProfile - -let getPlatformPenalty = - let rec getPlatformPenalty alreadyChecked (targetPlatform:FrameworkIdentifier) (packagePlatform:FrameworkIdentifier) = +// TODO: This function does now quite a lot, there probably should be several functions. +let extractPlatforms = memoize (fun path -> + if System.String.IsNullOrEmpty path then Some ParsedPlatformPath.Empty + else + let splits = split path + let platforms = splits |> Array.choose FrameworkDetection.Extract |> Array.toList + if platforms.Length = 0 then + if splits.Length = 1 && splits.[0].ToLowerInvariant().StartsWith "profile" then + // might be something like portable4.6-profile151 + let found = + KnownTargetProfiles.FindPortableProfile splits.[0] + |> ParsedPlatformPath.FromTargetProfile + Some { found with Name = path } + else + traceWarnfn "Could not detect any platforms from '%s'" path + None + else Some { Name = path; Platforms = platforms }) + +let forceExtractPlatforms path = + match extractPlatforms path with + | Some s -> s + | None -> failwithf "Extracting platforms from path '%s' failed" path + +// TODO: In future work this stuff should be rewritten. This penalty stuff is more random than a proper implementation. +let rec getPlatformPenalty = + memoize (fun (targetPlatform:TargetProfile,packagePlatform:TargetProfile) -> if packagePlatform = targetPlatform then 0 else - let penalty = - targetPlatform.SupportedPlatforms - |> List.filter (fun x -> Set.contains x alreadyChecked |> not) - |> List.map (fun target -> getPlatformPenalty (Set.add target alreadyChecked) target packagePlatform) - |> List.append [MaxPenalty] - |> List.min - |> fun p -> p + 1 - match targetPlatform, packagePlatform with - | DotNetFramework _, DotNetStandard _ -> 200 + penalty - | DotNetStandard _, DotNetFramework _ -> 200 + penalty - | _ -> penalty + | PortableProfile _, SinglePlatform _ -> + // There is no point in searching for frameworks in portables... + MaxPenalty + | _, PortableProfile (PortableProfileType.UnsupportedProfile fws) -> + // We cannot find unsupported profiles in our "SupportedPlatforms" list + // Just check if we are compatible at all and return a high penalty + + if packagePlatform.IsSupportedBy targetPlatform then + 700 + else MaxPenalty + | _ -> + let penalty = + targetPlatform.SupportedPlatforms + |> Seq.map (fun target -> getPlatformPenalty (target, packagePlatform)) + |> Seq.append [MaxPenalty] + |> Seq.min + |> fun p -> p + 1 + + match targetPlatform, packagePlatform with + | SinglePlatform (DotNetFramework _), SinglePlatform (DotNetStandard _) -> 200 + penalty + | SinglePlatform (DotNetStandard _), SinglePlatform(DotNetFramework _) -> 200 + penalty + | SinglePlatform _, PortableProfile _ -> 500 + penalty + | PortableProfile _, SinglePlatform _ -> 500 + penalty + | _ -> penalty) + +let getFrameworkPenalty (fr1, fr2) = + getPlatformPenalty (SinglePlatform fr1, SinglePlatform fr2) - memoize (fun (targetPlatform:FrameworkIdentifier,packagePlatform:FrameworkIdentifier) -> getPlatformPenalty Set.empty targetPlatform packagePlatform) let getPathPenalty = memoize - (fun (path:ParsedPlatformPath,platform:FrameworkIdentifier) -> - if String.IsNullOrWhiteSpace path.Name then + (fun (path:ParsedPlatformPath,platform:TargetProfile) -> + let handleEmpty () = match platform with - | Native(_) -> MaxPenalty // an empty path is considered incompatible with native targets - | _ -> 500 // an empty path is considered compatible with every .NET target, but with a high penalty so explicit paths are preferred - else - path.Platforms - |> List.map (fun target -> getPlatformPenalty(platform,target)) - |> List.append [ MaxPenalty ] - |> List.min) - -// Checks wether a list of target platforms is supported by this path and with which penalty. -let getPenalty (requiredPlatforms:FrameworkIdentifier list) (path:ParsedPlatformPath) = - requiredPlatforms - |> List.sumBy (fun p -> getPathPenalty(path,p)) + | SinglePlatform(Native(_)) -> MaxPenalty // an empty path is considered incompatible with native targets + | _ -> 2000 // an empty path is considered compatible with every .NET target, but with a high penalty so explicit paths are preferred + match path.Platforms with + | _ when String.IsNullOrWhiteSpace path.Name -> handleEmpty() + | [] -> MaxPenalty // Ignore this path as it contains no platforms, but the folder apparently has a name -> we failed to detect the framework and ignore it + | [ h ] -> getPlatformPenalty(platform,SinglePlatform h) + | _ -> + getPlatformPenalty(platform, TargetProfile.FindPortable path.Platforms)) + +[] +let getFrameworkPathPenalty fr path = + match fr with + | [ h ] -> getPathPenalty (path, SinglePlatform h) + | _ -> + getPathPenalty (path, TargetProfile.FindPortable fr) type PathPenalty = (ParsedPlatformPath * int) @@ -95,67 +131,36 @@ let comparePaths (p1 : PathPenalty) (p2 : PathPenalty) = let collectPlatforms = - let rec loop (acc:FrameworkIdentifier list) (framework:FrameworkIdentifier) (profls:TargetProfile list) = - match profls with - | [] -> acc - | (SinglePlatform f)::tl -> - if f.SupportedPlatforms |> List.exists ((=) framework) - then loop (f::acc) framework tl - else loop acc framework tl - | _::tl -> loop acc framework tl - memoize (fun (framework,profls) -> loop ([]:FrameworkIdentifier list) framework profls) + let rec loop (acc:TargetProfile list) (framework:TargetProfile) (profls:TargetProfile Set) = + profls + |> Seq.fold (fun acc f -> + if f.SupportedPlatforms |> Set.contains (framework) then + Set.add f acc + else acc) Set.empty + memoize (fun (framework,profls) -> loop ([]:TargetProfile list) framework profls) + let platformsSupport = let rec platformsSupport platform platforms = - if List.isEmpty platforms then MaxPenalty - elif platforms |> List.exists ((=) platform) then 1 + if Set.isEmpty platforms then MaxPenalty + elif platforms |> Set.contains (platform) then 1 else - platforms |> Array.ofList - |> Array.Parallel.map (fun (p : FrameworkIdentifier) -> + platforms |> Set.toArray + |> Array.Parallel.map (fun (p : TargetProfile) -> collectPlatforms (p,KnownTargetProfiles.AllProfiles) - ) |> List.concat + ) |> Set.unionMany |> platformsSupport platform |> (+) 1 memoize (fun (platform,platforms) -> platformsSupport platform platforms) let findBestMatch = let rec findBestMatch (paths : ParsedPlatformPath list, targetProfile : TargetProfile) = - let requiredPlatforms = - match targetProfile with - | PortableProfile(_, platforms) -> platforms - | SinglePlatform(platform) -> [ platform ] - - let supported = - paths - |> List.map (fun path -> path, (getPenalty requiredPlatforms path)) - |> List.filter (fun (_, penalty) -> penalty < MaxPenalty) - |> List.sortWith comparePaths - |> List.map fst - |> List.tryHead - - let findBestPortableMatch findPenalty (portableProfile:TargetProfile) paths = - paths - |> Seq.tryFind (fun p -> tryGetProfile p = Some portableProfile) - |> Option.map (fun p -> p, findPenalty) - - match supported with - | None -> - // Fallback Portable Library - KnownTargetProfiles.AllProfiles - |> List.choose (fun p -> - match targetProfile with - | SinglePlatform x -> - match platformsSupport(x,p.ProfilesCompatibleWithPortableProfile) with - | pen when pen < MaxPenalty -> - findBestPortableMatch pen p paths - | _ -> - None - | _ -> None) - |> List.distinct - |> List.sortBy (fun (x, pen) -> pen, x.Platforms.Length) // prefer portable platform with less platforms - |> List.map fst - |> List.tryHead - | path -> path + paths + |> List.map (fun path -> path, (getPathPenalty (path, targetProfile))) + |> List.filter (fun (_, penalty) -> penalty < MaxPenalty) + |> List.sortWith comparePaths + |> List.map fst + |> List.tryHead memoize (fun (paths : ParsedPlatformPath list,targetProfile : TargetProfile) -> findBestMatch(paths,targetProfile)) @@ -165,93 +170,80 @@ let getSupportedTargetProfiles = memoize (fun (paths : ParsedPlatformPath list) -> KnownTargetProfiles.AllProfiles - |> List.choose (fun target -> + |> Seq.choose (fun target -> match findBestMatch(paths,target) with | Some p -> Some(p, target) | _ -> None) - |> List.groupBy fst - |> List.map (fun (path, group) -> path, List.map snd group) - |> Map.ofList) + |> Seq.groupBy fst + |> Seq.map (fun (path, group) -> path, Seq.map snd group |> Set.ofSeq) + |> Map.ofSeq) let getTargetCondition (target:TargetProfile) = match target with - | SinglePlatform(platform) -> + | SinglePlatform(platform) -> match platform with - | DotNetFramework(version) when version = FrameworkVersion.V4_Client -> - "$(TargetFrameworkIdentifier) == '.NETFramework'", sprintf "($(TargetFrameworkVersion) == '%O' And $(TargetFrameworkProfile) == 'Client')" version | DotNetFramework(version) ->"$(TargetFrameworkIdentifier) == '.NETFramework'", sprintf "$(TargetFrameworkVersion) == '%O'" version | DNX(version) ->"$(TargetFrameworkIdentifier) == 'DNX'", sprintf "$(TargetFrameworkVersion) == '%O'" version | DNXCore(version) ->"$(TargetFrameworkIdentifier) == 'DNXCore'", sprintf "$(TargetFrameworkVersion) == '%O'" version | DotNetStandard(version) ->"$(TargetFrameworkIdentifier) == '.NETStandard'", sprintf "$(TargetFrameworkVersion) == '%O'" version | DotNetCore(version) ->"$(TargetFrameworkIdentifier) == '.NETCoreApp'", sprintf "$(TargetFrameworkVersion) == '%O'" version - | DotNetUnity(version) when version = DotNetUnityVersion.V3_5_Full -> + | DotNetUnity(DotNetUnityVersion.V3_5_Full as version) -> "$(TargetFrameworkIdentifier) == '.NETFramework'", sprintf "($(TargetFrameworkVersion) == '%O' And $(TargetFrameworkProfile) == 'Unity Full v3.5')" version - | DotNetUnity(version) when version = DotNetUnityVersion.V3_5_Subset -> + | DotNetUnity(DotNetUnityVersion.V3_5_Subset as version) -> "$(TargetFrameworkIdentifier) == '.NETFramework'", sprintf "($(TargetFrameworkVersion) == '%O' And $(TargetFrameworkProfile) == 'Unity Subset v3.5')" version - | DotNetUnity(version) when version = DotNetUnityVersion.V3_5_Micro -> + | DotNetUnity(DotNetUnityVersion.V3_5_Micro as version) -> "$(TargetFrameworkIdentifier) == '.NETFramework'", sprintf "($(TargetFrameworkVersion) == '%O' And $(TargetFrameworkProfile) == 'Unity Micro v3.5')" version - | DotNetUnity(version) when version = DotNetUnityVersion.V3_5_Web -> + | DotNetUnity(DotNetUnityVersion.V3_5_Web as version) -> "$(TargetFrameworkIdentifier) == '.NETFramework'", sprintf "($(TargetFrameworkVersion) == '%O' And $(TargetFrameworkProfile) == 'Unity Web v3.5')" version - | Windows(version) -> "$(TargetFrameworkIdentifier) == '.NETCore'", sprintf "$(TargetFrameworkVersion) == '%O'" version + | Windows(version) -> "$(TargetFrameworkIdentifier) == '.NETCore'", sprintf "$(TargetFrameworkVersion) == '%O'" version.NetCoreVersion | Silverlight(version) -> "$(TargetFrameworkIdentifier) == 'Silverlight'", sprintf "$(TargetFrameworkVersion) == '%O'" version | WindowsPhoneApp(version) -> "$(TargetFrameworkIdentifier) == 'WindowsPhoneApp'", sprintf "$(TargetFrameworkVersion) == '%O'" version - | WindowsPhoneSilverlight(version) -> "$(TargetFrameworkIdentifier) == 'WindowsPhone'", sprintf "$(TargetFrameworkVersion) == '%O'" version + | WindowsPhone(version) -> "$(TargetFrameworkIdentifier) == 'WindowsPhone'", sprintf "$(TargetFrameworkVersion) == '%O'" version | MonoAndroid -> "$(TargetFrameworkIdentifier) == 'MonoAndroid'", "" | MonoTouch -> "$(TargetFrameworkIdentifier) == 'MonoTouch'", "" | MonoMac -> "$(TargetFrameworkIdentifier) == 'MonoMac'", "" | XamariniOS -> "$(TargetFrameworkIdentifier) == 'Xamarin.iOS'", "" - | UAP(version) ->"$(TargetPlatformIdentifier) == 'UAP'", sprintf "$(TargetPlatformVersion.StartsWith('%O'))" version + | UAP(version) -> "$(TargetFrameworkIdentifier) == '.NETCore'", sprintf "$(TargetFrameworkVersion) == '%O'" version.NetCoreVersion | XamarinMac -> "$(TargetFrameworkIdentifier) == 'Xamarin.Mac'", "" | Native(NoBuildMode,NoPlatform) -> "true", "" | Native(NoBuildMode,bits) -> (sprintf "'$(Platform)'=='%s'" bits.AsString), "" | Native(profile,bits) -> (sprintf "'$(Configuration)|$(Platform)'=='%s|%s'" profile.AsString bits.AsString), "" - | PortableProfile(name, _) -> sprintf "$(TargetFrameworkProfile) == '%O'" name,"" + | PortableProfile p -> sprintf "$(TargetFrameworkProfile) == '%O'" p.ProfileName,"" -let getCondition (referenceCondition:string option) (allTargets: TargetProfile list list) (targets : TargetProfile list) = - let inline CheckIfFullyInGroup typeName matchF (processed,targets) = +let getCondition (referenceCondition:string option) (allTargets: TargetProfile Set list) (targets : TargetProfile Set) = + let inline CheckIfFullyInGroup typeName matchF filterRestF (processed,targets) = let fullyContained = KnownTargetProfiles.AllDotNetProfiles |> List.filter matchF - |> List.forall (fun p -> targets |> Seq.exists ((=) p)) + |> List.forall (fun p -> targets |> Set.contains p) if fullyContained then - (sprintf "$(TargetFrameworkIdentifier) == '%s'" typeName,"") :: processed,targets |> List.filter (matchF >> not) + (sprintf "$(TargetFrameworkIdentifier) == '%s'" typeName,"") :: processed,targets |> Set.filter (filterRestF >> not) else processed,targets - + let inline CheckIfFullyInGroupS typeName matchF (processed,targets) = + CheckIfFullyInGroup typeName matchF matchF (processed,targets) let grouped,targets = ([],targets) - |> CheckIfFullyInGroup "true" (fun _ -> true) - |> CheckIfFullyInGroup ".NETFramework" (function SinglePlatform (DotNetFramework _) -> true | _ -> false) - |> CheckIfFullyInGroup ".NETCore" (function SinglePlatform (Windows _) -> true | _ -> false) - |> CheckIfFullyInGroup "Silverlight" (function SinglePlatform (Silverlight _) -> true | _ -> false) - |> CheckIfFullyInGroup "WindowsPhoneApp" (function SinglePlatform (WindowsPhoneApp _) -> true | _ -> false) - |> CheckIfFullyInGroup "WindowsPhone" (function SinglePlatform (WindowsPhoneSilverlight _) -> true | _ -> false) - - let targets = - targets - |> List.map (fun target -> - match target with - | SinglePlatform(DotNetFramework(FrameworkVersion.V4_Client)) -> - if allTargets |> List.exists (List.contains (SinglePlatform(DotNetFramework(FrameworkVersion.V4)))) |> not then - SinglePlatform(DotNetFramework(FrameworkVersion.V4)) - else - target - | _ -> target) + |> CheckIfFullyInGroupS "true" (fun _ -> true) + |> CheckIfFullyInGroupS ".NETFramework" (function SinglePlatform (DotNetFramework _) -> true | _ -> false) + |> CheckIfFullyInGroup ".NETCore" (function SinglePlatform (Windows _) -> true | _ -> false) (function SinglePlatform (Windows _) -> true | SinglePlatform (UAP _) -> true | _ -> false) + |> CheckIfFullyInGroupS "Silverlight" (function SinglePlatform (Silverlight _) -> true | _ -> false) + |> CheckIfFullyInGroupS "WindowsPhoneApp" (function SinglePlatform (WindowsPhoneApp _) -> true | _ -> false) + |> CheckIfFullyInGroupS "WindowsPhone" (function SinglePlatform (WindowsPhone _) -> true | _ -> false) let conditions = - if targets = [ SinglePlatform(Native(NoBuildMode,NoPlatform)) ] then + if targets.Count = 1 && targets |> Set.minElement = SinglePlatform(Native(NoBuildMode,NoPlatform)) then targets else targets - |> List.filter (function + |> Set.filter (function | SinglePlatform(Native(NoBuildMode,NoPlatform)) -> false - | SinglePlatform(DotNetFramework(FrameworkVersion.V4_Client)) -> - targets |> List.contains (SinglePlatform(DotNetFramework(FrameworkVersion.V4))) |> not | _ -> true) - |> List.map getTargetCondition - |> List.filter (fun (_, v) -> v <> "false") + |> Seq.map getTargetCondition + |> Seq.filter (fun (_, v) -> v <> "false") + |> Seq.toList |> List.append grouped |> List.groupBy fst @@ -264,6 +256,8 @@ let getCondition (referenceCondition:string option) (allTargets: TargetProfile l | [] -> "false" | [ detail ] -> sprintf "%s And %s" group detail | conditions -> + if conditions |> Seq.exists (String.IsNullOrEmpty) then + failwithf "Something went wrong (Details: probably in CheckIfFullyInGroup). Please open an issue." let detail = conditions |> fun cs -> String.Join(" Or ",cs) diff --git a/src/Paket.Core/Versioning/Requirements.fs b/src/Paket.Core/Versioning/Requirements.fs index ee0177c8ac..72ad539767 100644 --- a/src/Paket.Core/Versioning/Requirements.fs +++ b/src/Paket.Core/Versioning/Requirements.fs @@ -7,42 +7,510 @@ open Paket.PackageSources open Paket.Logging [] -type FrameworkRestriction = -| Exactly of FrameworkIdentifier -| Portable of string -| AtLeast of FrameworkIdentifier -| Between of FrameworkIdentifier * FrameworkIdentifier - +// To make reasoning and writing tests easier. +// Ideally we would "simplify" the trees to a "normal" form internally +[] +[] +type FrameworkRestrictionP = + private + | ExactlyP of TargetProfile + | AtLeastP of TargetProfile + // Means: Take all frameworks NOT given by the restriction + | NotP of FrameworkRestrictionP + | OrP of FrameworkRestrictionP list + | AndP of FrameworkRestrictionP list + member x.InfixNotation = + match x with + | FrameworkRestrictionP.ExactlyP r -> "== " + r.ToString() + | FrameworkRestrictionP.AtLeastP r -> ">= " + r.ToString() + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.AtLeastP r) -> sprintf "< " + r.ToString() + | FrameworkRestrictionP.NotP(fr) -> sprintf "NOT (%O)" fr + | FrameworkRestrictionP.OrP(frl) -> + match frl with + | [] -> "false" + | [single] -> sprintf "%O" single + | _ -> sprintf "(%s)" (System.String.Join(" || ", frl |> Seq.map (fun inner -> sprintf "(%s)" inner.InfixNotation))) + | FrameworkRestrictionP.AndP(frl) -> + match frl with + | [] -> "true" + | [single] -> sprintf "%O" single + | _ -> sprintf "(%s)" (System.String.Join(" && ", frl |> Seq.map (fun inner -> sprintf "(%s)" inner.InfixNotation))) override this.ToString() = match this with - | FrameworkRestriction.Exactly r -> r.ToString() - | FrameworkRestriction.Portable r -> r - | FrameworkRestriction.AtLeast r -> ">= " + r.ToString() - | FrameworkRestriction.Between(min,max) -> sprintf ">= %O < %O" min max + | FrameworkRestrictionP.ExactlyP r -> "== " + r.ToString() + | FrameworkRestrictionP.AtLeastP r -> ">= " + r.ToString() + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.AtLeastP r) -> sprintf "< " + r.ToString() + | FrameworkRestrictionP.NotP(fr) -> sprintf "NOT (%O)" fr + | FrameworkRestrictionP.OrP(frl) -> + match frl with + | [] -> "false" + | [single] -> sprintf "%O" single + | _ -> sprintf "|| %s" (System.String.Join(" ", frl |> Seq.map (sprintf "(%O)"))) + | FrameworkRestrictionP.AndP(frl) -> + match frl with + | [] -> "true" + | [single] -> sprintf "%O" single + | _ -> sprintf "&& %s" (System.String.Join(" ", frl |> Seq.map (sprintf "(%O)"))) + + /// The list represented by this restriction (ie the included set of frameworks) + // NOTE: All critical paths test only if this set is empty, so we use lazy seq here + member x.RepresentedFrameworks = + match x with + | FrameworkRestrictionP.ExactlyP r -> [ r ] |> Set.ofList + | FrameworkRestrictionP.AtLeastP r -> r.PlatformsSupporting + //PlatformMatching.get r + //KnownTargetProfiles.AllProfiles + //|> Set.filter (fun plat -> r.IsSupportedBy plat) + | FrameworkRestrictionP.NotP(fr) -> + let notTaken = fr.RepresentedFrameworks + Set.difference KnownTargetProfiles.AllProfiles notTaken + | FrameworkRestrictionP.OrP (frl) -> + frl + |> Seq.map (fun fr -> fr.RepresentedFrameworks) + |> Set.unionMany + | FrameworkRestrictionP.AndP (frl) -> + match frl with + | h :: _ -> + frl + |> Seq.map (fun fr -> fr.RepresentedFrameworks) + |> Set.intersectMany + | [] -> + KnownTargetProfiles.AllProfiles + + member x.IsMatch (tp:TargetProfile) = + match x with + | FrameworkRestrictionP.ExactlyP r -> r = tp + | FrameworkRestrictionP.AtLeastP r -> + tp.SupportedPlatformsTransitive |> Seq.contains r + | FrameworkRestrictionP.NotP(fr) -> + fr.IsMatch tp |> not + | FrameworkRestrictionP.OrP (frl) -> + frl + |> List.exists (fun fr -> fr.IsMatch tp) + | FrameworkRestrictionP.AndP (frl) -> + frl + |> List.forall (fun fr -> fr.IsMatch tp) + + /// Returns true if the restriction x is a subset of the restriction y (a restriction basically represents a list, see RepresentedFrameworks) + /// For example =net46 is a subset of >=netstandard13 + member x.IsSubsetOf (y:FrameworkRestrictionP) = + + // better ~ 5 Mins, but below recursive logic should be even better. + let inline fallBack doAssert = +#if DEBUG + if doAssert then + assert (false)// make sure the fallback is never needed +#endif + let superset = y.RepresentedFrameworks + let subset = x.RepresentedFrameworks + Set.isSubset subset superset + + // Because the formula simplifier needs it this is a quite HOT PATH + match x with + | FrameworkRestrictionP.ExactlyP x' -> + match y with + | FrameworkRestrictionP.ExactlyP y' -> x' = y' + | FrameworkRestrictionP.AtLeastP y' -> + // =x' is a subset of >=y' when 'y is smaller than 'x + y'.IsSmallerThanOrEqual x' + // these are or 'common' forms, others are not allowed + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.AtLeastP y') -> + // =x is only a subset of = y + y'.IsSmallerThanOrEqual x' + |> not + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.ExactlyP y') -> + x' <> y' + // This one should never actually hit. + | FrameworkRestrictionP.NotP(y') -> fallBack true + | FrameworkRestrictionP.OrP (ys) -> + ys + |> Seq.exists (fun y' -> x.IsSubsetOf y') + | FrameworkRestrictionP.AndP (ys) -> + ys + |> Seq.forall (fun y' -> x.IsSubsetOf y') + | FrameworkRestrictionP.AtLeastP x' -> + match y with + | FrameworkRestrictionP.ExactlyP y' -> + // >=x can only be a subset of =y when it is already the max + x' = y' && x'.SupportedPlatforms.IsEmpty + | FrameworkRestrictionP.AtLeastP y' -> + // >=x is only a subset of >=y when y is 'smaller" than x + y'.IsSmallerThanOrEqual x' + // these are or 'common' forms, others are not allowed + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.AtLeastP y') -> + // >= x' is only a subset of < y' when their intersection is empty + Set.intersect (x'.PlatformsSupporting) (y'.PlatformsSupporting) + |> Set.isEmpty + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.ExactlyP y') -> + // >= x' is only a subset of <> y' when y' is not part of >=x' + x'.PlatformsSupporting + |> Set.contains y' + |> not + // This one should never actually hit. + | FrameworkRestrictionP.NotP(y') -> fallBack true + | FrameworkRestrictionP.OrP (ys) -> + ys + |> Seq.exists (fun y' -> x.IsSubsetOf y') + | FrameworkRestrictionP.AndP (ys) -> + ys + |> Seq.forall (fun y' -> x.IsSubsetOf y') + + // these are or 'common' forms, others are not allowed + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.AtLeastP x' as notX) -> + match y with + | FrameworkRestrictionP.ExactlyP y' -> + // < x is a subset of ='y when? +#if DEBUG + assert (not (fallBack false))// TODO: can this happen? +#endif + false + | FrameworkRestrictionP.AtLeastP y' -> + // < x is a subset of >= y when there are no smaller things than y and +#if DEBUG + assert (not (fallBack false))// TODO: can this happen? +#endif + false + // these are or 'common' forms, others are not allowed + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.AtLeastP y' as notY) -> + // < 'x is a subset of < y when >=y is a subset of >=x + notY.IsSubsetOf notX + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.ExactlyP y' as notY) -> + // < 'x is a subset of <> y when =y is a subset of >=x + notY.IsSubsetOf notX + // This one should never actually hit. + | FrameworkRestrictionP.NotP(y') -> fallBack true + | FrameworkRestrictionP.OrP (ys) -> + ys + |> Seq.exists (fun y' -> x.IsSubsetOf y') + | FrameworkRestrictionP.AndP (ys) -> + ys + |> Seq.forall (fun y' -> x.IsSubsetOf y') + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.ExactlyP x' as notX) -> + match y with + | FrameworkRestrictionP.ExactlyP y' -> + // <> x is a subset of =y ? +#if DEBUG + assert (not (fallBack false))// TODO: can this happen? +#endif + false + | FrameworkRestrictionP.AtLeastP y' -> + // <> x is a subset of >= y +#if DEBUG + assert (not (fallBack false))// TODO: can this happen? +#endif + false + //fallBack() + // these are or 'common' forms, others are not allowed + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.AtLeastP y' as notY) -> + notY.IsSubsetOf notX + | FrameworkRestrictionP.NotP(FrameworkRestrictionP.ExactlyP y' as notY) -> + notY.IsSubsetOf notX + // This one should never actually hit. + | FrameworkRestrictionP.NotP(y') -> fallBack true + | FrameworkRestrictionP.OrP (ys) -> + ys + |> Seq.exists (fun y' -> x.IsSubsetOf y') + | FrameworkRestrictionP.AndP (ys) -> + ys + |> Seq.forall (fun y' -> x.IsSubsetOf y') + // This one should never actually hit. + | FrameworkRestrictionP.NotP(x') -> fallBack true + | FrameworkRestrictionP.OrP (xs) -> + xs + |> Seq.forall (fun x' -> x'.IsSubsetOf y) + | FrameworkRestrictionP.AndP (xs) -> + xs + |> Seq.exists (fun x' -> x'.IsSubsetOf y) + + + // Bad ~ 10 mins + //|> Seq.forall (fun inner -> superset |> Seq.contains inner) + static member ExactlyFramework (tf: FrameworkIdentifier) = + ExactlyP (SinglePlatform tf) + + override x.Equals(y) = (match y with :? FrameworkRestrictionP as r -> r.RepresentedFrameworks = x.RepresentedFrameworks | _ -> false) + override x.GetHashCode() = x.RepresentedFrameworks.GetHashCode() + interface System.IComparable with + member x.CompareTo(y) = (match y with :? FrameworkRestrictionP as r -> compare x.RepresentedFrameworks r.RepresentedFrameworks | _ -> failwith "wrong type") - member x.GetOneIdentifier = +type FrameworkRestrictionLiteralI = + | ExactlyL of TargetProfile + | AtLeastL of TargetProfile + member internal x.RawFormular = 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 = -| FrameworkRestrictionList of FrameworkRestriction list + | ExactlyL id -> FrameworkRestrictionP.ExactlyP id + | AtLeastL id -> FrameworkRestrictionP.AtLeastP id +type FrameworkRestrictionLiteral = + { LiteraL : FrameworkRestrictionLiteralI; IsNegated : bool } + member internal x.RawFormular = + let raw = x.LiteraL.RawFormular + if x.IsNegated then FrameworkRestrictionP.NotP raw else raw + static member FromLiteral l = + { LiteraL = l ; IsNegated = false } + static member FromNegatedLiteral l = + { LiteraL = l ; IsNegated = true } +type FrameworkRestrictionAndList = + { Literals : FrameworkRestrictionLiteral list } + member internal x.RawFormular = + FrameworkRestrictionP.AndP (x.Literals |> List.map (fun literal -> literal.RawFormular)) + +[] +type FrameworkRestriction = + private { OrFormulas : FrameworkRestrictionAndList list + mutable PrivateRawFormula : FrameworkRestrictionP option ref + mutable PrivateRepresentedFrameworks : TargetProfile Set option ref } + static member FromOrList l = { OrFormulas = l; PrivateRepresentedFrameworks = ref None; PrivateRawFormula = ref None } + static member internal WithOrListInternal orList l = { l with OrFormulas = orList } + member internal x.RawFormular = + match !x.PrivateRawFormula with + | Some f -> f + | None -> + let raw = FrameworkRestrictionP.OrP (x.OrFormulas |> List.map (fun andList -> andList.RawFormular)) + x.PrivateRawFormula := Some raw + raw + override x.ToString() = + x.RawFormular.ToString() + member x.IsSubsetOf (y:FrameworkRestriction) = + x.RawFormular.IsSubsetOf y.RawFormular + member x.RepresentedFrameworks = + match !x.PrivateRepresentedFrameworks with + | Some s -> s + | None -> + let set = x.RawFormular.RepresentedFrameworks + x.PrivateRepresentedFrameworks := Some set + set + member x.IsMatch tp = + x.RawFormular.IsMatch tp + override x.Equals(y) = (match y with :? FrameworkRestriction as r -> r.RepresentedFrameworks = x.RepresentedFrameworks | _ -> false) + override x.GetHashCode() = x.RepresentedFrameworks.GetHashCode() + interface System.IComparable with + member x.CompareTo(y) = (match y with :? FrameworkRestriction as r -> compare x.RepresentedFrameworks r.RepresentedFrameworks | _ -> failwith "wrong type") + +module FrameworkRestriction = + let EmptySet = FrameworkRestriction.FromOrList [] // false + let NoRestriction = FrameworkRestriction.FromOrList [ { Literals = [] } ] // true + let FromLiteral lit = FrameworkRestriction.FromOrList [ { Literals = [ lit ] } ] + let AtLeastPlatform pf = FromLiteral (FrameworkRestrictionLiteral.FromLiteral (AtLeastL pf)) + let ExactlyPlatform pf = FromLiteral (FrameworkRestrictionLiteral.FromLiteral (ExactlyL pf)) + let Exactly id = ExactlyPlatform (SinglePlatform id) + let AtLeastPortable (name, fws)= AtLeastPlatform (TargetProfile.FindPortable fws) + let AtLeast id = AtLeastPlatform (SinglePlatform id) + let NotAtLeastPlatform pf = FromLiteral (FrameworkRestrictionLiteral.FromNegatedLiteral (AtLeastL pf)) + let NotAtLeast id = NotAtLeastPlatform (SinglePlatform id) + + let private simplify (fr:FrameworkRestriction) = + /// When we have a restriction like (>=net35 && =net45 + /// then we can "optimize" / simplify to (>=net35 || >= net45) + /// because we don't need to "pseudo" restrict the set with the first restriction + /// when we add back later all the things we removed. + /// Generally: We can remove all negated literals in all clauses when a positive literal exists as a standalone Or clause + let rec removeNegatedLiteralsWhichOccurSinglePositive (fr:FrameworkRestriction) = + let positiveSingles = + fr.OrFormulas + |> List.choose (fun andFormular -> match andFormular.Literals with [ { IsNegated = false } as h ] -> Some h | _ -> None) + let workDone, reworked = + fr.OrFormulas + |> List.fold (fun (workDone, reworkedOrFormulas) andFormula -> + let reworkedAnd = + andFormula.Literals + |> List.filter (fun literal -> + positiveSingles + |> List.exists (fun p -> literal.IsNegated && literal.LiteraL = p.LiteraL) + |> not + ) + if reworkedAnd.Length < andFormula.Literals.Length then + true, { Literals = reworkedAnd } :: reworkedOrFormulas + else + workDone, andFormula :: reworkedOrFormulas + ) (false, []) + if workDone then removeNegatedLiteralsWhichOccurSinglePositive (FrameworkRestriction.WithOrListInternal reworked fr) + else fr + /// (>= net40-full) && (< net46) && (>= net20) can be simplified to (< net46) && (>= net40-full) because (>= net40-full) is a subset of (>= net20) + // NOTE: This optimization is kind of dangerous as future frameworks might make it invalid + // However a lot of tests expect this simplification... We maybe want to remove it (or at least test) after we know the new framework restriction works. + let removeSubsetLiteralsInAndClause (fr:FrameworkRestriction) = + let simplifyAndClause (andClause:FrameworkRestrictionAndList) = + let literals = andClause.Literals + let newLiterals = + andClause.Literals + |> List.filter (fun literal -> + // we filter out literals, for which another literal exists which is a subset + literals + |> Seq.filter (fun l -> l <> literal) + |> Seq.exists (fun otherLiteral -> + otherLiteral.RawFormular.IsSubsetOf literal.RawFormular) + |> not) + if newLiterals.Length <> literals.Length + then true, {Literals = newLiterals} + else false, andClause + //andClause + let wasChanged, newOrList = + fr.OrFormulas + |> List.fold (fun (oldWasChanged, newList) andList -> + let wasChanged, newAndList = simplifyAndClause andList + oldWasChanged || wasChanged, newAndList :: newList) (false, []) + if wasChanged then + FrameworkRestriction.WithOrListInternal newOrList fr + else fr + + /// (>= net40-full) || (< net46) || (>= net20) can be simplified to (< net46) || (>= net20) because (>= net40-full) is a subset of (>= net20) + // NOTE: This optimization is kind of dangerous as future frameworks might make it invalid + // However a lot of tests expect this simplification... We maybe want to remove it (or at least test) after we know the new framework restriction works. + let removeSubsetLiteralsInOrClause (fr:FrameworkRestriction) = + let simpleOrLiterals = + fr.OrFormulas + |> List.choose (function { Literals = [h] } -> Some h | _ -> None) + let newOrList = + fr.OrFormulas + |> List.filter (function + | { Literals = [h] } -> + simpleOrLiterals + |> Seq.filter (fun l -> l <> h) + |> Seq.exists (fun otherLiteral -> + h.RawFormular.IsSubsetOf otherLiteral.RawFormular) + |> not + | _ -> true) + if newOrList.Length < fr.OrFormulas.Length then + FrameworkRestriction.WithOrListInternal newOrList fr + else fr + + /// ((>= net20) && (>= net40)) || (>= net20) can be simplified to (>= net20) because any AND clause with (>= net20) can be removed. + let removeUneccessaryOrClauses (fr:FrameworkRestriction) = + let orClauses = + fr.OrFormulas + let isContained (andList:FrameworkRestrictionAndList) (item:FrameworkRestrictionAndList) = + if item.Literals.Length >= andList.Literals.Length then false + else + item.Literals + |> Seq.forall (fun lit -> andList.Literals |> Seq.contains lit) + + let newOrList = + fr.OrFormulas + |> List.filter (fun orClause -> + orClauses |> Seq.exists (isContained orClause) |> not) + + if newOrList.Length < fr.OrFormulas.Length then + FrameworkRestriction.WithOrListInternal newOrList fr + else fr + + /// clauses with ((>= net20) && (< net20) && ...) can be removed because they contains a literal and its negation. + let removeUneccessaryAndClauses (fr:FrameworkRestriction) = + let newOrList = + fr.OrFormulas + |> List.filter (fun andList -> + let normalizeLiterals = + andList.Literals + |> List.map (function + | { LiteraL = FrameworkRestrictionLiteralI.ExactlyL l; IsNegated = n } -> + { LiteraL = FrameworkRestrictionLiteralI.AtLeastL l; IsNegated = n } + | lit -> lit) + let foundLiteralAndNegation = + normalizeLiterals + |> Seq.exists (fun l -> + normalizeLiterals |> Seq.contains { l with IsNegated = not l.IsNegated}) + not foundLiteralAndNegation) + + if newOrList.Length < fr.OrFormulas.Length then + FrameworkRestriction.WithOrListInternal newOrList fr + else fr + + + /// When we optmized a clause away completely we can replace the hole formula with "NoRestriction" + /// This happens for example with ( =net45) and the removeNegatedLiteralsWhichOccurSinglePositive + /// optimization + let replaceWithNoRestrictionIfAnyLiteralListIsEmpty (fr:FrameworkRestriction) = + let containsEmptyAnd = + fr.OrFormulas + |> Seq.exists (fun andFormular -> andFormular.Literals |> Seq.isEmpty) + if containsEmptyAnd then NoRestriction else fr + + let sortClauses (fr:FrameworkRestriction) = + fr.OrFormulas + |> List.map (fun andFormula -> { Literals = andFormula.Literals |> List.distinct |> List.sort }) + |> List.distinct + |> List.sort + |> fun newOrList -> FrameworkRestriction.WithOrListInternal newOrList fr + let optimize fr = + fr + |> removeNegatedLiteralsWhichOccurSinglePositive + |> removeSubsetLiteralsInAndClause + |> removeSubsetLiteralsInOrClause + |> removeUneccessaryAndClauses + |> removeUneccessaryOrClauses + |> replaceWithNoRestrictionIfAnyLiteralListIsEmpty + |> sortClauses + let mutable hasChanged = true + let mutable newFormula = fr + while hasChanged do + let old = newFormula + newFormula <- optimize newFormula + if old = newFormula then hasChanged <- false + newFormula + + + let rec private And2 (left : FrameworkRestriction) (right : FrameworkRestriction) = + match left.OrFormulas with + | [] -> right + | [h] -> + right.OrFormulas + |> List.map (fun andFormula -> { Literals = andFormula.Literals @ h.Literals } ) + |> FrameworkRestriction.FromOrList + | h :: t -> + (And2 (FrameworkRestriction.FromOrList [h]) right).OrFormulas @ (And2 (FrameworkRestriction.FromOrList t) right).OrFormulas + |> FrameworkRestriction.FromOrList + + let And (rst:FrameworkRestriction list) = + List.fold And2 NoRestriction rst + |> simplify + + let private Or2 (left : FrameworkRestriction) (right : FrameworkRestriction) = + left.OrFormulas @ right.OrFormulas + |> FrameworkRestriction.FromOrList + + let Or (rst:FrameworkRestriction list) = + List.fold Or2 EmptySet rst + |> simplify + + //[] + //let Not (rst:FrameworkRestriction) = + // Unchecked.defaultof<_> + + let Between (x, y) = + And2 (AtLeast x) (NotAtLeast y) + |> simplify + + let combineRestrictionsWithOr (x : FrameworkRestriction) y = + Or2 x y + |> simplify + + let (|HasNoRestriction|_|) x = + if x = NoRestriction then Some () else None + + let combineRestrictionsWithAnd (x : FrameworkRestriction) y = + And2 x y + |> simplify + +type FrameworkRestrictions = +| ExplicitRestriction of FrameworkRestriction | AutoDetectFramework + override x.ToString() = + match x with + | ExplicitRestriction r -> r.ToString() + | AutoDetectFramework -> "AutoDetect" + member x.GetExplicitRestriction () = + match x with + | ExplicitRestriction list -> list + | AutoDetectFramework -> failwith "The framework restriction could not be determined." -let getRestrictionList (frameworkRestrictions:FrameworkRestrictions) = - match frameworkRestrictions with - | FrameworkRestrictionList list -> list - | AutoDetectFramework -> failwith "The framework restriction could not be determined." + member x.IsSupersetOf (fw:FrameworkRestriction) = + fw.IsSubsetOf(x.GetExplicitRestriction ()) -let parseRestrictions failImmediatly (text:string) = +let getExplicitRestriction (frameworkRestrictions:FrameworkRestrictions) = + frameworkRestrictions.GetExplicitRestriction() + + +let parseRestrictionsLegacy failImmediatly (text:string) = + // older lockfiles to the new "restriction" semantics let handleError = if failImmediatly then failwith @@ -55,6 +523,8 @@ let parseRestrictions failImmediatly (text:string) = let text = // workaround missing spaces text.Replace("<=","<= ").Replace(">=",">= ").Replace("=","= ") + if text.StartsWith("||") || text.StartsWith("&&") then + raise <| InvalidOperationException("&& and || are not allowed in a legacy 'framework' section.") let commaSplit = text.Trim().Split(',') [for p in commaSplit do @@ -67,11 +537,12 @@ let parseRestrictions failImmediatly (text:string) = match FrameworkDetection.Extract(framework) with - | None -> - if (PlatformMatching.extractPlatforms framework).Platforms |> List.isEmpty |> not then - yield FrameworkRestriction.Portable framework - else - handleError <| sprintf "Could not parse framework '%s'. Try to update or install again or report a paket bug." framework + | None -> + match PlatformMatching.extractPlatforms framework |> Option.bind (fun pp -> pp.ToTargetProfile) with + | Some profile -> + yield FrameworkRestriction.AtLeastPlatform profile + | None -> + handleError <| sprintf "Could not parse framework '%s'. Try to update or install again or report a paket bug." framework | Some x -> if operatorSplit.[0] = ">=" then if operatorSplit.Length < 4 then @@ -81,463 +552,107 @@ let parseRestrictions failImmediatly (text:string) = match FrameworkDetection.Extract(item) with | None -> handleError <| sprintf "Could not parse second framework of between operator '%s'. Try to update or install again or report a paket bug." item - | Some y -> yield FrameworkRestriction.Between(x,y) + | Some y -> yield FrameworkRestriction.Between(x, y) else yield FrameworkRestriction.Exactly x] + |> List.fold (fun state item -> FrameworkRestriction.combineRestrictionsWithOr state item) FrameworkRestriction.EmptySet + +let parseRestrictions failImmediatly (text:string) = + let handleError = + if failImmediatly then + failwith + else + if verbose then + (fun s -> + traceError s + traceVerbose Environment.StackTrace) + else traceError -let private minRestriction = FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V1)) -let private minStandardRestriction = FrameworkRestriction.Exactly(DotNetStandard(DotNetStandardVersion.V1_0)) - -let findMaxDotNetRestriction restrictions = - minRestriction :: restrictions - |> List.filter (fun (r:FrameworkRestriction) -> - match r with - | FrameworkRestriction.Exactly(DotNetFramework _) -> true - | _ -> false) - |> List.max - |> fun r -> - match r with - | FrameworkRestriction.Exactly r -> r - | _ -> failwith "error" - -let findMaxStandardRestriction restrictions = - minStandardRestriction :: restrictions - |> List.filter (fun (r:FrameworkRestriction) -> - match r with - | FrameworkRestriction.Exactly(DotNetStandard _) -> true - | _ -> false) - |> List.max - |> fun r -> - match r with - | FrameworkRestriction.Exactly r -> r - | _ -> failwith "error" - -let rec optimizeRestrictions restrictions = - let sorting xs = - xs - |> List.sortBy (fun x -> - match x with - | FrameworkRestriction.Exactly r -> r - | FrameworkRestriction.Portable r -> FrameworkIdentifier.MonoMac - | FrameworkRestriction.AtLeast r -> r - | FrameworkRestriction.Between(min,max) -> min - |> fun y -> y,x) + let rec parseOperator (text:string) = + match text.Trim() with + | t when String.IsNullOrEmpty t -> failwithf "trying to parse an otherator but got no content" + | h when h.StartsWith ">=" || h.StartsWith "==" || h.StartsWith "<" -> + // parse >= + let smallerThan = h.StartsWith "<" + let isEquals = h.StartsWith "==" + let rest = h.Substring 2 + let splitted = rest.Split([|' '|], StringSplitOptions.RemoveEmptyEntries) + if splitted.Length < 1 then failwithf "No parameter after >= or < in '%s'" text + let rawOperator = splitted.[0] + let operator = rawOperator.TrimEnd([|')'|]) + match PlatformMatching.extractPlatforms operator |> Option.bind (fun pp -> pp.ToTargetProfile) with + | None -> failwithf "invalid parameter '%s' after >= or < in '%s'" operator text + | Some plat -> + let f = + if smallerThan then FrameworkRestriction.NotAtLeastPlatform + elif isEquals then FrameworkRestriction.ExactlyPlatform + else FrameworkRestriction.AtLeastPlatform + let operatorIndex = text.IndexOf operator + f plat, text.Substring(operatorIndex + operator.Length) + | h when h.StartsWith "&&" || h.StartsWith "||" -> + let isAnd = h.StartsWith "&&" + let next = h.Substring 2 + let rec parseOperand cur (next:string) = + let trimmed = next.TrimStart() + if trimmed.StartsWith "(" then + let operand, remaining = parseOperator (trimmed.Substring 1) + let remaining = remaining.TrimStart() + if remaining.StartsWith ")" |> not then failwithf "expected ')' after operand, '%s'" text + parseOperand (operand::cur) (remaining.Substring 1) + else + cur, next - match sorting restrictions |> List.distinct with - | [] -> [] - | [x] -> [x] - | odered -> - let newRestrictions = - match odered |> Seq.tryFind (function | FrameworkRestriction.AtLeast r -> true | _ -> false) with - | Some((FrameworkRestriction.AtLeast(DotNetFramework(v)) as r)) -> - odered - |> List.filter (fun r' -> - match r' with - | FrameworkRestriction.Exactly(DotNetFramework(x)) when x > v -> false - | FrameworkRestriction.AtLeast(DotNetFramework(x)) when x > v -> false - | _ -> true) - | Some((FrameworkRestriction.AtLeast(DotNetStandard(v)) as r)) -> - odered - |> List.filter (fun r' -> - match r' with - | FrameworkRestriction.Exactly(DotNetStandard(x)) when x > v -> false - | FrameworkRestriction.AtLeast(DotNetStandard(x)) when x > v -> false - | _ -> true) - | _ -> odered - - let filtered = - match newRestrictions |> Seq.rev |> Seq.tryFind (function | FrameworkRestriction.AtLeast(DotNetFramework r) -> true | FrameworkRestriction.AtLeast(DotNetStandard r) -> true | _ -> false) with - | None -> newRestrictions - | Some r -> - let currentVersion = - match r with - | FrameworkRestriction.AtLeast(DotNetFramework(x)) -> DotNetFramework x - | FrameworkRestriction.AtLeast(DotNetStandard(x)) -> DotNetStandard x - | x -> failwithf "Unknown .NET moniker %O" x - - let isLowerVersion (currentVersion:FrameworkIdentifier) compareVersion = - let isMatching (x:FrameworkIdentifier) = - if x = DotNetFramework FrameworkVersion.V3_5 && currentVersion = DotNetFramework FrameworkVersion.V4 then true else - if x = DotNetFramework FrameworkVersion.V3_5 && currentVersion = DotNetFramework FrameworkVersion.V4_Client then true else - if x = DotNetFramework FrameworkVersion.V4_Client && currentVersion = DotNetFramework FrameworkVersion.V4_5 then true else - let hasFrameworksBetween = - KnownTargetProfiles.DotNetFrameworkVersions - |> Seq.exists (fun p -> DotNetFramework p > x && DotNetFramework p < currentVersion) - let hasStandardsBetween = - KnownTargetProfiles.DotNetStandardVersions - |> Seq.exists (fun p -> DotNetStandard p > x && DotNetStandard p < currentVersion) - - not hasFrameworksBetween && not hasStandardsBetween - - match compareVersion with - | FrameworkRestriction.Exactly(DotNetFramework(x)) -> isMatching (DotNetFramework x) - | FrameworkRestriction.Exactly(DotNetStandard(x)) -> isMatching (DotNetStandard x) - | FrameworkRestriction.AtLeast(DotNetFramework(x)) -> - isMatching (DotNetFramework x) || - (match currentVersion with - | DotNetFramework(y) when x < y -> true - | _ -> false) - | FrameworkRestriction.AtLeast(DotNetStandard(x)) -> - isMatching (DotNetStandard x) || - (match currentVersion with - | DotNetStandard(y) when x < y -> true - | _ -> false) - | _ -> false - - match newRestrictions |> Seq.tryFind (isLowerVersion currentVersion) with - | None -> newRestrictions - | Some n -> - let newLowest = - match n with - | FrameworkRestriction.Exactly(DotNetFramework(x)) -> DotNetFramework x - | FrameworkRestriction.AtLeast(DotNetFramework(x)) -> DotNetFramework x - | FrameworkRestriction.Exactly(DotNetStandard(x)) -> DotNetStandard x - | FrameworkRestriction.AtLeast(DotNetStandard(x)) -> DotNetStandard x - | x -> failwithf "Unknown .NET moniker %O" x - - let filtered = - newRestrictions - |> List.filter (fun x -> x <> r && x <> n) - - filtered @ [FrameworkRestriction.AtLeast(newLowest)] - - if restrictions = filtered then sorting filtered else optimizeRestrictions filtered - -let hasDotNetFrameworkOrAnyCase = - List.exists (fun (_,_,rs) -> - rs = [] || - rs - |> List.exists (function - | FrameworkRestriction.Exactly(DotNetFramework(_)) -> true - | FrameworkRestriction.AtLeast(DotNetFramework(_)) -> true - | _ -> false)) - -let optimizeDependencies originalDependencies = - let grouped = originalDependencies |> List.groupBy (fun (n,v,_) -> n,v) - - let expanded = - [for (n,vr,r:FrameworkRestriction list) in originalDependencies do - for r' in r do - yield n,vr,r'] - |> List.groupBy (fun (_,_,r) -> r) - - let invertedRestrictions = - [for restriction,packages in expanded do - match restriction with - | FrameworkRestriction.Exactly(DotNetFramework _ as r) -> - yield r,packages |> List.map (fun (n,v,_) -> n,v) - | _ -> () ] - |> List.sortBy fst - - let invertedStandardRestrictions = - [for restriction,packages in expanded do - match restriction with - | FrameworkRestriction.Exactly(DotNetStandard _ as r) -> - yield r,packages |> List.map (fun (n,v,_) -> n,v) - | _ -> () ] - |> List.sortBy fst - - let globalMax = - invertedRestrictions - |> List.tryLast - |> Option.map fst - - let globalStandardMax = - invertedStandardRestrictions - |> List.tryLast - |> Option.map fst - - let globalMin = - invertedRestrictions - |> List.tryHead - |> Option.map fst - - let globalStandardMin = - invertedStandardRestrictions - |> List.tryHead - |> Option.map fst - - let emptyRestrictions = - [for (n,vr,r:FrameworkRestriction list) in originalDependencies do - if r = [] then - yield n,vr] - |> Set.ofList - - let allRestrictions = - [for (n,vr,r:FrameworkRestriction list) in originalDependencies do - yield r] - |> Set.ofList - - let restrictionsPerPackage = - originalDependencies - |> List.groupBy (fun (n,vr,r) -> n,vr) - |> List.map (fun ((n,vr),rs) -> - n,vr, - (rs - |> List.map (fun (_,_,r) -> r) - |> Set.ofList)) - - let packagesWithAllRestrictions = - restrictionsPerPackage - |> List.filter (fun (_,_,rs) -> rs = allRestrictions) - |> List.map (fun (n,vr,_) -> n,vr) - |> Set.ofList - - let newRestictions = - [for (name,versionRequirement:VersionRequirement),group in grouped do - if name <> PackageName "" then - let hasEmpty = not (Set.isEmpty emptyRestrictions) && Set.contains (name,versionRequirement) emptyRestrictions - let hasAll = not (Set.isEmpty packagesWithAllRestrictions) && Set.contains (name,versionRequirement) packagesWithAllRestrictions + let operands, next = parseOperand [] next + if operands.Length = 0 then failwithf "Operand '%s' without argument is invalid in '%s'" (h.Substring (0, 2)) text + let f, def = if isAnd then FrameworkRestriction.And, FrameworkRestriction.NoRestriction else FrameworkRestriction.Or, FrameworkRestriction.EmptySet + operands |> f, next + | h when h.StartsWith "NOT" -> + let next = h.Substring 2 - if hasEmpty && hasAll then - yield name,versionRequirement,[] - else - let sorted = - group - |> List.map (fun (_,_,res) -> res) - |> List.concat - |> List.distinct - |> List.sort - - let localMaxDotNetRestriction = findMaxDotNetRestriction sorted - let localMaxStandardRestriction = findMaxStandardRestriction sorted - let globalMax = defaultArg globalMax localMaxDotNetRestriction - let globalStandardMax = defaultArg globalStandardMax localMaxStandardRestriction - - let plain = - match sorted with - | [] -> - let globalStandardMin = defaultArg globalStandardMin localMaxDotNetRestriction - - let frameworks = - match globalMin with - | Some globalMin -> - KnownTargetProfiles.DotNetFrameworkVersions - |> List.filter (fun fw -> DotNetFramework(fw) < globalMin) - |> List.map (fun fw -> FrameworkRestriction.Exactly(DotNetFramework(fw))) - | _ -> - KnownTargetProfiles.DotNetFrameworkVersions - |> List.map (fun fw -> FrameworkRestriction.Exactly(DotNetFramework(fw))) - - let standards = - KnownTargetProfiles.DotNetStandardVersions - |> List.filter (fun fw -> DotNetStandard(fw) < globalStandardMin) - |> List.map (fun fw -> FrameworkRestriction.Exactly(DotNetStandard(fw))) - - frameworks @ standards - - | _ -> sorted - - let dotnetRestrictions,others = - plain - |> List.partition (fun p -> - match p with - | FrameworkRestriction.Exactly(DotNetFramework(_)) -> true - | FrameworkRestriction.AtLeast(DotNetFramework(_)) -> true - | FrameworkRestriction.Exactly(DotNetStandard(_)) -> true - | FrameworkRestriction.AtLeast(DotNetStandard(_)) -> true - | _ -> false) - - let restrictions' = - dotnetRestrictions - |> List.map (fun restriction -> - match restriction with - | FrameworkRestriction.Exactly(DotNetFramework _ as r) -> - if r = localMaxDotNetRestriction && r = globalMax then - FrameworkRestriction.AtLeast r - else - restriction - | FrameworkRestriction.Exactly (DotNetStandard _ as r) -> - if r = localMaxStandardRestriction && r = globalStandardMax then - FrameworkRestriction.AtLeast r - else - restriction - | _ -> restriction) - - let restrictions = optimizeRestrictions restrictions' - - yield name,versionRequirement,others @ restrictions] - - let hasDotNetFrameworkOrStandard = - newRestictions - |> List.exists (fun (_,_,rs) -> - rs - |> List.exists (function - | FrameworkRestriction.Exactly(DotNetFramework(_)) -> true - | FrameworkRestriction.AtLeast(DotNetFramework(_)) -> true - | FrameworkRestriction.Exactly(DotNetStandard(_)) -> true - | FrameworkRestriction.AtLeast(DotNetStandard(_)) -> true - | _ -> false)) - - if not hasDotNetFrameworkOrStandard then - newRestictions - else - let newRestictions = - if hasDotNetFrameworkOrAnyCase originalDependencies then - newRestictions + if next.TrimStart().StartsWith "(" then + let operand, remaining = parseOperator (next.Substring 1) + let remaining = remaining.TrimStart() + if remaining.StartsWith ")" |> not then failwithf "expected ')' after operand, '%s'" text + let next = remaining.Substring 1 + + let negated = + match operand with + | { OrFormulas = [ {Literals = [ lit] } ] } -> + [ {Literals = [ { lit with IsNegated = not lit.IsNegated } ] } ] + |> FrameworkRestriction.FromOrList + | _ -> failwithf "a general NOT is not implemted jet (and shouldn't be emitted for now)" + negated, next else - newRestictions - |> List.map (fun (name,vr,rs) -> - let newRs = - rs - |> List.collect (function - | FrameworkRestriction.Exactly(DotNetStandard(r)) -> - let compatible = - KnownTargetProfiles.DotNetFrameworkIdentifiers - |> List.filter (fun p -> p.IsCompatible(DotNetStandard r)) - |> List.map (fun p -> FrameworkRestriction.Exactly p) - FrameworkRestriction.AtLeast(DotNetStandard(r)) :: compatible - | FrameworkRestriction.AtLeast(DotNetStandard(r)) -> - let compatible = - KnownTargetProfiles.DotNetFrameworkIdentifiers - |> List.filter (fun p -> p.IsCompatible(DotNetStandard r)) - |> List.map (fun p -> FrameworkRestriction.AtLeast p) - FrameworkRestriction.AtLeast(DotNetStandard(r)) :: compatible - | r -> [r]) - |> optimizeRestrictions - - name,vr,newRs) - - - newRestictions - |> List.map (fun (p,v,rs) -> - let filtered = - rs - |> List.map (fun r -> - match r with - | FrameworkRestriction.Portable portable -> - let newPortable = - portable.Split('+') - |> Array.filter (fun s -> s.StartsWith "net" |> not) - |> fun xs -> String.Join("+",xs) - FrameworkRestriction.Portable newPortable - | _ -> r) - p,v,filtered) - - - |> List.map (fun (a,b,c) -> a,b, FrameworkRestrictionList c) - -let private combineSameCategoryOrPortableRestrictions x y = - match x with - | FrameworkRestriction.Exactly r -> - match y with - | FrameworkRestriction.Exactly r' -> if r = r' then [FrameworkRestriction.Exactly r] else [] - | FrameworkRestriction.Portable _ -> [] - | FrameworkRestriction.AtLeast r' -> if r' <= r then [FrameworkRestriction.Exactly r] else [] - | FrameworkRestriction.Between(min,max) -> if min <= r && r < max then [FrameworkRestriction.Exactly r] else [] - | FrameworkRestriction.Portable r -> - match y with - | FrameworkRestriction.Portable r' -> if r = r' then [FrameworkRestriction.Portable r] else [] - | _ -> [] - | FrameworkRestriction.AtLeast r -> - match y with - | FrameworkRestriction.Exactly r' -> if r <= r' then [FrameworkRestriction.Exactly r'] else [] - | FrameworkRestriction.Portable _ -> [] - | FrameworkRestriction.AtLeast r' -> [FrameworkRestriction.AtLeast (max r r')] - | FrameworkRestriction.Between(min,max') -> if r < max' then [FrameworkRestriction.Between(max r min,max')] else [] - | FrameworkRestriction.Between(min1,max1) -> - match y with - | FrameworkRestriction.Exactly r -> if min1 <= r && r < max1 then [FrameworkRestriction.Exactly r] else [] - | FrameworkRestriction.Portable _ -> [] - | FrameworkRestriction.AtLeast r -> if r < max1 then [FrameworkRestriction.Between(max r min1,max1)] else [] - | FrameworkRestriction.Between(min2,max2) -> - let min' = max min1 min2 - let max' = min max1 max2 - if min' < max' then [FrameworkRestriction.Between(min',max')] else - if min' = max' then [FrameworkRestriction.Exactly(min')] else - [] - -let combineRestrictions loose (x : FrameworkRestriction) y = - if x.IsSameCategoryAs(y) <> Some false then - combineSameCategoryOrPortableRestrictions x y - else - if loose then - match (x.GetOneIdentifier, y.GetOneIdentifier) with - | Some (FrameworkIdentifier.DotNetFramework _ ), Some (FrameworkIdentifier.DotNetStandard _ ) -> [x] - | Some (FrameworkIdentifier.DotNetStandard _ ), Some (FrameworkIdentifier.DotNetFramework _ ) -> [y] - | _ -> [] - else - [] + failwithf "Expected operand after NOT, '%s'" text + | h when h.StartsWith "true" -> + let rest = (h.Substring 4).TrimStart() + FrameworkRestriction.NoRestriction, rest + | h when h.StartsWith "false" -> + let rest = (h.Substring 5).TrimStart() + FrameworkRestriction.EmptySet, rest + | _ -> + failwithf "Expected operator, but got '%s'" text + + let result, next = parseOperator text + if String.IsNullOrEmpty next |> not then + failwithf "Successfully parsed '%O' but got additional text '%s'" result next + result let filterRestrictions (list1:FrameworkRestrictions) (list2:FrameworkRestrictions) = match list1,list2 with - | FrameworkRestrictionList [], AutoDetectFramework -> AutoDetectFramework - | AutoDetectFramework, FrameworkRestrictionList [] -> AutoDetectFramework + | ExplicitRestriction FrameworkRestriction.HasNoRestriction, AutoDetectFramework -> AutoDetectFramework + | AutoDetectFramework, ExplicitRestriction FrameworkRestriction.HasNoRestriction -> AutoDetectFramework | AutoDetectFramework, AutoDetectFramework -> AutoDetectFramework - | FrameworkRestrictionList list1 , FrameworkRestrictionList list2 -> - let filtered = - match list1, list2 with - | [],_ -> list2 - | _,[] -> list1 - | _ -> - [for x in list1 do - for y in list2 do - let c = combineRestrictions false x y - if c <> [] then yield! c] - - let tryLoose = - (filtered |> List.exists (fun r -> match r.GetOneIdentifier with | Some (FrameworkIdentifier.DotNetFramework _ ) -> true | _ -> false) |> not) && - (list2 |> List.exists (fun r -> match r.GetOneIdentifier with | Some (FrameworkIdentifier.DotNetFramework _ ) -> true | _ -> false)) - - let filtered = - if tryLoose then - match list1, list2 with - | [],_ -> list2 - | _,[] -> list1 - | _ -> - [for x in list1 do - for y in list2 do - let c = combineRestrictions true x y - if c <> [] then yield! c] - else - filtered - - let optimized = - filtered - |> optimizeRestrictions - FrameworkRestrictionList optimized + | ExplicitRestriction fr1 , ExplicitRestriction fr2 -> ExplicitRestriction (FrameworkRestriction.combineRestrictionsWithAnd fr1 fr2) | _ -> failwithf "The framework restriction %O and %O could not be combined." list1 list2 /// Get if a target should be considered with the specified restrictions -let isTargetMatchingRestrictions = - memoize <| fun (restrictions:FrameworkRestriction list, target) -> - if List.isEmpty restrictions then true else - match target with - | SinglePlatform pf -> - restrictions - |> List.exists (fun restriction -> - match restriction with - | FrameworkRestriction.Exactly (Native(NoBuildMode,NoPlatform)) -> - match pf with - | Native(_) -> true - | _ -> false - | FrameworkRestriction.Exactly fw -> - match fw, pf with - | DotNetFramework _, DotNetStandard _ -> false - | DotNetStandard _, DotNetFramework _ -> false - | _ -> pf.IsCompatible(fw) - | FrameworkRestriction.Portable _ -> false - | FrameworkRestriction.AtLeast fw -> - match fw, pf with - | DotNetFramework _, DotNetStandard _ -> false - | DotNetStandard _, DotNetFramework _ -> false - | _ -> pf.IsAtLeast(fw) - | FrameworkRestriction.Between(min,max) -> - match min, pf with - | DotNetFramework _, DotNetStandard _ -> false - | DotNetStandard _, DotNetFramework _ -> false - | _ -> pf.IsBetween(min,max)) - | _ -> - restrictions - |> List.exists (fun restriction -> - match restriction with - | FrameworkRestriction.Portable r -> true - | _ -> false) +let isTargetMatchingRestrictions (restriction:FrameworkRestriction, target)= + restriction.IsMatch target /// Get all targets that should be considered with the specified restrictions -let applyRestrictionsToTargets (restrictions:FrameworkRestriction list) (targets: TargetProfile list) = - targets - |> List.filter (fun t -> isTargetMatchingRestrictions(restrictions,t)) +let applyRestrictionsToTargets (restriction:FrameworkRestriction) (targets: TargetProfile Set) = + Set.intersect targets restriction.RepresentedFrameworks type ContentCopySettings = | Omit @@ -570,7 +685,7 @@ type InstallSettings = static member Default = { CopyLocal = None ImportTargets = None - FrameworkRestrictions = FrameworkRestrictionList [] + FrameworkRestrictions = ExplicitRestriction FrameworkRestriction.NoRestriction IncludeVersionInPath = None ReferenceCondition = None CreateBindingRedirects = None @@ -610,9 +725,9 @@ type InstallSettings = | Some Force -> yield "redirects: force" | None -> () match this.FrameworkRestrictions with - | FrameworkRestrictionList [] -> () + | ExplicitRestriction FrameworkRestriction.HasNoRestriction -> () | AutoDetectFramework -> () - | FrameworkRestrictionList list -> yield "framework: " + (String.Join(", ",list)) + | ExplicitRestriction fr -> yield "restriction: " + (fr.ToString()) match this.GenerateLoadScripts with | Some true -> yield "generate_load_scripts: true" | Some false -> yield "generate_load_scripts: false" @@ -652,9 +767,12 @@ type InstallSettings = | Some "true" -> Some true | _ -> None FrameworkRestrictions = - match getPair "framework" with - | Some s -> FrameworkRestrictionList(parseRestrictions true s) - | _ -> FrameworkRestrictionList [] + match getPair "restriction" with + | Some s -> ExplicitRestriction(parseRestrictions true s) + | _ -> + match getPair "framework" with + | Some s -> ExplicitRestriction(parseRestrictionsLegacy true s) + | _ -> ExplicitRestriction FrameworkRestriction.NoRestriction OmitContent = match getPair "content" with | Some "none" -> Some ContentCopySettings.Omit @@ -762,7 +880,7 @@ type PackageRequirement = ResolverStrategyForDirectDependencies : ResolverStrategy option ResolverStrategyForTransitives : ResolverStrategy option Parent: PackageRequirementSource - Graph: PackageRequirement list + Graph: PackageRequirement Set Sources: PackageSource list Settings: InstallSettings } @@ -788,7 +906,7 @@ type PackageRequirement = member this.IncludingPrereleases() = this.IncludingPrereleases(PreReleaseStatus.All) - member this.Depth = this.Graph.Length + member this.Depth = this.Graph.Count static member Compare(x,y,startWithPackage:PackageFilter option,boostX,boostY) = if obj.ReferenceEquals(x, y) then 0 else @@ -809,11 +927,11 @@ type PackageRequirement = if c <> 0 then c else let c = -compare x.VersionRequirement y.VersionRequirement if c <> 0 then c else - let c = compare x.Settings.FrameworkRestrictions y.Settings.FrameworkRestrictions - if c <> 0 then c else let c = compare x.Parent y.Parent if c <> 0 then c else let c = compare x.Name y.Name + if c <> 0 then c else + let c = compare x.Settings.FrameworkRestrictions y.Settings.FrameworkRestrictions if c <> 0 then c else 0 interface System.IComparable with @@ -821,4 +939,53 @@ type PackageRequirement = match that with | :? PackageRequirement as that -> PackageRequirement.Compare(this,that,None,0,0) - | _ -> invalidArg "that" "cannot compare value of different types" \ No newline at end of file + | _ -> invalidArg "that" "cannot compare value of different types" + +let addFrameworkRestrictionsToDependencies rawDependencies (frameworkGroups:PlatformMatching.ParsedPlatformPath list) = + let referenced = + rawDependencies + |> List.groupBy (fun (n:PackageName,req,pp:PlatformMatching.ParsedPlatformPath) -> n,req) + |> List.map (fun ((name, req), group) -> + // We need to append all the other platforms we support. + let packageGroups = group |> List.map (fun (_,_,packageGroup) -> packageGroup) + let restrictions = + packageGroups + |> List.map (fun packageGroup -> + let packageGroupRestriction = + match packageGroup.Platforms with + | _ when System.String.IsNullOrEmpty packageGroup.Name -> FrameworkRestriction.NoRestriction + | [] -> FrameworkRestriction.NoRestriction + | [ pf ] -> FrameworkRestriction.AtLeast pf + | _ -> FrameworkRestriction.AtLeastPortable(packageGroup.Name, packageGroup.Platforms) + + frameworkGroups + |> Seq.choose (fun g -> g.ToTargetProfile) + // TODO: Check if this is needed (I think the logic below is a general version of this subset logic) + |> Seq.filter (fun frameworkGroup -> + // filter all restrictions which would render this group to nothing (ie smaller restrictions) + // filter out unrelated restrictions + packageGroupRestriction.IsSubsetOf (FrameworkRestriction.AtLeastPlatform frameworkGroup) |> not) + |> Seq.fold (fun curRestr frameworkGroup -> + // We start with the restriction inherently given by the current group, + // But this is too broad as other groups might "steal" better suited frameworks + // So we subtract all "bigger" groups ('frameworkGroup' parameter). + // Problem is that this is too strict as there might be an intersection that now is assigned nowhere + // Example would be two groups with netstandard13 and net451 which will generate + // (>=net451 && <=netstandard13) for one and (>=netstandard13 && <=net451) for the other group + // but now net461 which supports netstandard13 is nowhere -> we need to decide here and add back the intersection + + let missing = FrameworkRestriction.combineRestrictionsWithAnd curRestr (FrameworkRestriction.AtLeastPlatform frameworkGroup) + let combined = FrameworkRestriction.combineRestrictionsWithAnd curRestr (FrameworkRestriction.NotAtLeastPlatform frameworkGroup) + match packageGroup.Platforms, missing.RepresentedFrameworks.IsEmpty with + | [ packageGroupFw ], false -> + // the common set goes to the better matching one + match PlatformMatching.findBestMatch (frameworkGroups, missing.RepresentedFrameworks.MinimumElement) with + | Some { PlatformMatching.ParsedPlatformPath.Platforms = [ cfw ] } when cfw = packageGroupFw -> curRestr + | _ -> combined + | _ -> combined) packageGroupRestriction) + let combinedRestrictions = restrictions |> List.fold FrameworkRestriction.combineRestrictionsWithOr FrameworkRestriction.EmptySet + name, req, combinedRestrictions + ) + + referenced + |> List.map (fun (a,b,c) -> a,b, ExplicitRestriction c) \ No newline at end of file diff --git a/src/Paket/Paket.fsproj b/src/Paket/Paket.fsproj index 6abd605f9a..576d6a05d8 100644 --- a/src/Paket/Paket.fsproj +++ b/src/Paket/Paket.fsproj @@ -30,8 +30,8 @@ Project paket.exe Project - restore - C:\temp\PaketRepro + update + C:\PROJ\Yaaf\Paket\integrationtests\scenarios\i002294-pin-netstandard-1-6\temp true @@ -42,7 +42,7 @@ update - D:\temp\TestProject + C:\PROJ\Yaaf\paket-tests\test2\ 14.0 diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index f017480d5f..018f4b193e 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -13,8 +13,7 @@ open PackageSources open System.Xml open Paket.Domain -let private stopWatch = new Stopwatch() -stopWatch.Start() +let sw = Stopwatch.StartNew() type PaketExiter() = interface IExiter with @@ -35,10 +34,71 @@ let processWithValidation silent validateF commandF (result : ParseResults<'T>) Environment.ExitCode <- 1 #endif else - commandF result - let elapsedTime = Utils.TimeSpanToReadableString stopWatch.Elapsed - if not silent then - tracefn "%s - ready." elapsedTime + try + commandF result + finally + sw.Stop() + if not silent then + let realTime = sw.Elapsed + let groupedResults = + Profile.events + |> Seq.groupBy (fun (ev) -> ev.Category) + |> Seq.map (fun (cat, group) -> + let l = group |> Seq.toList + cat, l.Length, l |> Seq.map (fun ev -> ev.Duration) |> Seq.fold (+) (TimeSpan())) + |> Seq.toList + let blockedRaw = + groupedResults + |> List.filter (function Profile.Category.ResolverAlgorithmBlocked _, _, _ -> true | _ -> false) + let blocked = + blockedRaw + |> List.map (fun (_,_,t) -> t) + |> Seq.fold (+) (TimeSpan()) + let resolver = + match groupedResults |> List.tryPick (function Profile.Category.ResolverAlgorithm, _, s -> Some s | _ -> None) with + | Some s -> s + | None -> TimeSpan() + tracefn "Performance:" + groupedResults + |> List.sortBy (fun (cat,_,_) -> + match cat with + | Profile.Category.ResolverAlgorithm -> 1 + | Profile.Category.ResolverAlgorithmBlocked b -> 2 + | Profile.Category.FileIO -> 3 + | Profile.Category.NuGetDownload -> 4 + | Profile.Category.NuGetRequest -> 5 + | Profile.Category.Other -> 6) + |> List.iter (fun (cat, num, elapsed) -> + match cat with + | Profile.Category.ResolverAlgorithm -> + tracefn " - Resolver: %s (%d runs)" (Utils.TimeSpanToReadableString elapsed) num + let realTime = resolver - blocked + tracefn " - Runtime: %s" (Utils.TimeSpanToReadableString realTime) + let blockNum = blockedRaw |> Seq.sumBy (fun (_, num, _) -> num) + let blockPaket4 = TimeSpan.FromMilliseconds(500.0 * float blockNum) + tracefn " - Runtime Paket 4 (estimated ~500ms respose*): %s" (Utils.TimeSpanToReadableString (realTime + blockPaket4)) + tracefn " * See http://stats.pingdom.com/aqicaf2upspo/1265300 for average response times." + | Profile.Category.ResolverAlgorithmBlocked b -> + let reason = + match b with + | Profile.BlockReason.PackageDetails -> "retrieving package details" + | Profile.BlockReason.GetVersion -> "retrieving package versions" + tracefn " - Blocked (%s): %s (%d times)" reason (Utils.TimeSpanToReadableString elapsed) num + | Profile.Category.FileIO -> + tracefn " - Disk IO: %s" (Utils.TimeSpanToReadableString elapsed) + | Profile.Category.NuGetDownload -> + let avg = TimeSpan.FromTicks(elapsed.Ticks / int64 num) + tracefn " - Average Download Time: %s" (Utils.TimeSpanToReadableString avg) + tracefn " - Number of downloads: %d" num + | Profile.Category.NuGetRequest -> + let avg = TimeSpan.FromTicks(elapsed.Ticks / int64 num) + tracefn " - Average Request Time: %s" (Utils.TimeSpanToReadableString avg) + tracefn " - Number of Requests: %d" num + | Profile.Category.Other -> + tracefn " - Other: %s" (Utils.TimeSpanToReadableString elapsed) + ) + + tracefn " - Runtime: %s" (Utils.TimeSpanToReadableString realTime) let processCommand silent commandF result = processWithValidation silent (fun _ -> true) commandF result diff --git a/tests/Paket.Tests/DependenciesFile/ParserSpecs.fs b/tests/Paket.Tests/DependenciesFile/ParserSpecs.fs index c41032bd26..b8b0fd9f54 100644 --- a/tests/Paket.Tests/DependenciesFile/ParserSpecs.fs +++ b/tests/Paket.Tests/DependenciesFile/ParserSpecs.fs @@ -749,7 +749,7 @@ let ``should read config with local source``() = let p = cfg.Groups.[Constants.MainDependencyGroup].Packages |> List.find (fun x-> x.Name = PackageName "Nancy.Owin") p.VersionRequirement.Range |> shouldEqual (VersionRange.Specific (SemVer.Parse "0.22.2")) - p.Settings.FrameworkRestrictions |> getRestrictionList |> shouldEqual [] + p.Settings.FrameworkRestrictions |> getExplicitRestriction |> shouldEqual FrameworkRestriction.NoRestriction [] @@ -770,7 +770,7 @@ let ``should read config with single framework restriction``() = let p = cfg.Groups.[Constants.MainDependencyGroup].Packages |> List.find (fun x-> x.Name = PackageName "Foobar") p.VersionRequirement.Range |> shouldEqual (VersionRange.Specific (SemVer.Parse "1.2.3")) - p.Settings.FrameworkRestrictions |> getRestrictionList |> shouldEqual [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_Client))] + p.Settings.FrameworkRestrictions |> getExplicitRestriction |> shouldEqual (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) p.Settings.ImportTargets |> shouldEqual None @@ -783,7 +783,7 @@ let ``should read config with framework restriction``() = let p = cfg.Groups.[Constants.MainDependencyGroup].Packages |> List.find (fun x-> x.Name = PackageName "Foobar") p.VersionRequirement.Range |> shouldEqual (VersionRange.Specific (SemVer.Parse "1.2.3")) - p.Settings.FrameworkRestrictions |> getRestrictionList |> shouldEqual [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V3_5)); FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_Client))] + p.Settings.FrameworkRestrictions |> getExplicitRestriction |> shouldEqual (makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V3_5)); FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] |> getExplicitRestriction) p.Settings.ImportTargets |> shouldEqual None p.Settings.CopyLocal |> shouldEqual None @@ -796,7 +796,7 @@ let ``should read config with no targets import``() = let p = cfg.Groups.[Constants.MainDependencyGroup].Packages |> List.find (fun x-> x.Name = PackageName "Foobar") p.VersionRequirement.Range |> shouldEqual (VersionRange.Specific (SemVer.Parse "1.2.3")) - p.Settings.FrameworkRestrictions |> getRestrictionList |> shouldEqual [] + p.Settings.FrameworkRestrictions |> getExplicitRestriction |> shouldEqual FrameworkRestriction.NoRestriction p.Settings.ImportTargets |> shouldEqual (Some false) p.Settings.CopyLocal |> shouldEqual (Some false) p.Settings.OmitContent |> shouldEqual None @@ -810,7 +810,7 @@ let ``should read config with content none``() = let p = cfg.Groups.[Constants.MainDependencyGroup].Packages |> List.find (fun x-> x.Name = PackageName "Foobar") p.VersionRequirement.Range |> shouldEqual (VersionRange.Specific (SemVer.Parse "1.2.3")) - p.Settings.FrameworkRestrictions |> getRestrictionList |> shouldEqual [] + p.Settings.FrameworkRestrictions |> getExplicitRestriction |> shouldEqual FrameworkRestriction.NoRestriction p.Settings.ImportTargets |> shouldEqual None p.Settings.CopyLocal |> shouldEqual (Some false) p.Settings.OmitContent |> shouldEqual (Some ContentCopySettings.Omit) @@ -1127,8 +1127,8 @@ let ``should read config with target framework``() = let cfg = DependenciesFile.FromSource(configTargetFramework) cfg.Groups.[Constants.MainDependencyGroup].Options.Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual [FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))] + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))) [] let ``should read packages with redirects``() = diff --git a/tests/Paket.Tests/DependenciesFile/VersionRequirementSpecs.fs b/tests/Paket.Tests/DependenciesFile/VersionRequirementSpecs.fs index a88076a786..254c4ea227 100644 --- a/tests/Paket.Tests/DependenciesFile/VersionRequirementSpecs.fs +++ b/tests/Paket.Tests/DependenciesFile/VersionRequirementSpecs.fs @@ -14,7 +14,7 @@ let require packageName strategyForTransitives text : PackageRequirement = ResolverStrategyForDirectDependencies = None ResolverStrategyForTransitives = Some strategyForTransitives Parent = PackageRequirementSource.DependenciesFile "" - Graph = [] + Graph = Set.empty Sources = [] Settings = InstallSettings.Default } diff --git a/tests/Paket.Tests/InstallModel/FrameworkIdentifierSpecs.fs b/tests/Paket.Tests/InstallModel/FrameworkIdentifierSpecs.fs index fe5bc11911..ea6e6f7fc7 100644 --- a/tests/Paket.Tests/InstallModel/FrameworkIdentifierSpecs.fs +++ b/tests/Paket.Tests/InstallModel/FrameworkIdentifierSpecs.fs @@ -7,24 +7,24 @@ open FsUnit [] let ``should understand basic framework versions net20, net40, net45 ...``() = FrameworkDetection.Extract("net20").Value |> shouldEqual (DotNetFramework(FrameworkVersion.V2)) - FrameworkDetection.Extract("net40").Value |> shouldEqual (DotNetFramework(FrameworkVersion.V4_Client)) + FrameworkDetection.Extract("net40").Value |> shouldEqual (DotNetFramework(FrameworkVersion.V4)) FrameworkDetection.Extract("net45").Value |> shouldEqual (DotNetFramework(FrameworkVersion.V4_5)) [] let ``should understand basic silverlight``() = - FrameworkDetection.Extract("sl").Value |> shouldEqual (Silverlight "v3.0") - FrameworkDetection.Extract("sl3").Value |> shouldEqual (Silverlight "v3.0") - FrameworkDetection.Extract("sl4").Value |> shouldEqual (Silverlight "v4.0") + FrameworkDetection.Extract("sl").Value |> shouldEqual (Silverlight SilverlightVersion.V3) + FrameworkDetection.Extract("sl3").Value |> shouldEqual (Silverlight SilverlightVersion.V3) + FrameworkDetection.Extract("sl4").Value |> shouldEqual (Silverlight SilverlightVersion.V4) [] let ``should serialize basic framework versions net20, net40, net45 ...``() = DotNetFramework(FrameworkVersion.V2).ToString() |> shouldEqual "net20" - DotNetFramework(FrameworkVersion.V4_Client).ToString() |> shouldEqual "net40" + DotNetFramework(FrameworkVersion.V4).ToString() |> shouldEqual "net40" DotNetFramework(FrameworkVersion.V4_5).ToString() |> shouldEqual "net45" [] let ``should serialize silverlight framework identifier correctly``() = - Silverlight("v5.0").ToString() |> shouldEqual "sl50" + (Silverlight SilverlightVersion.V5).ToString() |> shouldEqual "sl5" [] let ``should understand basic dnx``() = diff --git a/tests/Paket.Tests/InstallModel/Penalty/FrameworkConditionsSpecs.fs b/tests/Paket.Tests/InstallModel/Penalty/FrameworkConditionsSpecs.fs index 4dda0bd24e..89a3a79752 100644 --- a/tests/Paket.Tests/InstallModel/Penalty/FrameworkConditionsSpecs.fs +++ b/tests/Paket.Tests/InstallModel/Penalty/FrameworkConditionsSpecs.fs @@ -11,49 +11,51 @@ let getCondition cond targets = getCondition cond [targets] targets [] let ``should create empty condition for empty profile list``() = - getCondition None [] + getCondition None Set.empty |> shouldEqual "" [] let ``should create simple condition for simple .NET Framework``() = - getCondition None [SinglePlatform(DotNetFramework FrameworkVersion.V3)] + getCondition None (SinglePlatform(DotNetFramework FrameworkVersion.V3) |> Set.singleton) |> shouldEqual "$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v3.0'" [] let ``should create nested condition for two .NET Frameworks``() = - getCondition None [SinglePlatform(DotNetFramework FrameworkVersion.V3); SinglePlatform(DotNetFramework FrameworkVersion.V4_5)] + getCondition None ([SinglePlatform(DotNetFramework FrameworkVersion.V3); SinglePlatform(DotNetFramework FrameworkVersion.V4_5)] |> Set.ofSeq) |> shouldEqual "$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v3.0' Or $(TargetFrameworkVersion) == 'v4.5')" [] let ``should create nested condition for two .NET Frameworks in different order``() = - getCondition None [SinglePlatform(DotNetFramework FrameworkVersion.V4_5); SinglePlatform(DotNetFramework FrameworkVersion.V3)] + getCondition None ([SinglePlatform(DotNetFramework FrameworkVersion.V4_5); SinglePlatform(DotNetFramework FrameworkVersion.V3)] |> Set.ofSeq) |> shouldEqual "$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v3.0' Or $(TargetFrameworkVersion) == 'v4.5')" [] let ``should create nested condition for multiple .NET Frameworks``() = - getCondition None [SinglePlatform(DotNetFramework FrameworkVersion.V3); SinglePlatform(DotNetFramework FrameworkVersion.V4_5); SinglePlatform(DotNetFramework FrameworkVersion.V2)] + getCondition None ([SinglePlatform(DotNetFramework FrameworkVersion.V3); SinglePlatform(DotNetFramework FrameworkVersion.V4_5); SinglePlatform(DotNetFramework FrameworkVersion.V2)] |> Set.ofSeq) |> shouldEqual "$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v2.0' Or $(TargetFrameworkVersion) == 'v3.0' Or $(TargetFrameworkVersion) == 'v4.5')" [] let ``should minimize condition if we have all .NET Frameworks``() = - getCondition None KnownTargetProfiles.DotNetFrameworkProfiles + getCondition None (KnownTargetProfiles.DotNetFrameworkProfiles |> Set.ofSeq) |> shouldEqual "$(TargetFrameworkIdentifier) == '.NETFramework'" [] let ``should minimize condition if we have all WindowsProfiles``() = - getCondition None KnownTargetProfiles.WindowsProfiles + getCondition None (KnownTargetProfiles.WindowsProfiles |> Set.ofSeq) |> shouldEqual "$(TargetFrameworkIdentifier) == '.NETCore'" [] let ``should create nested condition for .NET Framework and Silverlight``() = [SinglePlatform(DotNetFramework FrameworkVersion.V3) SinglePlatform(DotNetFramework FrameworkVersion.V4_5) - SinglePlatform(Silverlight("v3.0"))] + SinglePlatform(Silverlight SilverlightVersion.V3)] + |> Set.ofSeq |> getCondition None |> shouldEqual "($(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v3.0' Or $(TargetFrameworkVersion) == 'v4.5')) Or ($(TargetFrameworkIdentifier) == 'Silverlight' And $(TargetFrameworkVersion) == 'v3.0')" [] let ``should create nested condition for full .NET Framework and Silverlight``() = - SinglePlatform(Silverlight("v3.0")) :: KnownTargetProfiles.DotNetFrameworkProfiles + SinglePlatform(Silverlight SilverlightVersion.V3) :: KnownTargetProfiles.DotNetFrameworkProfiles + |> Set.ofSeq |> getCondition None |> shouldEqual "($(TargetFrameworkIdentifier) == '.NETFramework') Or ($(TargetFrameworkIdentifier) == 'Silverlight' And $(TargetFrameworkVersion) == 'v3.0')" \ No newline at end of file diff --git a/tests/Paket.Tests/InstallModel/Penalty/PenaltySpecs.fs b/tests/Paket.Tests/InstallModel/Penalty/PenaltySpecs.fs index 0103fb9bf8..10ad68b377 100644 --- a/tests/Paket.Tests/InstallModel/Penalty/PenaltySpecs.fs +++ b/tests/Paket.Tests/InstallModel/Penalty/PenaltySpecs.fs @@ -9,84 +9,86 @@ module ``Given a target platform`` = [] let ``it should return no penalty for the same platform``() = - getPlatformPenalty (DotNetFramework FrameworkVersion.V4_5, DotNetFramework FrameworkVersion.V4_5) + getFrameworkPenalty (DotNetFramework FrameworkVersion.V4_5, DotNetFramework FrameworkVersion.V4_5) |> shouldEqual 0 [] let ``it should return the right penalty for a compatible platform``() = - getPlatformPenalty (DotNetFramework FrameworkVersion.V4_5, DotNetFramework FrameworkVersion.V4) - |> shouldEqual 1 + getFrameworkPenalty (DotNetFramework FrameworkVersion.V4_5, DotNetFramework FrameworkVersion.V4) + |> shouldEqual 2 [] let ``it should return > 1000 for an incompatible platform``() = - getPlatformPenalty (DotNetFramework FrameworkVersion.V4_5, Silverlight "v5.0") + getFrameworkPenalty (DotNetFramework FrameworkVersion.V4_5, Silverlight SilverlightVersion.V5) |> shouldBeGreaterThan MaxPenalty [] let ``it should prefer .net proper``() = - let p1 = getPlatformPenalty (DotNetFramework FrameworkVersion.V4_6_2, DotNetFramework FrameworkVersion.V4_5_1) - let p2 = getPlatformPenalty (DotNetFramework FrameworkVersion.V4_6_2, DotNetStandard DotNetStandardVersion.V1_5) + let p1 = getFrameworkPenalty (DotNetFramework FrameworkVersion.V4_6_2, DotNetFramework FrameworkVersion.V4_5_1) + let p2 = getFrameworkPenalty (DotNetFramework FrameworkVersion.V4_6_2, DotNetStandard DotNetStandardVersion.V1_5) p1 |> shouldBeSmallerThan p2 module ``Given a path`` = [] let ``it should split it into the right platforms``() = - extractPlatforms "net40+win8" + forceExtractPlatforms "net40+win8" |> shouldEqual - { Platforms = [ DotNetFramework FrameworkVersion.V4_Client; Windows "v4.5" ] + { Platforms = [ DotNetFramework FrameworkVersion.V4; Windows WindowsVersion.V8 ] Name = "net40+win8" } [] let ``it should ignore 'portable-'``() = - extractPlatforms "portable-net40+win8" + forceExtractPlatforms "portable-net40+win8" |> shouldEqual - { Platforms = [ DotNetFramework FrameworkVersion.V4_Client; Windows "v4.5" ] + { Platforms = [ DotNetFramework FrameworkVersion.V4; Windows WindowsVersion.V8 ] Name = "portable-net40+win8" } [] let ``it should return no penalty for a matching .NET framework``() = - let path = extractPlatforms "net45" - getPenalty [ DotNetFramework FrameworkVersion.V4_5 ] path |> shouldEqual 0 + let path = forceExtractPlatforms "net45" + getFrameworkPathPenalty [ DotNetFramework FrameworkVersion.V4_5 ] path |> shouldEqual 0 [] let ``it should return no penalty for a matching portable profile``() = - let path = extractPlatforms "net40+sl4" - getPenalty [ DotNetFramework FrameworkVersion.V4_Client - Silverlight "v4.0" ] path + let path = forceExtractPlatforms "net40+sl4" + getFrameworkPathPenalty + [ DotNetFramework FrameworkVersion.V4 + Silverlight SilverlightVersion.V4 ] path |> shouldEqual 0 [] let ``it should return 1 for a compatible portable profile``() = - let path = extractPlatforms "net40+sl4" - getPenalty [ DotNetFramework FrameworkVersion.V4_Client - Silverlight "v5.0" ] path + let path = forceExtractPlatforms "net40+sl4" + getFrameworkPathPenalty + [ DotNetFramework FrameworkVersion.V4 + Silverlight SilverlightVersion.V5 ] path |> shouldEqual 1 [] let ``it should return the correct penalty for compatible .NET Frameworks``() = - let path = extractPlatforms "net20" - getPenalty [ DotNetFramework FrameworkVersion.V2 ] path |> shouldEqual 0 - getPenalty [ DotNetFramework FrameworkVersion.V3 ] path |> shouldEqual 1 - getPenalty [ DotNetFramework FrameworkVersion.V3_5 ] path |> shouldEqual 2 - getPenalty [ DotNetFramework FrameworkVersion.V4_Client ] path |> shouldEqual 3 + let path = forceExtractPlatforms "net20" + getFrameworkPathPenalty [ DotNetFramework FrameworkVersion.V2 ] path |> shouldEqual 0 + getFrameworkPathPenalty [ DotNetFramework FrameworkVersion.V3 ] path |> shouldEqual 1 + getFrameworkPathPenalty [ DotNetFramework FrameworkVersion.V3_5 ] path |> shouldEqual 2 + getFrameworkPathPenalty [ DotNetFramework FrameworkVersion.V4 ] path |> shouldEqual 3 module ``Given an empty path`` = [] let ``it should be okay to use from .NET``() = - let path = extractPlatforms "" - getPenalty [ DotNetFramework FrameworkVersion.V4_5 ] path |> shouldBeSmallerThan 1000 + let path = forceExtractPlatforms "" + getFrameworkPathPenalty [ DotNetFramework FrameworkVersion.V4_5 ] path |> shouldBeSmallerThan 2000 [] let ``it should be okay to use from a portable profile``() = - let path = extractPlatforms "" - getPenalty [ DotNetFramework FrameworkVersion.V4_5; Windows "v4.5"; WindowsPhoneApp "v8.1" ] path |> shouldBeSmallerThan 2000 + let path = forceExtractPlatforms "" + getFrameworkPathPenalty [ DotNetFramework FrameworkVersion.V4_5; Windows WindowsVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] path |> shouldBeSmallerThan 2000 module ``Given a list of paths`` = let paths = [ "net40"; "portable-monotouch+monoandroid"; "portable-net40+sl5+win8+wp8+wpa81" "portable-net45+winrt45+wp8+wpa81"; "portable-win81+wpa81"; "portable-windows8+net45+wp8"; "sl5"; "win8" "wp8" ] - |> List.map extractPlatforms + |> List.map forceExtractPlatforms let find n = paths |> Seq.find (fun p -> p.Name = n) @@ -97,11 +99,11 @@ module ``Given a list of paths`` = [] let ``it should find the best match for Silverlight 5``() = - findBestMatch (paths, SinglePlatform(Silverlight "v5.0")) |> shouldEqual (find "sl5"|> Some) + findBestMatch (paths, SinglePlatform(Silverlight SilverlightVersion.V5)) |> shouldEqual (find "sl5"|> Some) [] let ``it should find no match for Silverlight 4``() = - findBestMatch (paths, SinglePlatform(Silverlight "v4.0")) |> shouldEqual None + findBestMatch (paths, SinglePlatform(Silverlight SilverlightVersion.V4)) |> shouldEqual None [] let ``it should prefer (older) full .NET frameworks over portable class libraries``() = @@ -124,130 +126,124 @@ module ``Given a list of paths`` = } flattend |> shouldNotContain (KnownTargetProfiles.FindPortableProfile "Profile41") -module ``ProfileAnalyzer tests`` = - [] - let ``test that we cannot detect portable-net40+sl4+win8+wp71+wpa81`` () = - let res = Paket.PlatformMatching.tryGetProfile (extractPlatforms "portable-net40+sl4+win8+wp71+wpa81") - res |> shouldEqual None - module ``General Penalty checks`` = [] let ``prefer net20 over emtpy folder``()= - Paket.PlatformMatching.findBestMatch ([""; "net20"] |> List.map extractPlatforms, SinglePlatform(DotNetFramework(FrameworkVersion.V4_6_1))) - |> shouldEqual (Some (extractPlatforms "net20")) + Paket.PlatformMatching.findBestMatch ([""; "net20"] |> List.map forceExtractPlatforms, SinglePlatform(DotNetFramework(FrameworkVersion.V4_6_1))) + |> shouldEqual (Some (forceExtractPlatforms "net20")) [] let ``best match for DotNet Standard 1.0``()= - Paket.PlatformMatching.findBestMatch (["net20"; "net40"; "net45"; "net451"]|> List.map extractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_0))) + Paket.PlatformMatching.findBestMatch (["net20"; "net40"; "net45"; "net451"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_0))) |> shouldEqual (None) [] let ``best match for DotNet Standard 1.1``()= - Paket.PlatformMatching.findBestMatch (["net20"; "net40"; "net45"; "net451"]|> List.map extractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_1))) + Paket.PlatformMatching.findBestMatch (["net20"; "net40"; "net45"; "net451"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_1))) |> shouldEqual (None) [] let ``best match for DotNet Standard 1.5``()= - Paket.PlatformMatching.findBestMatch (["net20"; "net40"; "net45"; "net451"]|> List.map extractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_5))) + Paket.PlatformMatching.findBestMatch (["net20"; "net40"; "net45"; "net451"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_5))) |> shouldEqual (None) [] let ``best match for net45``()= Paket.PlatformMatching.findBestMatch - (["netstandard10"; "netstandard11"; "netstandard12"; "netstandard13"; "netstandard14"; "netstandard15"; "netstandard16"]|> List.map extractPlatforms, + (["netstandard10"; "netstandard11"; "netstandard12"; "netstandard13"; "netstandard14"; "netstandard15"; "netstandard16"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetFramework(FrameworkVersion.V4_5))) - |> shouldEqual (Some (extractPlatforms "netstandard11")) + |> shouldEqual (Some (forceExtractPlatforms "netstandard11")) [] let ``best match for netstandard in portable``()= Paket.PlatformMatching.findBestMatch - (["portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_1))) |> shouldEqual (None) Paket.PlatformMatching.findBestMatch - (["portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_2))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wpa81")) Paket.PlatformMatching.findBestMatch - (["portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_3))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wpa81")) Paket.PlatformMatching.findBestMatch - (["portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_4))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wpa81")) Paket.PlatformMatching.findBestMatch - (["portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_5))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wpa81")) Paket.PlatformMatching.findBestMatch - (["portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_6))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wpa81")) [] let ``best match for netstandard, netstandard is preferred``()= Paket.PlatformMatching.findBestMatch - (["portable-win81+wpa81"; "netstandard1.3"]|> List.map extractPlatforms, + (["portable-win81+wpa81"; "netstandard1.3"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_2))) - |> shouldEqual (Some (extractPlatforms "portable-win81+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-win81+wpa81")) Paket.PlatformMatching.findBestMatch - (["portable-win81+wpa81"; "netstandard1.3"]|> List.map extractPlatforms, + (["portable-win81+wpa81"; "netstandard1.3"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_3))) - |> shouldEqual (Some (extractPlatforms "netstandard1.3")) + |> shouldEqual (Some (forceExtractPlatforms "netstandard1.3")) Paket.PlatformMatching.findBestMatch - (["portable-win81+wpa81"; "netstandard1.3"]|> List.map extractPlatforms, + (["portable-win81+wpa81"; "netstandard1.3"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_4))) - |> shouldEqual (Some (extractPlatforms "netstandard1.3")) + |> shouldEqual (Some (forceExtractPlatforms "netstandard1.3")) [] let ``best match for netstandard, use possible.``()= Paket.PlatformMatching.findBestMatch // Profile31 (supports netstandard1.0), Profile32 (supports netstandard1.2) - (["portable-netcore451+wp81"; "portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wp81"; "portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_0))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wp81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wp81")) Paket.PlatformMatching.findBestMatch // Profile31 (supports netstandard1.0), Profile32 (supports netstandard1.2) - (["portable-netcore451+wp81"; "portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wp81"; "portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_2))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wpa81")) Paket.PlatformMatching.findBestMatch // Profile31 (supports netstandard1.0), Profile32 (supports netstandard1.2) - (["portable-netcore451+wp81"; "portable-netcore451+wpa81"]|> List.map extractPlatforms, + (["portable-netcore451+wp81"; "portable-netcore451+wpa81"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_4))) - |> shouldEqual (Some (extractPlatforms "portable-netcore451+wpa81")) + |> shouldEqual (Some (forceExtractPlatforms "portable-netcore451+wpa81")) [] let ``make sure not all portable profiles match``()= // Not all portable profiles have a match. Paket.PlatformMatching.findBestMatch - (["portable-net403+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1"]|> List.map extractPlatforms, + (["portable-net45+win8"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetStandard(DotNetStandardVersion.V1_0))) |> shouldEqual (None) [] let ``best match for net451``()= Paket.PlatformMatching.findBestMatch - (["netstandard10"; "netstandard11"; "netstandard12"; "netstandard13"; "netstandard14"; "netstandard15"; "netstandard16"]|> List.map extractPlatforms, + (["netstandard10"; "netstandard11"; "netstandard12"; "netstandard13"; "netstandard14"; "netstandard15"; "netstandard16"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetFramework(FrameworkVersion.V4_5_1))) - |> shouldEqual (Some (extractPlatforms "netstandard12")) + |> shouldEqual (Some (forceExtractPlatforms "netstandard12")) [] let ``best match for net463``()= Paket.PlatformMatching.findBestMatch - (["netstandard10"; "netstandard11"; "netstandard12"; "netstandard13"; "netstandard14"; "netstandard15"; "netstandard16"]|> List.map extractPlatforms, + (["netstandard10"; "netstandard11"; "netstandard12"; "netstandard13"; "netstandard14"; "netstandard15"; "netstandard16"]|> List.map forceExtractPlatforms, SinglePlatform(DotNetFramework(FrameworkVersion.V4_6_3))) - |> shouldEqual (Some (extractPlatforms "netstandard16")) + |> shouldEqual (Some (forceExtractPlatforms "netstandard16")) diff --git a/tests/Paket.Tests/InstallModel/ProcessingSpecs.fs b/tests/Paket.Tests/InstallModel/ProcessingSpecs.fs index 51abf56392..d0496373d9 100644 --- a/tests/Paket.Tests/InstallModel/ProcessingSpecs.fs +++ b/tests/Paket.Tests/InstallModel/ProcessingSpecs.fs @@ -22,7 +22,7 @@ let ``should create empty model with net40, net45 ...``() = let targets = model.CompileLibFolders - |> List.map (fun folder -> folder.Targets) + |> List.map (fun folder -> folder.Targets |> Set.toList) |> List.concat targets |> shouldContain (SinglePlatform (DotNetFramework FrameworkVersion.V4)) @@ -32,7 +32,7 @@ let ``should create empty model with net40, net45 ...``() = let ``should understand net40 and net45``() = let model = emptymodel.AddReferences ([ @"..\Rx-Main\lib\net40\Rx.dll"; @"..\Rx-Main\lib\net45\Rx.dll" ] |> fromLegacyList @"..\Rx-Main\") - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain (@"..\Rx-Main\lib\net40\Rx.dll") model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_5)) |> Seq.map (fun f -> f.Path)|> shouldContain @"..\Rx-Main\lib\net45\Rx.dll" @@ -41,14 +41,14 @@ let ``should understand net40 and net45``() = let ``should understand lib in lib.dll``() = let model = emptymodel.AddReferences ([ @"..\FunScript.TypeScript\lib\net40\FunScript.TypeScript.Binding.lib.dll" ] |> fromLegacyList @"..\FunScript.TypeScript\") - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\FunScript.TypeScript\lib\net40\FunScript.TypeScript.Binding.lib.dll" [] let ``should understand libuv in runtimes``() = let model = emptymodel.AddReferences ([ @"..\Microsoft.AspNetCore.Server.Kestrel\runtimes\win7-x64\native\libuv.dll" ] |> fromLegacyList @"..\Microsoft.AspNetCore.Server.Kestrel\") - model.GetRuntimeLibraries RuntimeGraph.Empty (Rid.Of "win7-x64") (SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetRuntimeLibraries RuntimeGraph.Empty (Rid.Of "win7-x64") (SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun (r:RuntimeLibrary) -> r.Library.Path) |> shouldContain @"..\Microsoft.AspNetCore.Server.Kestrel\runtimes\win7-x64\native\libuv.dll" [] @@ -198,7 +198,7 @@ let ``should put _._ files into right buckets``() = model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V2)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Rx-Main\lib\net20\_._" - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Rx-Main\lib\net40\_._" [] @@ -248,7 +248,7 @@ let ``should install single client profile lib for everything``() = let model = emptymodel.AddReferences([ @"..\Castle.Core\lib\net40-client\Castle.Core.dll" ] |> fromLegacyList @"..\Castle.Core\") - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Castle.Core\lib\net40-client\Castle.Core.dll" model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Castle.Core\lib\net40-client\Castle.Core.dll" @@ -265,7 +265,7 @@ let ``should install net40 for client profile``() = model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V3_5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Newtonsoft.Json\lib\net35\Newtonsoft.Json.dll" - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Newtonsoft.Json\lib\net40\Newtonsoft.Json.dll" model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Newtonsoft.Json\lib\net40\Newtonsoft.Json.dll" @@ -281,8 +281,6 @@ let ``should install not use net40-full for client profile``() = |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Newtonsoft.Json\lib\net35\Newtonsoft.Json.dll" model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Newtonsoft.Json\lib\net40-full\Newtonsoft.Json.dll" - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) - |> Seq.map (fun f -> f.Path) |> shouldNotContain @"..\Newtonsoft.Json\lib\net40-full\Newtonsoft.Json.dll" [] let ``should handle lib install of Microsoft.Net.Http for .NET 4.5``() = @@ -327,7 +325,7 @@ let ``should handle lib install of Jint for NET >= 40 and SL >= 50``() = model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Jint\lib\portable-net40+sl50+win+wp80\Jint.dll" - model.GetLegacyReferences(SinglePlatform (Silverlight "v5.0")) + model.GetLegacyReferences(SinglePlatform (Silverlight SilverlightVersion.V5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Jint\lib\portable-net40+sl50+win+wp80\Jint.dll" model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V3_5)) @@ -387,11 +385,11 @@ let ``should not use portable-net40 if we have net40``() = @"..\Microsoft.Bcl\lib\portable-net40+sl4+win8\System.Runtime.dll" @"..\Microsoft.Bcl\lib\portable-net40+sl4+win8\System.Threading.Tasks.dll" ] |> fromLegacyList @"..\Microsoft.Bcl\") - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\net40\System.IO.dll" - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\net40\System.Runtime.dll" - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\net40\System.Threading.Tasks.dll" let profile41 = KnownTargetProfiles.FindPortableProfile "Profile41" @@ -423,7 +421,7 @@ let ``should handle lib install of NUnit 2.6 for windows 8``() = |> Seq.map (fun f -> f.Path) |> shouldContain @"..\NUnit\lib\nunit.framework.dll" model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\NUnit\lib\nunit.framework.dll" - model.GetLegacyReferences(SinglePlatform (Windows "v4.5")) + model.GetLegacyReferences(SinglePlatform (Windows WindowsVersion.V8)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\NUnit\lib\nunit.framework.dll" @@ -502,14 +500,14 @@ let ``should handle lib install of Microsoft.Net.Http 2.2.28``() = model.GetLegacyReferences(profile7) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Net.Http\lib\portable-net45+win8\System.Net.Http.Primitives.dll" - model.GetLegacyReferences(SinglePlatform (Windows "v4.5")) + model.GetLegacyReferences(SinglePlatform (Windows WindowsVersion.V8)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Net.Http\lib\win8\System.Net.Http.Extensions.dll" - model.GetLegacyReferences(SinglePlatform (Windows "v4.5")) + model.GetLegacyReferences(SinglePlatform (Windows WindowsVersion.V8)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Net.Http\lib\win8\System.Net.Http.Primitives.dll" - model.GetLegacyReferences(SinglePlatform (WindowsPhoneApp "v8.1")) + model.GetLegacyReferences(SinglePlatform (WindowsPhoneApp WindowsPhoneAppVersion.V8_1)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Net.Http\lib\wpa81\System.Net.Http.Extensions.dll" - model.GetLegacyReferences(SinglePlatform (WindowsPhoneApp "v8.1")) + model.GetLegacyReferences(SinglePlatform (WindowsPhoneApp WindowsPhoneAppVersion.V8_1)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Net.Http\lib\wpa81\System.Net.Http.Primitives.dll" @@ -561,9 +559,9 @@ let ``should handle lib install of MicrosoftBcl``() = model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_5)) |> shouldBeEmpty model.GetLegacyReferences(SinglePlatform MonoAndroid) |> shouldBeEmpty model.GetLegacyReferences(SinglePlatform MonoTouch) |> shouldBeEmpty - model.GetLegacyReferences(SinglePlatform (Windows "v4.5")) |> shouldBeEmpty - model.GetLegacyReferences(SinglePlatform (WindowsPhoneSilverlight "v8.0")) |> shouldBeEmpty - model.GetLegacyReferences(SinglePlatform (WindowsPhoneApp "v8.1")) |> shouldBeEmpty + model.GetLegacyReferences(SinglePlatform (Windows WindowsVersion.V8)) |> shouldBeEmpty + model.GetLegacyReferences(SinglePlatform (WindowsPhone WindowsPhoneVersion.V8)) |> shouldBeEmpty + model.GetLegacyReferences(SinglePlatform (WindowsPhoneApp WindowsPhoneAppVersion.V8_1)) |> shouldBeEmpty model.GetLegacyReferences(KnownTargetProfiles.FindPortableProfile "Profile44") |> shouldBeEmpty model.GetLegacyReferences(KnownTargetProfiles.FindPortableProfile "Profile151") |> shouldBeEmpty @@ -575,25 +573,25 @@ let ``should handle lib install of MicrosoftBcl``() = model.GetLegacyReferences(profile41) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\portable-net40+sl4+win8\System.Threading.Tasks.dll" - model.GetLegacyReferences(SinglePlatform (Silverlight "v4.0")) + model.GetLegacyReferences(SinglePlatform (Silverlight SilverlightVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl4\System.IO.dll" - model.GetLegacyReferences(SinglePlatform (Silverlight "v4.0")) + model.GetLegacyReferences(SinglePlatform (Silverlight SilverlightVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl4\System.Runtime.dll" - model.GetLegacyReferences(SinglePlatform (Silverlight "v4.0")) + model.GetLegacyReferences(SinglePlatform (Silverlight SilverlightVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl4\System.Threading.Tasks.dll" - model.GetLegacyReferences(SinglePlatform (WindowsPhoneSilverlight "v7.1")) + model.GetLegacyReferences(SinglePlatform (WindowsPhone WindowsPhoneVersion.V7_5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl4-windowsphone71\System.IO.dll" - model.GetLegacyReferences(SinglePlatform (WindowsPhoneSilverlight "v7.1")) + model.GetLegacyReferences(SinglePlatform (WindowsPhone WindowsPhoneVersion.V7_5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl4-windowsphone71\System.Runtime.dll" - model.GetLegacyReferences(SinglePlatform (WindowsPhoneSilverlight "v7.1")) + model.GetLegacyReferences(SinglePlatform (WindowsPhone WindowsPhoneVersion.V7_5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl4-windowsphone71\System.Threading.Tasks.dll" - model.GetLegacyReferences(SinglePlatform (Silverlight "v5.0")) + model.GetLegacyReferences(SinglePlatform (Silverlight SilverlightVersion.V5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl5\System.IO.dll" - model.GetLegacyReferences(SinglePlatform (Silverlight "v5.0")) + model.GetLegacyReferences(SinglePlatform (Silverlight SilverlightVersion.V5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl5\System.Runtime.dll" - model.GetLegacyReferences(SinglePlatform (Silverlight "v5.0")) + model.GetLegacyReferences(SinglePlatform (Silverlight SilverlightVersion.V5)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\Microsoft.Bcl\lib\sl5\System.Threading.Tasks.dll" @@ -738,7 +736,7 @@ let ``should filter .NET 4.0 dlls for System.Net.Http 2.2.8``() = let model = InstallModel.CreateFromLibs (PackageName "System.Net.Http", SemVer.Parse "2.2.8", - [ ], + FrameworkRestriction.NoRestriction, [ @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Extensions.dll" @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Primitives.dll" @"..\Microsoft.Net.Http\lib\monotouch\System.Net.Http.Extensions.dll" @@ -773,7 +771,7 @@ let ``should filter .NET 4.5 dlls for System.Net.Http 2.2.8``() = let model = InstallModel.CreateFromLibs (PackageName "System.Net.Http", SemVer.Parse "2.2.8", - [ ], + FrameworkRestriction.NoRestriction, [ @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Extensions.dll" @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Primitives.dll" @"..\Microsoft.Net.Http\lib\monotouch\System.Net.Http.Extensions.dll" @@ -807,7 +805,7 @@ let ``should filter properly when portables are available``() = let model = InstallModel.CreateFromLibs (PackageName "Newtonsoft.Json", SemVer.Parse "8.0.3", - [ ], + FrameworkRestriction.NoRestriction, [ @"..\Newtonsoft.Json\lib\net20\Newtonsoft.Json.dll" @"..\Newtonsoft.Json\lib\net35\Newtonsoft.Json.dll" @"..\Newtonsoft.Json\lib\net40\Newtonsoft.Json.dll" @@ -816,7 +814,7 @@ let ``should filter properly when portables are available``() = @"..\Newtonsoft.Json\lib\portable-net45+wp80+win8+wpa81+dnxcore50\Newtonsoft.Json.dll" ] |> fromLegacyList @"..\Newtonsoft.Json\", [], [], Nuspec.All) let filteredModel = - model.ApplyFrameworkRestrictions ( [ FrameworkRestriction.Exactly (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_5) ] ) + model.ApplyFrameworkRestrictions (FrameworkRestriction.Exactly (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_5)) filteredModel.GetLegacyReferences(SinglePlatform(DotNetFramework(FrameworkVersion.V4_5))) |> Seq.map (fun f -> f.Path) @@ -832,11 +830,11 @@ let ``should keep net20 if nothing better is available``() = let model = InstallModel.CreateFromLibs (PackageName "EPPlus", SemVer.Parse "4.0.5", - [ ], + FrameworkRestriction.NoRestriction, [ @"..\EPPlus\lib\net20\EPPlus.dll" ] |> fromLegacyList @"..\EPPlus\", [], [], Nuspec.All) let filteredModel = - model.ApplyFrameworkRestrictions ( [ FrameworkRestriction.Exactly (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_6_1) ] ) + model.ApplyFrameworkRestrictions (FrameworkRestriction.Exactly (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_6_1)) filteredModel.GetLegacyReferences(SinglePlatform(DotNetFramework(FrameworkVersion.V4_6_1))) |> Seq.map (fun f -> f.Path) @@ -853,12 +851,12 @@ let ``prefer net20 over empty folder``() = let model = InstallModel.CreateFromLibs (PackageName "EPPlus", SemVer.Parse "4.0.5", - [ ], + FrameworkRestriction.NoRestriction, [ @"..\EPPlus\lib\readme.txt" @"..\EPPlus\lib\net20\EPPlus.dll" ] |> fromLegacyList @"..\EPPlus\", [], [], Nuspec.All) let filteredModel = - model.ApplyFrameworkRestrictions ( [ FrameworkRestriction.Exactly (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_6_1) ] ) + model.ApplyFrameworkRestrictions (FrameworkRestriction.Exactly (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_6_1)) filteredModel.GetLegacyReferences(SinglePlatform(DotNetFramework(FrameworkVersion.V4_6_1))) |> Seq.map (fun f -> f.Path) @@ -871,7 +869,7 @@ let ``prefer net20 over empty folder``() = [] let ``should understand xamarinios``() = - let model = emptymodel.ApplyFrameworkRestrictions ([FrameworkRestriction.Exactly (XamariniOS)]) + let model = emptymodel.ApplyFrameworkRestrictions (FrameworkRestriction.Exactly (XamariniOS)) let model = model.AddReferences ([ @"..\FSharp.Core\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll" ] |> fromLegacyList @"..\FSharp.Core\") model.GetLegacyReferences(SinglePlatform (XamariniOS)) diff --git a/tests/Paket.Tests/InstallModel/Xml/CodeCracker.fs b/tests/Paket.Tests/InstallModel/Xml/CodeCracker.fs index 8f191e0649..12e8057042 100644 --- a/tests/Paket.Tests/InstallModel/Xml/CodeCracker.fs +++ b/tests/Paket.Tests/InstallModel/Xml/CodeCracker.fs @@ -3,6 +3,7 @@ open FsUnit open NUnit.Framework open Paket +open Paket.Requirements open Paket.Domain open Paket.TestHelpers @@ -23,7 +24,7 @@ let expectedCsharp = """ let ``should generate Xml for codecracker.CSharp``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "codecracker.CSharp", SemVer.Parse "1.0.0-rc2", [], + InstallModel.CreateFromLibs(PackageName "codecracker.CSharp", SemVer.Parse "1.0.0-rc2", FrameworkRestriction.NoRestriction, [], [], [ @@ -45,7 +46,7 @@ let ``should generate Xml for codecracker.CSharp``() = let ``should generate Xml for codecracker.CSharp in VisualBasic project``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "codecracker.CSharp", SemVer.Parse "1.0.0-rc2", [], + InstallModel.CreateFromLibs(PackageName "codecracker.CSharp", SemVer.Parse "1.0.0-rc2", FrameworkRestriction.NoRestriction, [], [], [ @@ -76,7 +77,7 @@ let expectedVb = """ let ``should generate Xml for codecracker.VisualBasic``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "codecracker.VisualBasic", SemVer.Parse "1.0.0-rc2", [], + InstallModel.CreateFromLibs(PackageName "codecracker.VisualBasic", SemVer.Parse "1.0.0-rc2", FrameworkRestriction.NoRestriction, [], [], [ diff --git a/tests/Paket.Tests/InstallModel/Xml/EmptyLibs.fs b/tests/Paket.Tests/InstallModel/Xml/EmptyLibs.fs index 3a69904a96..670258c47e 100644 --- a/tests/Paket.Tests/InstallModel/Xml/EmptyLibs.fs +++ b/tests/Paket.Tests/InstallModel/Xml/EmptyLibs.fs @@ -18,7 +18,7 @@ let expected = """ let ``should generate Xml for framework references and empty libs``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "TempPkg", SemVer.Parse "0.1", [], + InstallModel.CreateFromLibs(PackageName "TempPkg", SemVer.Parse "0.1", FrameworkRestriction.NoRestriction, [ ], [], [], diff --git a/tests/Paket.Tests/InstallModel/Xml/FSharp.Data.SqlClient.fs b/tests/Paket.Tests/InstallModel/Xml/FSharp.Data.SqlClient.fs index 16e2709309..1ecead7d76 100644 --- a/tests/Paket.Tests/InstallModel/Xml/FSharp.Data.SqlClient.fs +++ b/tests/Paket.Tests/InstallModel/Xml/FSharp.Data.SqlClient.fs @@ -10,7 +10,7 @@ open System.IO let expected = """ - + True @@ -32,7 +32,7 @@ let ``should generate Xml for FSharp.Data.SqlClient 1.4.4``() = if not isMonoRuntime then // TODO - figure out why nuspec content is different on Mono ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "FSharp.Data.SqlClient", SemVer.Parse "1.4.4", [], + InstallModel.CreateFromLibs(PackageName "FSharp.Data.SqlClient", SemVer.Parse "1.4.4", FrameworkRestriction.NoRestriction, [ @"..\FSharp.Data.SqlClient\lib\net40\FSharp.Data.SqlClient.dll" @"..\FSharp.Data.SqlClient\lib\net40\FSharp.Data.SqlClient.pdb" @"..\FSharp.Data.SqlClient\lib\net40\FSharp.Data.SqlClient.XML" diff --git a/tests/Paket.Tests/InstallModel/Xml/Fantomas.fs b/tests/Paket.Tests/InstallModel/Xml/Fantomas.fs index 73a70a84a1..c482357eab 100644 --- a/tests/Paket.Tests/InstallModel/Xml/Fantomas.fs +++ b/tests/Paket.Tests/InstallModel/Xml/Fantomas.fs @@ -22,7 +22,7 @@ let fromLegacyList = Paket.InstallModel.ProcessingSpecs.fromLegacyList let ``should generate Xml for Fantomas 1.5``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList @"..\Fantomas\", @@ -60,7 +60,7 @@ let fullDoc = """ let ``should generate full Xml for Fantomas 1.5``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList @"..\Fantomas\", @@ -82,7 +82,7 @@ let ``should generate full Xml for Fantomas 1.5``() = let ``should not generate full Xml for Fantomas 1.5 if not referenced``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList @"..\Fantomas\", @@ -119,7 +119,7 @@ let fullDocWithRefernceCondition = """ let ``should generate full Xml with reference condition for Fantomas 1.5``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList @"..\Fantomas\", @@ -163,7 +163,7 @@ let ``should generate full Xml with reference condition and framework restrictio let model = InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [ FrameworkRestriction.Exactly (FrameworkIdentifier.XamariniOS) - FrameworkRestriction.Exactly (FrameworkIdentifier.MonoAndroid)], + FrameworkRestriction.Exactly (FrameworkIdentifier.MonoAndroid)] |> makeOrList |> getExplicitRestriction, [ @"..\Fantomas\lib\portable-net45+win8\FantomasLib.dll" ] |> fromLegacyList @"..\Fantomas\", [], [], diff --git a/tests/Paket.Tests/InstallModel/Xml/FantomasLib.fs b/tests/Paket.Tests/InstallModel/Xml/FantomasLib.fs index 1e4e5111b8..8cdeaf204b 100644 --- a/tests/Paket.Tests/InstallModel/Xml/FantomasLib.fs +++ b/tests/Paket.Tests/InstallModel/Xml/FantomasLib.fs @@ -20,7 +20,7 @@ let expected = """ let ``should generate Xml for Fantomas 1.5``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\Lib\FantomasLib.dll" @"..\Fantomas\Lib\FSharp.Core.dll" @"..\Fantomas\Lib\Fantomas.exe" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\Fantomas\", diff --git a/tests/Paket.Tests/InstallModel/Xml/Fuchu.fs b/tests/Paket.Tests/InstallModel/Xml/Fuchu.fs index 26b83b2df0..53e030f02a 100644 --- a/tests/Paket.Tests/InstallModel/Xml/Fuchu.fs +++ b/tests/Paket.Tests/InstallModel/Xml/Fuchu.fs @@ -20,7 +20,7 @@ let expected = """ let ``should generate Xml for Fuchu 0.4``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fuchu", SemVer.Parse "0.4.0", [], + InstallModel.CreateFromLibs(PackageName "Fuchu", SemVer.Parse "0.4.0", FrameworkRestriction.NoRestriction, [ @"..\Fuchu\lib\Fuchu.dll" @"..\Fuchu\lib\Fuchu.XML" @"..\Fuchu\lib\Fuchu.pdb" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\Fuchu\", diff --git a/tests/Paket.Tests/InstallModel/Xml/GitInfoPlanter.fs b/tests/Paket.Tests/InstallModel/Xml/GitInfoPlanter.fs index d42d35698a..85d3de7524 100644 --- a/tests/Paket.Tests/InstallModel/Xml/GitInfoPlanter.fs +++ b/tests/Paket.Tests/InstallModel/Xml/GitInfoPlanter.fs @@ -20,7 +20,7 @@ let expectedPropertyNodes = """ let ``should generate Xml for GitInfoPlanter2.0.0``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "GitInfoPlanter", SemVer.Parse "0.21", [], + InstallModel.CreateFromLibs(PackageName "GitInfoPlanter", SemVer.Parse "0.21", FrameworkRestriction.NoRestriction, [ ], [ @"..\GitInfoPlanter\build\GitInfoPlanter.targets" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\GitInfoPlanter\", diff --git a/tests/Paket.Tests/InstallModel/Xml/LibGit2Sharp.fs b/tests/Paket.Tests/InstallModel/Xml/LibGit2Sharp.fs index 245e87531f..8192b1336c 100644 --- a/tests/Paket.Tests/InstallModel/Xml/LibGit2Sharp.fs +++ b/tests/Paket.Tests/InstallModel/Xml/LibGit2Sharp.fs @@ -9,7 +9,7 @@ open Paket.Requirements let expectedReferenceNodes = """ - + ..\..\..\LibGit2Sharp\lib\net40\LibGit2Sharp.dll @@ -22,7 +22,7 @@ let expectedReferenceNodes = """ let expectedPropertyDefinitionNodes = """ - + <__paket__LibGit2Sharp_props>net40\LibGit2Sharp @@ -36,7 +36,7 @@ let expectedPropertyNodes = """ let ``should generate Xml for LibGit2Sharp 2.0.0``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "LibGit2Sharp", SemVer.Parse "0.21", [], + InstallModel.CreateFromLibs(PackageName "LibGit2Sharp", SemVer.Parse "0.21", FrameworkRestriction.NoRestriction, [ @"..\LibGit2Sharp\lib\net40\LibGit2Sharp.dll" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\LibGit2Sharp\", [ @"..\LibGit2Sharp\build\net40\LibGit2Sharp.props" ] @@ -44,7 +44,7 @@ let ``should generate Xml for LibGit2Sharp 2.0.0``() = [], Nuspec.All) - model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4_Client)) + model.GetLegacyReferences(SinglePlatform (DotNetFramework FrameworkVersion.V4)) |> Seq.map (fun f -> f.Path) |> shouldContain @"..\LibGit2Sharp\lib\net40\LibGit2Sharp.dll" let ctx = ProjectFile.TryLoad("./ProjectFile/TestData/Empty.fsprojtest").Value.GenerateXml(model, System.Collections.Generic.HashSet<_>(),Map.empty,Some true,true,KnownTargetProfiles.AllProfiles,None) diff --git a/tests/Paket.Tests/InstallModel/Xml/ManualNodes.fs b/tests/Paket.Tests/InstallModel/Xml/ManualNodes.fs index 7a0c03a992..4663a6fea5 100644 --- a/tests/Paket.Tests/InstallModel/Xml/ManualNodes.fs +++ b/tests/Paket.Tests/InstallModel/Xml/ManualNodes.fs @@ -13,7 +13,7 @@ let fromLegacyList = Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\Fant let ``should find custom nodes in doc``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList, @@ -28,7 +28,7 @@ let ``should find custom nodes in doc``() = let ``should find custom Paket nodes in doc``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList, @@ -44,7 +44,7 @@ let ``should find custom Paket nodes in doc``() = let ``should not find custom nodes if there are none``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList, @@ -60,7 +60,7 @@ let ``should not find custom nodes if there are none``() = let ``should delete custom nodes if there are some``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Fantomas", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Fantomas\lib\FantomasLib.dll" @"..\Fantomas\lib\FSharp.Core.dll" @"..\Fantomas\lib\Fantomas.exe" ] |> fromLegacyList, diff --git a/tests/Paket.Tests/InstallModel/Xml/Microsoft.Bcl.Build.fs b/tests/Paket.Tests/InstallModel/Xml/Microsoft.Bcl.Build.fs index 8307878950..a909cbfccd 100644 --- a/tests/Paket.Tests/InstallModel/Xml/Microsoft.Bcl.Build.fs +++ b/tests/Paket.Tests/InstallModel/Xml/Microsoft.Bcl.Build.fs @@ -4,13 +4,14 @@ open Paket open NUnit.Framework open FsUnit open Paket.Domain +open Paket.Requirements open Paket.TestHelpers [] let ``should not install targets node for Microsoft.Bcl.Build``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Microsoft.Bcl.Build", SemVer.Parse "1.0.21", [], + InstallModel.CreateFromLibs(PackageName "Microsoft.Bcl.Build", SemVer.Parse "1.0.21", FrameworkRestriction.NoRestriction, [ ], [ @"..\Microsoft.Bcl.Build\build\Microsoft.Bcl.Build.Tasks.dll"; @"..\Microsoft.Bcl.Build\build\Microsoft.Bcl.Build.targets" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\Microsoft.Bcl.Build\", diff --git a/tests/Paket.Tests/InstallModel/Xml/Microsoft.CodeAnalysis.Analyzers.fs b/tests/Paket.Tests/InstallModel/Xml/Microsoft.CodeAnalysis.Analyzers.fs index 1d6302cb7a..d0cc3ce7df 100644 --- a/tests/Paket.Tests/InstallModel/Xml/Microsoft.CodeAnalysis.Analyzers.fs +++ b/tests/Paket.Tests/InstallModel/Xml/Microsoft.CodeAnalysis.Analyzers.fs @@ -3,6 +3,7 @@ open FsUnit open NUnit.Framework open Paket +open Paket.Requirements open Paket.Constants open Paket.Domain open Paket.TestHelpers @@ -10,7 +11,7 @@ open System.Text open System.IO let model = - InstallModel.CreateFromLibs(PackageName "Microsoft.CodeAnalysis.Analyzers", SemVer.Parse "1.0.0", [], + InstallModel.CreateFromLibs(PackageName "Microsoft.CodeAnalysis.Analyzers", SemVer.Parse "1.0.0", FrameworkRestriction.NoRestriction, [], [], [ @@ -64,7 +65,7 @@ let ``should generate Xml for RefactoringEssentials in VisualBasic project``() = |> shouldEqual (normalizeXml expectedVb) let oldModel = - InstallModel.CreateFromLibs(PackageName "Microsoft.CodeAnalysis.Analyzers", SemVer.Parse "1.0.0-rc2", [], + InstallModel.CreateFromLibs(PackageName "Microsoft.CodeAnalysis.Analyzers", SemVer.Parse "1.0.0-rc2", FrameworkRestriction.NoRestriction, [], [], [], // Analyzers weren't in the correct folder and won't be found for this version diff --git a/tests/Paket.Tests/InstallModel/Xml/Plossum.fs b/tests/Paket.Tests/InstallModel/Xml/Plossum.fs index fcb895fa3d..2d7673229c 100644 --- a/tests/Paket.Tests/InstallModel/Xml/Plossum.fs +++ b/tests/Paket.Tests/InstallModel/Xml/Plossum.fs @@ -9,7 +9,7 @@ open Paket.Requirements let expected = """ - + ..\..\..\Plossum.CommandLine\lib\net40\Plossum CommandLine.dll @@ -24,7 +24,7 @@ let expected = """ let ``should generate Xml for Plossum``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Plossum.CommandLine", SemVer.Parse "1.5.0", [], + InstallModel.CreateFromLibs(PackageName "Plossum.CommandLine", SemVer.Parse "1.5.0", FrameworkRestriction.NoRestriction, [ @"..\Plossum.CommandLine\lib\net40\Plossum CommandLine.dll" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\Plossum.CommandLine\", [], diff --git a/tests/Paket.Tests/InstallModel/Xml/RefactoringEssentials.fs b/tests/Paket.Tests/InstallModel/Xml/RefactoringEssentials.fs index 76eaefaf69..b9746c6d7c 100644 --- a/tests/Paket.Tests/InstallModel/Xml/RefactoringEssentials.fs +++ b/tests/Paket.Tests/InstallModel/Xml/RefactoringEssentials.fs @@ -3,6 +3,7 @@ open FsUnit open NUnit.Framework open Paket +open Paket.Requirements open Paket.Domain open Paket.TestHelpers @@ -17,7 +18,7 @@ let expected = """ let ``should generate Xml for RefactoringEssentials in CSharp project``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "RefactoringEssentials", SemVer.Parse "1.2.0", [], + InstallModel.CreateFromLibs(PackageName "RefactoringEssentials", SemVer.Parse "1.2.0", FrameworkRestriction.NoRestriction, [], [], [ @@ -37,7 +38,7 @@ let ``should generate Xml for RefactoringEssentials in CSharp project``() = let ``should generate Xml for RefactoringEssentials in VisualBasic project``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "RefactoringEssentials", SemVer.Parse "1.2.0", [], + InstallModel.CreateFromLibs(PackageName "RefactoringEssentials", SemVer.Parse "1.2.0", FrameworkRestriction.NoRestriction, [], [], [ diff --git a/tests/Paket.Tests/InstallModel/Xml/RxXaml.fs b/tests/Paket.Tests/InstallModel/Xml/RxXaml.fs index 8e29541839..63f428a7c4 100644 --- a/tests/Paket.Tests/InstallModel/Xml/RxXaml.fs +++ b/tests/Paket.Tests/InstallModel/Xml/RxXaml.fs @@ -9,7 +9,7 @@ open Paket.Requirements let expected = """ - + True @@ -63,7 +63,7 @@ let expected = """ - + True @@ -90,7 +90,7 @@ let expected = """ let ``should generate Xml for Rx-XAML 2.2.4 with correct framework assembly references``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "Rx-XAML", SemVer.Parse "2.2.4", [], + InstallModel.CreateFromLibs(PackageName "Rx-XAML", SemVer.Parse "2.2.4", FrameworkRestriction.NoRestriction, [ @"..\Rx-XAML\lib\net40\System.Reactive.Windows.Threading.dll" @"..\Rx-XAML\lib\net45\System.Reactive.Windows.Threading.dll" @"..\Rx-XAML\lib\portable-win81+wpa81\System.Reactive.Windows.Threading.dll" @@ -108,10 +108,10 @@ let ``should generate Xml for Rx-XAML 2.2.4 with correct framework assembly refe LicenseUrl = "" IsDevelopmentDependency = false FrameworkAssemblyReferences = - [{ AssemblyName = "WindowsBase"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework FrameworkVersion.V4_5)] } - { AssemblyName = "WindowsBase"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework FrameworkVersion.V4)] } - { AssemblyName = "System.Windows"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(Silverlight "v5.0")] } - { AssemblyName = "System.Windows"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(WindowsPhoneSilverlight "v7.1")] }]}) + [{ AssemblyName = "WindowsBase"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(DotNetFramework FrameworkVersion.V4_5)] } + { AssemblyName = "WindowsBase"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(DotNetFramework FrameworkVersion.V4)] } + { AssemblyName = "System.Windows"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(Silverlight SilverlightVersion.V5)] } + { AssemblyName = "System.Windows"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(WindowsPhone WindowsPhoneVersion.V7_5)] }]}) let ctx = ProjectFile.TryLoad("./ProjectFile/TestData/Empty.fsprojtest").Value.GenerateXml(model, System.Collections.Generic.HashSet<_>(),Map.empty,Some true,true,KnownTargetProfiles.AllProfiles,None) let currentXml = ctx.ChooseNodes.Head.OuterXml |> normalizeXml diff --git a/tests/Paket.Tests/InstallModel/Xml/SQLite.fs b/tests/Paket.Tests/InstallModel/Xml/SQLite.fs index cbdcddb89d..fd577deff0 100644 --- a/tests/Paket.Tests/InstallModel/Xml/SQLite.fs +++ b/tests/Paket.Tests/InstallModel/Xml/SQLite.fs @@ -22,7 +22,7 @@ let expectedReferenceNodes = """ - + ..\..\..\System.Data.SQLite.Core\lib\net40\System.Data.SQLite.dll @@ -59,7 +59,7 @@ let expectedPropertyDefinitionNodes = """ <__paket__System_Data_SQLite_Core_targets>net20\System.Data.SQLite.Core - + <__paket__System_Data_SQLite_Core_targets>net40\System.Data.SQLite.Core @@ -83,11 +83,11 @@ let expectedPropertyNodes = """ let ``can get supported target profile``()= let profiles = ["net20"; "net40"; "net45"; "net451"; "netstandard14" ] - |> List.map extractPlatforms + |> List.map forceExtractPlatforms |> PlatformMatching.getSupportedTargetProfiles let folder = profiles |> Seq.item 2 - folder.Key |> shouldEqual (extractPlatforms "net45") - folder.Value |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] + folder.Key |> shouldEqual (forceExtractPlatforms "net45") + folder.Value |> Set.toList |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] [] let ``should extract lib folders for SQLite``() = @@ -118,7 +118,7 @@ let ``should calc lib folders for SQLite``() = let model = calcLegacyReferenceLibFolders libs let folder = model |> List.item 2 - folder.Targets |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] + folder.Targets |> Set.toList |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] [] @@ -136,13 +136,13 @@ let ``should init model for SQLite``() = let libFolder = model.CompileLibFolders |> List.item 2 libFolder.Path.Name |> shouldEqual "net45" - libFolder.Targets |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] + libFolder.Targets |> Set.toList |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] [] let ``should generate model for SQLite``() = let model = - InstallModel.CreateFromLibs(PackageName "System.Data.SQLite.Core", SemVer.Parse "3.8.2", [], + InstallModel.CreateFromLibs(PackageName "System.Data.SQLite.Core", SemVer.Parse "3.8.2", FrameworkRestriction.NoRestriction, [ @"..\System.Data.SQLite.Core\lib\net20\System.Data.SQLite.dll" @"..\System.Data.SQLite.Core\lib\net40\System.Data.SQLite.dll" @"..\System.Data.SQLite.Core\lib\net45\System.Data.SQLite.dll" @@ -158,13 +158,13 @@ let ``should generate model for SQLite``() = let libFolder = model.CompileLibFolders |> List.item 2 libFolder.Path.Name |> shouldEqual "net45" - libFolder.Targets |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] + libFolder.Targets |> Set.toList |> shouldEqual [SinglePlatform (DotNetFramework FrameworkVersion.V4_5)] [] let ``should generate Xml for SQLite``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "System.Data.SQLite.Core", SemVer.Parse "3.8.2", [], + InstallModel.CreateFromLibs(PackageName "System.Data.SQLite.Core", SemVer.Parse "3.8.2", FrameworkRestriction.NoRestriction, [ @"..\System.Data.SQLite.Core\lib\net20\System.Data.SQLite.dll" @"..\System.Data.SQLite.Core\lib\net40\System.Data.SQLite.dll" @"..\System.Data.SQLite.Core\lib\net45\System.Data.SQLite.dll" diff --git a/tests/Paket.Tests/InstallModel/Xml/StyleCop.MSBuild.fs b/tests/Paket.Tests/InstallModel/Xml/StyleCop.MSBuild.fs index 1bb145d462..a4a63f7b2f 100644 --- a/tests/Paket.Tests/InstallModel/Xml/StyleCop.MSBuild.fs +++ b/tests/Paket.Tests/InstallModel/Xml/StyleCop.MSBuild.fs @@ -17,7 +17,7 @@ let expectedPropertyNodes = """ let ``should generate Xml for StyleCop.MSBuild``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "StyleCop.MSBuild", SemVer.Parse "4.7.49.1", [],[], + InstallModel.CreateFromLibs(PackageName "StyleCop.MSBuild", SemVer.Parse "4.7.49.1", FrameworkRestriction.NoRestriction,[], [ @"..\StyleCop.MSBuild\build\StyleCop.MSBuild.Targets" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\StyleCop.MSBuild\", [], Nuspec.All) diff --git a/tests/Paket.Tests/InstallModel/Xml/System.Security.Cryptography.Algorithms.fs b/tests/Paket.Tests/InstallModel/Xml/System.Security.Cryptography.Algorithms.fs index cb5741535c..88e65b5daa 100644 --- a/tests/Paket.Tests/InstallModel/Xml/System.Security.Cryptography.Algorithms.fs +++ b/tests/Paket.Tests/InstallModel/Xml/System.Security.Cryptography.Algorithms.fs @@ -3,6 +3,7 @@ open FsUnit open NUnit.Framework open Paket +open Paket.Requirements open Paket.Domain open Paket.TestHelpers @@ -68,7 +69,7 @@ let expected = """ let ``should generate Xml for System.Security.Cryptography.Algorithms in CSharp project``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "System.Security.Cryptography.Algorithms", SemVer.Parse "1.2.0", [], + InstallModel.CreateFromLibs(PackageName "System.Security.Cryptography.Algorithms", SemVer.Parse "1.2.0", FrameworkRestriction.NoRestriction, [ @"..\System.Security.Cryptography.Algorithms\lib\net46\System.Security.Cryptography.Algorithms.dll" @"..\System.Security.Cryptography.Algorithms\lib\net461\System.Security.Cryptography.Algorithms.dll" @"..\System.Security.Cryptography.Algorithms\lib\net463\System.Security.Cryptography.Algorithms.dll" @@ -97,4 +98,5 @@ let ``should generate Xml for System.Security.Cryptography.Algorithms in CSharp ctx.ChooseNodes |> (fun n -> n.Head.OuterXml) |> normalizeXml - result |> shouldEqual (normalizeXml expected) + let expectedXml = normalizeXml expected + result |> shouldEqual expectedXml diff --git a/tests/Paket.Tests/InstallModel/Xml/System.Spatial.fs b/tests/Paket.Tests/InstallModel/Xml/System.Spatial.fs index cda2855da0..b04aa4757b 100644 --- a/tests/Paket.Tests/InstallModel/Xml/System.Spatial.fs +++ b/tests/Paket.Tests/InstallModel/Xml/System.Spatial.fs @@ -9,7 +9,7 @@ open Paket.Requirements let expected = """ - + ..\..\..\System.Spatial\lib\net40\System.Spatial.dll @@ -33,7 +33,7 @@ let expected = """ let ``should generate Xml for System.Spatial``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "System.Spatial", SemVer.Parse "5.6.3", [], + InstallModel.CreateFromLibs(PackageName "System.Spatial", SemVer.Parse "5.6.3", FrameworkRestriction.NoRestriction, [ @"..\System.Spatial\lib\net40\System.Spatial.dll" @"..\System.Spatial\lib\net40\de\System.Spatial.resources.dll" @"..\System.Spatial\lib\net40\es\System.Spatial.resources.dll" diff --git a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttp.fs b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttp.fs index 57a4ae51e8..49f7b30a96 100644 --- a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttp.fs +++ b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttp.fs @@ -37,7 +37,7 @@ let expected = """ - + ..\..\..\Microsoft.Net.Http\lib\net40\System.Net.Http.dll @@ -75,7 +75,7 @@ let expected = """ - + ..\..\..\Microsoft.Net.Http\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll @@ -153,10 +153,11 @@ let expected = """ """ [] +[] let ``should generate Xml for System.Net.Http 2.2.8``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", [], + InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", FrameworkRestriction.NoRestriction, [ @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Extensions.dll" @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Primitives.dll" diff --git a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpForNet4.fs b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpForNet4.fs index 45fb5b0482..239758ed4e 100644 --- a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpForNet4.fs +++ b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpForNet4.fs @@ -39,7 +39,7 @@ let expected = """ let ``should generate Xml for System.Net.Http 2.2.8``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4))], + InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4)), [ @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Extensions.dll" @"..\Microsoft.Net.Http\lib\monoandroid\System.Net.Http.Primitives.dll" diff --git a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithExistingFrameworkReferences.fs b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithExistingFrameworkReferences.fs index 7b3e354817..5c49ab1dbf 100644 --- a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithExistingFrameworkReferences.fs +++ b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithExistingFrameworkReferences.fs @@ -9,7 +9,7 @@ open Paket.Requirements let expected = """ - + ..\..\..\Microsoft.Net.Http\lib\net40\System.Net.Http.dll @@ -51,7 +51,7 @@ let expected = """ let ``should generate Xml for System.Net.Http 2.2.8``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", [], + InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", FrameworkRestriction.NoRestriction, [ @"..\Microsoft.Net.Http\lib\net40\System.Net.Http.dll" @"..\Microsoft.Net.Http\lib\net40\System.Net.Http.Extensions.dll" @"..\Microsoft.Net.Http\lib\net40\System.Net.Http.Primitives.dll" @@ -69,8 +69,8 @@ let ``should generate Xml for System.Net.Http 2.2.8``() = LicenseUrl = "" IsDevelopmentDependency = false FrameworkAssemblyReferences = - [{ AssemblyName = "System.Net.Http"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] } - { AssemblyName = "System.Net.Http.WebRequest"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] }]}) + [{ AssemblyName = "System.Net.Http"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] } + { AssemblyName = "System.Net.Http.WebRequest"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] }]}) let ctx = ProjectFile.TryLoad("./ProjectFile/TestData/FrameworkAssemblies.fsprojtest").Value.GenerateXml(model, System.Collections.Generic.HashSet<_>(),Map.empty,Some true,true,KnownTargetProfiles.AllProfiles,None) let currentXML = ctx.ChooseNodes.Head.OuterXml |> normalizeXml diff --git a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithFrameworkReferences.fs b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithFrameworkReferences.fs index f24880ef43..0267226bd4 100644 --- a/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithFrameworkReferences.fs +++ b/tests/Paket.Tests/InstallModel/Xml/SystemNetHttpWithFrameworkReferences.fs @@ -9,7 +9,7 @@ open Paket.Requirements let expected = """ - + ..\..\..\Microsoft.Net.Http\lib\net40\System.Net.Http.dll @@ -59,7 +59,7 @@ let expected = """ let ``should generate Xml for System.Net.Http 2.2.8``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", [], + InstallModel.CreateFromLibs(PackageName "System.Net.Http", SemVer.Parse "2.2.8", FrameworkRestriction.NoRestriction, [ @"..\Microsoft.Net.Http\lib\net40\System.Net.Http.dll" @"..\Microsoft.Net.Http\lib\net40\System.Net.Http.Extensions.dll" @"..\Microsoft.Net.Http\lib\net40\System.Net.Http.Primitives.dll" @@ -76,8 +76,8 @@ let ``should generate Xml for System.Net.Http 2.2.8``() = LicenseUrl = "" IsDevelopmentDependency = false FrameworkAssemblyReferences = - [{ AssemblyName = "System.Net.Http"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))] } - { AssemblyName = "System.Net.Http.WebRequest"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] }]}) + [{ AssemblyName = "System.Net.Http"; FrameworkRestrictions = makeOrList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))] } + { AssemblyName = "System.Net.Http.WebRequest"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] }]}) let ctx = ProjectFile.TryLoad("./ProjectFile/TestData/Empty.fsprojtest").Value.GenerateXml(model, System.Collections.Generic.HashSet<_>(),Map.empty,Some true,true,KnownTargetProfiles.AllProfiles,None) let currentXML = ctx.ChooseNodes.Head.OuterXml |> normalizeXml diff --git a/tests/Paket.Tests/InstallModel/Xml/xunit.runner.fs b/tests/Paket.Tests/InstallModel/Xml/xunit.runner.fs index 03502e2d00..7bd450e67e 100644 --- a/tests/Paket.Tests/InstallModel/Xml/xunit.runner.fs +++ b/tests/Paket.Tests/InstallModel/Xml/xunit.runner.fs @@ -15,12 +15,12 @@ let expectedPropertyNodes = """ let expectedPropertyDefinitionNodes = """ - + <__paket__xunit_runner_visualstudio_props>net20\xunit.runner.visualstudio - + <__paket__xunit_runner_visualstudio_props>portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid\xunit.runner.visualstudio @@ -31,7 +31,7 @@ let expectedPropertyDefinitionNodes = """ let ``should generate Xml for xunit.runner.visualstudio 2.0.0``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "xunit.runner.visualstudio", SemVer.Parse "2.50.0", [],[], + InstallModel.CreateFromLibs(PackageName "xunit.runner.visualstudio", SemVer.Parse "2.50.0", FrameworkRestriction.NoRestriction,[], [ @"..\xunit.runner.visualstudio\build\net20\xunit.runner.visualstudio.props" @"..\xunit.runner.visualstudio\build\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid\xunit.runner.visualstudio.props" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\xunit.runner.visualstudio\", @@ -63,7 +63,7 @@ let disabledChooseNode = """ let ``should not generate Xml for xunit.runner.visualstudio 2.0.0 if import is disabled``() = ensureDir() let model = - InstallModel.CreateFromLibs(PackageName "xunit.runner.visualstudio", SemVer.Parse "2.50.0", [],[], + InstallModel.CreateFromLibs(PackageName "xunit.runner.visualstudio", SemVer.Parse "2.50.0", FrameworkRestriction.NoRestriction,[], [ @"..\xunit.runner.visualstudio\build\net20\xunit.runner.visualstudio.props" @"..\xunit.runner.visualstudio\build\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid\xunit.runner.visualstudio.props" ] |> Paket.InstallModel.ProcessingSpecs.fromLegacyList @"..\xunit.runner.visualstudio\", diff --git a/tests/Paket.Tests/Lockfile/GenerateWithOptionsSpecs.fs b/tests/Paket.Tests/Lockfile/GenerateWithOptionsSpecs.fs index 5b7a5eacd2..e8ee2647c6 100644 --- a/tests/Paket.Tests/Lockfile/GenerateWithOptionsSpecs.fs +++ b/tests/Paket.Tests/Lockfile/GenerateWithOptionsSpecs.fs @@ -23,7 +23,7 @@ let graph1 = let expected1 = """REFERENCES: STRICT COPY-LOCAL: FALSE -FRAMEWORK: >= NET45 +RESTRICTION: >= net45 NUGET remote: http://www.nuget.org/api/v2 Castle.Windsor-log4net (3.2)""" @@ -181,24 +181,24 @@ nuget NLog.Contrib "NLog.Contrib","1.0.0",["NLog",DependenciesFileParser.parseVersionRequirement ">= 1.0.1"] ] - let expected = """FRAMEWORK: >= NET40 + let expected = """RESTRICTION: >= net40 NUGET remote: https://www.nuget.org/api/v2 - NLog (1.0.1) + NLog (1.0.1) - restriction: == net40 NLog.Contrib (1.0) NLog (>= 1.0.1)""" let cfg = DependenciesFile.FromSource(config) let group = cfg.Groups.[Constants.MainDependencyGroup] group.Packages.Head.Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual [FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client)) ] + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))) let resolved = ResolveWithGraph(cfg,noSha1,VersionsFromGraphAsSeq graph, PackageDetailsFromGraph graph).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() getVersion resolved.[PackageName "NLog"] |> shouldEqual "1.0.1" resolved.[PackageName "NLog"].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual [FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client)) ] + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))) resolved |> LockFileSerializer.serializePackages cfg.Groups.[Constants.MainDependencyGroup].Options diff --git a/tests/Paket.Tests/Lockfile/GeneratorSpecs.fs b/tests/Paket.Tests/Lockfile/GeneratorSpecs.fs index 9099bc10a1..d026fa3f2f 100644 --- a/tests/Paket.Tests/Lockfile/GeneratorSpecs.fs +++ b/tests/Paket.Tests/Lockfile/GeneratorSpecs.fs @@ -59,15 +59,15 @@ nuget "Rx-Main" "~> 2.0" framework: >= net40 """ let ``should generate lock file with framework restrictions for packages``() = let expected = """NUGET remote: http://www.nuget.org/api/v2 - Castle.Windsor (2.1) - framework: net35 - Castle.Windsor-log4net (3.3) - framework: net35 + Castle.Windsor (2.1) - restriction: == net35 + Castle.Windsor-log4net (3.3) - restriction: == net35 Castle.Windsor (>= 2.0) log4net (>= 1.0) - log (1.2) - framework: net35 - log4net (1.1) - framework: net35 + log (1.2) - restriction: == net35 + log4net (1.1) - restriction: == net35 log (>= 1.0) - Rx-Core (2.1) - framework: >= net40 - Rx-Main (2.0) - framework: >= net40 + Rx-Core (2.1) - restriction: >= net40 + Rx-Main (2.0) - restriction: >= net40 Rx-Core (>= 2.1)""" let cfg = DependenciesFile.FromSource(configWithRestrictions) @@ -86,15 +86,15 @@ nuget "Rx-Main" "~> 2.0" framework: >= net40 """ let ``should generate lock file with no targets import for packages``() = let expected = """NUGET remote: "D:\code\temp with space" - Castle.Windsor (2.1) - import_targets: false, framework: net35 - Castle.Windsor-log4net (3.3) - import_targets: false, framework: net35 + Castle.Windsor (2.1) - import_targets: false, restriction: == net35 + Castle.Windsor-log4net (3.3) - import_targets: false, restriction: == net35 Castle.Windsor (>= 2.0) log4net (>= 1.0) - log (1.2) - import_targets: false, framework: net35 - log4net (1.1) - import_targets: false, framework: net35 + log (1.2) - import_targets: false, restriction: == net35 + log4net (1.1) - import_targets: false, restriction: == net35 log (>= 1.0) - Rx-Core (2.1) - framework: >= net40 - Rx-Main (2.0) - framework: >= net40 + Rx-Core (2.1) - restriction: >= net40 + Rx-Main (2.0) - restriction: >= net40 Rx-Core (>= 2.1)""" let cfg = DependenciesFile.FromSource(configWithNoImport) @@ -112,15 +112,15 @@ nuget "Rx-Main" "~> 2.0" framework: >= net40 """ let ``should generate lock file with no copy local for packages``() = let expected = """NUGET remote: http://www.nuget.org/api/v2 - Castle.Windsor (2.1) - copy_local: false, import_targets: false, framework: net35 - Castle.Windsor-log4net (3.3) - copy_local: false, import_targets: false, framework: net35 + Castle.Windsor (2.1) - copy_local: false, import_targets: false, restriction: == net35 + Castle.Windsor-log4net (3.3) - copy_local: false, import_targets: false, restriction: == net35 Castle.Windsor (>= 2.0) log4net (>= 1.0) - log (1.2) - copy_local: false, import_targets: false, framework: net35 - log4net (1.1) - copy_local: false, import_targets: false, framework: net35 + log (1.2) - copy_local: false, import_targets: false, restriction: == net35 + log4net (1.1) - copy_local: false, import_targets: false, restriction: == net35 log (>= 1.0) - Rx-Core (2.1) - framework: >= net40 - Rx-Main (2.0) - framework: >= net40 + Rx-Core (2.1) - restriction: >= net40 + Rx-Main (2.0) - restriction: >= net40 Rx-Core (>= 2.1)""" let cfg = DependenciesFile.FromSource(configWithCopyLocal) ResolveWithGraph(cfg,noSha1,VersionsFromGraphAsSeq graph, PackageDetailsFromGraph graph).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() @@ -138,15 +138,15 @@ nuget "Rx-Main" "~> 2.0" content: none, framework: >= net40 """ let ``should generate lock file with disabled content for packages``() = let expected = """NUGET remote: http://www.nuget.org/api/v2 - Castle.Windsor (2.1) - framework: net35 - Castle.Windsor-log4net (3.3) - framework: net35 + Castle.Windsor (2.1) - restriction: == net35 + Castle.Windsor-log4net (3.3) - restriction: == net35 Castle.Windsor (>= 2.0) log4net (>= 1.0) - log (1.2) - framework: net35 - log4net (1.1) - framework: net35 + log (1.2) - restriction: == net35 + log4net (1.1) - restriction: == net35 log (>= 1.0) - Rx-Core (2.1) - content: none, framework: >= net40 - Rx-Main (2.0) - content: none, framework: >= net40 + Rx-Core (2.1) - content: none, restriction: >= net40 + Rx-Main (2.0) - content: none, restriction: >= net40 Rx-Core (>= 2.1)""" let cfg = DependenciesFile.FromSource(configWithDisabledContent) ResolveWithGraph(cfg,noSha1,VersionsFromGraphAsSeq graph, PackageDetailsFromGraph graph).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() @@ -356,14 +356,14 @@ let ``should generate lock file with second group``() = let expected = """NUGET remote: http://www.nuget.org/api/v2 Castle.Windsor (2.1) - copy_content_to_output_dir: preserve_newest - Castle.Windsor-log4net (3.3) - framework: net35 + Castle.Windsor-log4net (3.3) - restriction: == net35 Castle.Windsor (>= 2.0) log4net (>= 1.0) log (1.2) log4net (1.1) - copy_content_to_output_dir: never log (>= 1.0) Rx-Core (2.1) - content: none - Rx-Main (2.0) - content: none, framework: >= net40 + Rx-Main (2.0) - content: none, restriction: >= net40 Rx-Core (>= 2.1) GROUP Build diff --git a/tests/Paket.Tests/Lockfile/ParserSpecs.fs b/tests/Paket.Tests/Lockfile/ParserSpecs.fs index 12c1e4da35..b6d678cd13 100644 --- a/tests/Paket.Tests/Lockfile/ParserSpecs.fs +++ b/tests/Paket.Tests/Lockfile/ParserSpecs.fs @@ -47,12 +47,12 @@ let ``should parse lock file``() = packages.[1].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[1].Name |> shouldEqual (PackageName "Castle.Windsor-log4net") packages.[1].Version |> shouldEqual (SemVer.Parse "3.3") - packages.[1].Dependencies |> shouldEqual (Set.ofList [PackageName "Castle.Windsor", VersionRequirement(Minimum(SemVer.Parse "2.0"), PreReleaseStatus.No), FrameworkRestrictionList []; PackageName "log4net", VersionRequirement(Minimum(SemVer.Parse "1.0"), PreReleaseStatus.No), FrameworkRestrictionList []]) + packages.[1].Dependencies |> shouldEqual (Set.ofList [PackageName "Castle.Windsor", VersionRequirement(Minimum(SemVer.Parse "2.0"), PreReleaseStatus.No), makeOrList []; PackageName "log4net", VersionRequirement(Minimum(SemVer.Parse "1.0"), PreReleaseStatus.No), makeOrList []]) packages.[5].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[5].Name |> shouldEqual (PackageName "log4net") packages.[5].Version |> shouldEqual (SemVer.Parse "1.1") - packages.[5].Dependencies |> shouldEqual (Set.ofList [PackageName "log", VersionRequirement(Minimum(SemVer.Parse "1.0"), PreReleaseStatus.No), FrameworkRestrictionList []]) + packages.[5].Dependencies |> shouldEqual (Set.ofList [PackageName "log", VersionRequirement(Minimum(SemVer.Parse "1.0"), PreReleaseStatus.No), makeOrList []]) let sourceFiles = List.rev lockFile.SourceFiles sourceFiles|> shouldEqual @@ -111,7 +111,7 @@ let ``should parse strict lock file``() = packages.[5].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[5].Name |> shouldEqual (PackageName "log4net") packages.[5].Version |> shouldEqual (SemVer.Parse "1.1") - packages.[5].Dependencies |> shouldEqual (Set.ofList [PackageName "log", VersionRequirement(Minimum(SemVer.Parse "1.0"), PreReleaseStatus.No), FrameworkRestrictionList []]) + packages.[5].Dependencies |> shouldEqual (Set.ofList [PackageName "log", VersionRequirement(Minimum(SemVer.Parse "1.0"), PreReleaseStatus.No), makeOrList []]) let redirectsLockFile = """REDIRECTS: ON IMPORT-TARGETS: TRUE @@ -224,7 +224,7 @@ let ``should parse own lock file``() = packages.[1].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[1].Name |> shouldEqual (PackageName "FAKE") packages.[1].Version |> shouldEqual (SemVer.Parse "3.5.5") - packages.[1].Settings.FrameworkRestrictions |> shouldEqual (FrameworkRestrictionList []) + packages.[1].Settings.FrameworkRestrictions |> shouldEqual (makeOrList []) lockFile.SourceFiles.[0].Name |> shouldEqual "modules/Octokit/Octokit.fsx" @@ -274,7 +274,7 @@ let ``should parse own lock file2``() = packages.[1].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[1].Name |> shouldEqual (PackageName "FAKE") packages.[1].Version |> shouldEqual (SemVer.Parse "3.5.5") - packages.[3].Settings.FrameworkRestrictions |> shouldEqual (FrameworkRestrictionList []) + packages.[3].Settings.FrameworkRestrictions |> shouldEqual (makeOrList []) lockFile.SourceFiles.[0].Name |> shouldEqual "modules/Octokit/Octokit.fsx" @@ -306,37 +306,37 @@ let ``should parse framework restricted lock file``() = packages.[0].Dependencies |> Set.toList |> List.map (fun (_, _, r) -> r) |> List.item 2 - |> getRestrictionList - |> shouldEqual ([FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))]) + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))) packages.[3].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[3].Name |> shouldEqual (PackageName "LinqBridge") packages.[3].Version |> shouldEqual (SemVer.Parse "1.3.0") packages.[3].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual ([FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2),FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))]) + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2),FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))) packages.[3].Settings.ImportTargets |> shouldEqual None let dependencies4 = packages.[4].Dependencies |> Set.toList |> List.map (fun (_, _, r) -> r) dependencies4.Head - |> getRestrictionList - |> shouldEqual ([FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2), FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))]) + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2), FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))) dependencies4.Tail.Head - |> getRestrictionList + |> getExplicitRestriction |> shouldEqual ([FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2)) FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) - FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))]) + FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))] |> makeOrList |> getExplicitRestriction) packages.[5].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[5].Name |> shouldEqual (PackageName "ReadOnlyCollectionInterfaces") packages.[5].Version |> shouldEqual (SemVer.Parse "1.0.0") packages.[5].Settings.FrameworkRestrictions - |> getRestrictionList + |> getExplicitRestriction |> shouldEqual ([FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2)) FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) - FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))]) + FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))] |> makeOrList |> getExplicitRestriction) let frameworkRestricted' = """NUGET remote: https://www.nuget.org/api/v2 @@ -365,16 +365,16 @@ let ``should parse framework restricted lock file in new syntax``() = packages.[0].Dependencies |> Set.toList |> List.map (fun (_, _, r) -> r) |> List.item 2 - |> getRestrictionList - |> shouldEqual ([FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))]) + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))) packages.[3].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[3].Name |> shouldEqual (PackageName "LinqBridge") packages.[3].Version |> shouldEqual (SemVer.Parse "1.3.0") packages.[3].Settings.CopyContentToOutputDirectory |> shouldEqual (Some CopyToOutputDirectorySettings.Never) packages.[3].Settings.FrameworkRestrictions - |> getRestrictionList - |> shouldEqual ([FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2),FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))]) + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2),FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))) packages.[3].Settings.CopyLocal |> shouldEqual None packages.[3].Settings.ImportTargets |> shouldEqual (Some false) packages.[3].Settings.IncludeVersionInPath |> shouldEqual (Some true) @@ -384,13 +384,13 @@ let ``should parse framework restricted lock file in new syntax``() = packages.[4].Dependencies |> Set.toList |> List.map (fun (_, _, r) -> r) dependencies4.Head - |> getRestrictionList - |> shouldEqual ([FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2), FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))]) + |> getExplicitRestriction + |> shouldEqual (FrameworkRestriction.Between(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2), FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5))) dependencies4.Tail.Head - |> getRestrictionList + |> getExplicitRestriction |> shouldEqual ([FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2)) FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) - FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))]) + FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))] |> makeOrList |> getExplicitRestriction) packages.[5].Source |> shouldEqual PackageSources.DefaultNuGetSource packages.[5].Name |> shouldEqual (PackageName "ReadOnlyCollectionInterfaces") @@ -400,10 +400,10 @@ let ``should parse framework restricted lock file in new syntax``() = packages.[5].Settings.OmitContent |> shouldEqual None packages.[5].Settings.IncludeVersionInPath |> shouldEqual None packages.[5].Settings.FrameworkRestrictions - |> getRestrictionList + |> getExplicitRestriction |> shouldEqual ([FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V2)) FrameworkRestriction.Exactly(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V3_5)) - FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4_Client))]) + FrameworkRestriction.AtLeast(FrameworkIdentifier.DotNetFramework(FrameworkVersion.V4))] |> makeOrList |> getExplicitRestriction) let simpleHTTP = """ HTTP @@ -465,7 +465,7 @@ let ``should parse portable lockfile``() = packages.[1].Name |> shouldEqual (PackageName "Zlib.Portable") packages.[1].Version |> shouldEqual (SemVer.Parse "1.10.0") - (packages.[1].Settings.FrameworkRestrictions |> getRestrictionList).ToString() |> shouldEqual "[portable-net40+sl50+wp80+win80]" + (packages.[1].Settings.FrameworkRestrictions |> getExplicitRestriction).ToString() |> shouldEqual ">= portable-net40+win8+wp8+sl5" let reactiveuiLockFile = """NUGET remote: https://www.nuget.org/api/v2 @@ -512,13 +512,13 @@ let ``should parse reactiveui lockfile``() = packages.[8].Name |> shouldEqual (PackageName "Rx-WindowStoreApps") packages.[8].Version |> shouldEqual (SemVer.Parse "2.2.5") - (packages.[8].Settings.FrameworkRestrictions |> getRestrictionList).ToString() |> shouldEqual "[winv4.5]" + (packages.[8].Settings.FrameworkRestrictions |> getExplicitRestriction).ToString() |> shouldEqual "== win8" packages.[10].Name |> shouldEqual (PackageName "Rx-Xaml") packages.[10].Version |> shouldEqual (SemVer.Parse "2.2.5") - (packages.[10].Settings.FrameworkRestrictions |> getRestrictionList).ToString() |> shouldEqual "[winv4.5; wpv8.0; >= net45]" + (packages.[10].Settings.FrameworkRestrictions |> getExplicitRestriction).ToString() |> shouldEqual "|| (== win8) (== wp8) (>= net45)" -let multipleFeedLockFile = """NUGET +let multipleFeedLockFileLegacy = """NUGET remote: http://internalfeed/NugetWebFeed/nuget Internal_1 (1.2.10) Newtonsoft.Json (>= 6.0 < 6.1) @@ -536,27 +536,47 @@ let multipleFeedLockFile = """NUGET Microsoft.AspNet.WebApi.Core (>= 5.2.3 < 5.3) """ +let multipleFeedLockFile = """NUGET + remote: http://internalfeed/NugetWebFeed/nuget + Internal_1 (1.2.10) + Newtonsoft.Json (>= 6.0 < 6.1) + log4net (1.2.10) + Newtonsoft.Json (6.0.6) + remote: https://www.nuget.org/api/v2 + Microsoft.AspNet.WebApi (5.2.3) + Microsoft.AspNet.WebApi.WebHost (>= 5.2.3 < 5.3) + Microsoft.AspNet.WebApi.Client (5.2.3) + Microsoft.Net.Http (>= 2.2.22) - restriction: >= portable-net45+win8+wp8+wp81+wpa81 + Newtonsoft.Json (>= 6.0.4) - restriction: >= portable-net45+win8+wp8+wp81+wpa81 + Microsoft.AspNet.WebApi.Core (5.2.3) + Microsoft.AspNet.WebApi.Client (>= 5.2.3) + Microsoft.AspNet.WebApi.WebHost (5.2.3) + Microsoft.AspNet.WebApi.Core (>= 5.2.3 < 5.3) +""" + [] let ``should parse lockfile with multiple feeds``() = - let lockFile = LockFileParser.Parse(toLines multipleFeedLockFile) |> List.head - let references = lockFile.SourceFiles + for lockFileText in [multipleFeedLockFileLegacy;multipleFeedLockFile] do + let lockFile = LockFileParser.Parse(toLines lockFileText) |> List.head + let references = lockFile.SourceFiles - references.Length |> shouldEqual 0 + references.Length |> shouldEqual 0 - let packages = List.rev lockFile.Packages - packages.Length |> shouldEqual 7 + let packages = List.rev lockFile.Packages + packages.Length |> shouldEqual 7 - packages.[3].Name |> shouldEqual (PackageName "Microsoft.AspNet.WebApi") - packages.[3].Version |> shouldEqual (SemVer.Parse "5.2.3") - packages.[3].Source.ToString() |> shouldEqual "https://www.nuget.org/api/v2" + packages.[3].Name |> shouldEqual (PackageName "Microsoft.AspNet.WebApi") + packages.[3].Version |> shouldEqual (SemVer.Parse "5.2.3") + packages.[3].Source.ToString() |> shouldEqual "https://www.nuget.org/api/v2" [] let ``should parse and serialise multiple feed lockfile``() = - let lockFile = LockFile.Parse("",toLines multipleFeedLockFile) - let lockFile' = lockFile.ToString() + for lockFileText in [multipleFeedLockFileLegacy;multipleFeedLockFile] do + let lockFile = LockFile.Parse("",toLines lockFileText) + let lockFile' = lockFile.ToString() - normalizeLineEndings lockFile' - |> shouldEqual (normalizeLineEndings multipleFeedLockFile) + normalizeLineEndings lockFile' + |> shouldEqual (normalizeLineEndings multipleFeedLockFile) let groupsLockFile = """REDIRECTS: ON @@ -753,26 +773,33 @@ let ``should parse lock file from auto-detect settings``() = let deps = packages.Tail.Head.Dependencies |> Seq.toList |> List.map (fun (n,_,_) -> n) deps.Head |> shouldEqual (PackageName "Autofac") -let lockFileWithManyFrameworks = """NUGET +let lockFileWithManyFrameworksLegacy = """NUGET remote: https://www.nuget.org/api/v2 CommonServiceLocator (1.3) - framework: >= net40, monoandroid, portable-net45+wp80+wpa81+win+monoandroid10+xamarinios10, xamarinios, winv4.5, winv4.5.1, wpv8.0, wpv8.1, sl50 MvvmLightLibs (5.2) CommonServiceLocator (>= 1.0) - framework: net35, sl40 CommonServiceLocator (>= 1.3) - framework: >= net40, monoandroid, portable-net45+wp80+wpa81+win+monoandroid10+xamarinios10, xamarinios, winv4.5, winv4.5.1, wpv8.0, wpv8.1, sl50""" +let lockFileWithManyFrameworks = """NUGET + remote: https://www.nuget.org/api/v2 + CommonServiceLocator (1.3) - restriction: || (== sl5) (>= net40) (>= portable-net45+monoandroid+xamarinios+win8+wp8+wpa81) + MvvmLightLibs (5.2) + CommonServiceLocator (>= 1.0) - restriction: || (== net35) (== sl4) + CommonServiceLocator (>= 1.3) - restriction: || (== sl5) (>= net40) (>= portable-net45+monoandroid+xamarinios+win8+wp8+wpa81)""" [] let ``should parse lock file many frameworks``() = - let lockFile = LockFileParser.Parse(toLines lockFileWithManyFrameworks) - let main = lockFile.Head - let packages = List.rev main.Packages + for lockFile in [lockFileWithManyFrameworksLegacy;lockFileWithManyFrameworks] do + let lockFile = LockFileParser.Parse(toLines lockFile) + let main = lockFile.Head + let packages = List.rev main.Packages - packages.Length |> shouldEqual 2 + packages.Length |> shouldEqual 2 - packages.Head.Name |> shouldEqual (PackageName "CommonServiceLocator") - packages.Tail.Head.Name |> shouldEqual (PackageName "MvvmLightLibs") - LockFileSerializer.serializePackages main.Options (main.Packages |> List.map (fun p -> p.Name,p) |> Map.ofList) - |> normalizeLineEndings - |> shouldEqual (normalizeLineEndings lockFileWithManyFrameworks) + packages.Head.Name |> shouldEqual (PackageName "CommonServiceLocator") + packages.Tail.Head.Name |> shouldEqual (PackageName "MvvmLightLibs") + LockFileSerializer.serializePackages main.Options (main.Packages |> List.map (fun p -> p.Name,p) |> Map.ofList) + |> normalizeLineEndings + |> shouldEqual (normalizeLineEndings lockFileWithManyFrameworks) let lockFileWithDependencies = """NUGET remote: https://www.nuget.org/api/v2 @@ -913,3 +940,70 @@ let ``should parse lock file with spaces in file names``() = OperatingSystemRestriction = None PackagePath = None AuthKey = Some "secret" } ] + + +let lockFileWithNewRestrictions = """NUGET + remote: http://www.nuget.org/api/v2 + MathNet.Numerics (3.2.3) + TaskParallelLibrary (>= 1.0.2856) - restriction: && (>= net35) (< net40) + MathNet.Numerics.FSharp (3.2.3) + MathNet.Numerics (3.2.3) + TaskParallelLibrary (1.0.2856) - restriction: && (>= net35) (< net40)""" + +[] +let ``should parse new restrictions && (>= net35) (< net40)``() = + let lockFile = LockFileParser.Parse (toLines lockFileWithNewRestrictions) + let main = lockFile.Head + let packages = lockFile.Tail + + LockFileSerializer.serializePackages main.Options (main.Packages |> List.map (fun p -> p.Name,p) |> Map.ofList) + |> normalizeLineEndings + |> shouldEqual (normalizeLineEndings lockFileWithNewRestrictions) + +let lockFileWithNewComplexRestrictions = """NUGET + remote: http://www.nuget.org/api/v2 + AWSSDK.Core (3.1.5.3) + Microsoft.Net.Http (>= 2.2.29) - restriction: && (< net45) (>= portable-net45+win8+wp8+wpa81) + PCLStorage (>= 1.0.2) - restriction: && (< net45) (>= portable-net45+win8+wp8+wpa81) + Microsoft.Bcl (1.1.10) - restriction: || (&& (< net45) (>= portable-net45+win8+wp8+wpa81)) (&& (< portable-net45+monoandroid+monotouch+xamarinios+xamarinmac+win8+wp8+wpa81) (>= portable-net45+win8+wp8+wpa81)) + Microsoft.Bcl.Build (>= 1.0.14) + Microsoft.Bcl.Async (1.0.168) - restriction: && (< portable-net45+monoandroid+monotouch+xamarinios+xamarinmac+win8+wp8+wpa81) (>= portable-net45+win8+wp8+wpa81) + Microsoft.Bcl (>= 1.1.8) + Microsoft.Bcl.Build (1.0.21) - import_targets: false, restriction: && (< net45) (>= portable-net45+win8+wp8+wpa81) + Microsoft.Net.Http (2.2.29) - restriction: && (< net45) (>= portable-net45+win8+wp8+wpa81) + Microsoft.Bcl (>= 1.1.10) + Microsoft.Bcl.Build (>= 1.0.14) + PCLStorage (1.0.2) - restriction: && (< net45) (>= portable-net45+win8+wp8+wpa81) + Microsoft.Bcl (>= 1.1.6) - restriction: < portable-net45+monoandroid+monotouch+xamarinios+xamarinmac+win8+wp8+wpa81 + Microsoft.Bcl.Async (>= 1.0.165) - restriction: < portable-net45+monoandroid+monotouch+xamarinios+xamarinmac+win8+wp8+wpa81""" + +[] +let ``should parse new restrictions || (&& (< net45) (>= portable-net45+win8+wp8+wpa81)) (&& (< portable-net45+monoandroid+monotouch+xamarinios+xamarinmac+win8+wp8+wpa81) (>= portable-net45+win8+wp8+wpa81))``() = + let lockFile = LockFileParser.Parse (toLines lockFileWithNewComplexRestrictions) + let main = lockFile.Head + let packages = lockFile.Tail + + LockFileSerializer.serializePackages main.Options (main.Packages |> List.map (fun p -> p.Name,p) |> Map.ofList) + |> normalizeLineEndings + |> shouldEqual (normalizeLineEndings lockFileWithNewComplexRestrictions) + +let lockFileWithMissingVersion = """NUGET + remote: https://www.nuget.org/api/v2 + Microsoft.Bcl (1.1.10) - restriction: || (== net10) (== net11) (== net20) (== net30) (== net35) (== net40) + Microsoft.Bcl.Build (>= 1.0.14) + Microsoft.Bcl.Build (1.0.21) - import_targets: false, restriction: || (== net10) (== net11) (== net20) (== net30) (== net35) (== net40) + Microsoft.Net.Http (2.2.29) - restriction: || (== net10) (== net11) (== net20) (== net30) (== net35) (== net40) + Microsoft.Bcl (>= 1.1.10) + Microsoft.Bcl.Build (>= 1.0.14) + Octokit (0.19) + Microsoft.Net.Http - restriction: || (== net10) (== net11) (== net20) (== net30) (== net35) (== net40)""" + +[] +let ``should parse lockfile with missing version``() = + let lockFile = LockFileParser.Parse (toLines lockFileWithMissingVersion) + let main = lockFile.Head + let packages = lockFile.Tail + + LockFileSerializer.serializePackages main.Options (main.Packages |> List.map (fun p -> p.Name,p) |> Map.ofList) + |> normalizeLineEndings + |> shouldEqual (normalizeLineEndings lockFileWithMissingVersion) \ No newline at end of file diff --git a/tests/Paket.Tests/NuGetOData/ODataSpecs.fs b/tests/Paket.Tests/NuGetOData/ODataSpecs.fs index 3ae2ebe54f..2ecbe2b5ba 100644 --- a/tests/Paket.Tests/NuGetOData/ODataSpecs.fs +++ b/tests/Paket.Tests/NuGetOData/ODataSpecs.fs @@ -8,11 +8,13 @@ open Paket.NuGetV2 open Paket.NuGetV3 open Paket.Requirements +open Paket.TestHelpers open Domain let fakeUrl = "http://doesntmatter" let parse fileName = + System.Environment.CurrentDirectory <- Path.GetDirectoryName __SOURCE_DIRECTORY__ parseODataDetails("tenp",fakeUrl,PackageName "package",SemVer.Parse "0",File.ReadAllText fileName) [] @@ -21,7 +23,7 @@ let ``can detect explicit dependencies for Fantomas``() = |> shouldEqual { PackageName = "Fantomas" DownloadUrl = "http://www.nuget.org/api/v2/package/Fantomas/1.6.0" - Dependencies = [PackageName "FSharp.Compiler.Service",DependenciesFileParser.parseVersionRequirement(">= 0.0.73"), FrameworkRestrictionList []] + SerializedDependencies = [PackageName "FSharp.Compiler.Service",DependenciesFileParser.parseVersionRequirement(">= 0.0.73"), "true"] Unlisted = false LicenseUrl = "http://github.com/dungpa/fantomas/blob/master/LICENSE.md" CacheVersion = NuGet.NuGetPackageCache.CurrentCacheVersion @@ -34,9 +36,9 @@ let ``can detect explicit dependencies for Rx-PlaformServices``() = |> shouldEqual { PackageName = "Rx-PlatformServices" DownloadUrl = "https://www.nuget.org/api/v2/package/Rx-PlatformServices/2.3.0" - Dependencies = - [PackageName "Rx-Interfaces",DependenciesFileParser.parseVersionRequirement(">= 2.2"), FrameworkRestrictionList [] - PackageName "Rx-Core",DependenciesFileParser.parseVersionRequirement(">= 2.2"), FrameworkRestrictionList []] + SerializedDependencies = + [PackageName "Rx-Interfaces",DependenciesFileParser.parseVersionRequirement(">= 2.2"), "true" + PackageName "Rx-Core",DependenciesFileParser.parseVersionRequirement(">= 2.2"), "true"] Unlisted = true LicenseUrl = "http://go.microsoft.com/fwlink/?LinkID=261272" Version = "2.3.0" @@ -49,8 +51,8 @@ let ``can detect explicit dependencies for EasyNetQ``() = |> shouldEqual { PackageName = "EasyNetQ" DownloadUrl = "https://www.nuget.org/api/v2/package/EasyNetQ/0.40.3.352" - Dependencies = - [PackageName "RabbitMQ.Client",DependenciesFileParser.parseVersionRequirement(">= 3.4.3"),FrameworkRestrictionList []] + SerializedDependencies = + [PackageName "RabbitMQ.Client",DependenciesFileParser.parseVersionRequirement(">= 3.4.3"),"true"] Unlisted = false LicenseUrl = "https://github.com/mikehadlow/EasyNetQ/blob/master/licence.txt" CacheVersion = NuGet.NuGetPackageCache.CurrentCacheVersion @@ -67,16 +69,17 @@ let ``can detect explicit dependencies for Fleece``() = CacheVersion = NuGet.NuGetPackageCache.CurrentCacheVersion LicenseUrl = "https://raw.github.com/mausch/Fleece/master/LICENSE" Version = "0.4.0" - Dependencies = - [PackageName "FSharpPlus",DependenciesFileParser.parseVersionRequirement(">= 0.0.4"),FrameworkRestrictionList [] - PackageName "ReadOnlyCollectionInterfaces",DependenciesFileParser.parseVersionRequirement("1.0.0"),FrameworkRestrictionList [] - PackageName "ReadOnlyCollectionExtensions",DependenciesFileParser.parseVersionRequirement(">= 1.2.0"),FrameworkRestrictionList [] - PackageName "System.Json",DependenciesFileParser.parseVersionRequirement(">= 4.0.20126.16343"),FrameworkRestrictionList []] + SerializedDependencies = + [PackageName "FSharpPlus",DependenciesFileParser.parseVersionRequirement(">= 0.0.4"),"true" + PackageName "ReadOnlyCollectionInterfaces",DependenciesFileParser.parseVersionRequirement("1.0.0"),"true" + PackageName "ReadOnlyCollectionExtensions",DependenciesFileParser.parseVersionRequirement(">= 1.2.0"),"true" + PackageName "System.Json",DependenciesFileParser.parseVersionRequirement(">= 4.0.20126.16343"),"true"] SourceUrl = fakeUrl } [] let ``can detect explicit dependencies for ReadOnlyCollectionExtensions``() = - parse "NuGetOData/ReadOnlyCollectionExtensions.xml" + let item = parse "NuGetOData/ReadOnlyCollectionExtensions.xml" + item |> shouldEqual { PackageName = "ReadOnlyCollectionExtensions" DownloadUrl = "http://www.nuget.org/api/v2/package/ReadOnlyCollectionExtensions/1.2.0" @@ -84,12 +87,9 @@ let ``can detect explicit dependencies for ReadOnlyCollectionExtensions``() = CacheVersion = NuGet.NuGetPackageCache.CurrentCacheVersion LicenseUrl = "https://github.com/mausch/ReadOnlyCollections/blob/master/license.txt" Version = "1.2.0" - Dependencies = - [PackageName "LinqBridge",DependenciesFileParser.parseVersionRequirement(">= 1.3.0"),FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V2))] - PackageName "ReadOnlyCollectionInterfaces",DependenciesFileParser.parseVersionRequirement("1.0.0"), - FrameworkRestrictionList - [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V2)) - FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V3_5))]] + SerializedDependencies = + [PackageName "LinqBridge",DependenciesFileParser.parseVersionRequirement(">= 1.3.0"), "&& (>= net20) (< net35)" + PackageName "ReadOnlyCollectionInterfaces",DependenciesFileParser.parseVersionRequirement("1.0.0"), ">= net20"] SourceUrl = fakeUrl } [] @@ -102,16 +102,16 @@ let ``can detect explicit dependencies for Math.Numerics``() = Version = "3.3.0" LicenseUrl = "http://numerics.mathdotnet.com/docs/License.html" CacheVersion = NuGet.NuGetPackageCache.CurrentCacheVersion - Dependencies = - [PackageName "TaskParallelLibrary",DependenciesFileParser.parseVersionRequirement(">= 1.0.2856"), FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))]] + SerializedDependencies = + [PackageName "TaskParallelLibrary",DependenciesFileParser.parseVersionRequirement(">= 1.0.2856"), "&& (>= net35) (< net40)" ] SourceUrl = fakeUrl } [] let ``can detect explicit dependencies for Math.Numerics.FSharp``() = - (parse "NuGetOData/Math.Numerics.FSharp.xml").Dependencies |> Seq.head + (parse "NuGetOData/Math.Numerics.FSharp.xml")|> NuGet.NuGetPackageCache.getDependencies |> Seq.head |> shouldEqual (PackageName "MathNet.Numerics", - DependenciesFileParser.parseVersionRequirement("3.3.0"),FrameworkRestrictionList []) + DependenciesFileParser.parseVersionRequirement("3.3.0"),makeOrList []) [] let ``can calculate v3 path``() = @@ -123,23 +123,24 @@ let ``can detect explicit dependencies for Microsoft.AspNet.WebApi.Client``() = let odata = parse "NuGetOData/Microsoft.AspNet.WebApi.Client.xml" odata.PackageName |> shouldEqual "Microsoft.AspNet.WebApi.Client" odata.DownloadUrl |> shouldEqual"https://www.nuget.org/api/v2/package/Microsoft.AspNet.WebApi.Client/5.2.3" - let dependencies = odata.Dependencies |> Array.ofList + let dependencies = odata|> NuGet.NuGetPackageCache.getDependencies |> Array.ofList dependencies.[0] |> shouldEqual (PackageName "Newtonsoft.Json", DependenciesFileParser.parseVersionRequirement(">= 6.0.4"), - FrameworkRestrictionList [FrameworkRestriction.Portable("portable-wp80+win+wp81+wpa81"); FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))]) + makeOrList [getPortableRestriction("portable-net45+win8+wp8+wp81+wpa81"); FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))]) dependencies.[1] |> shouldEqual (PackageName "Microsoft.Net.Http", DependenciesFileParser.parseVersionRequirement(">= 2.2.22"), - FrameworkRestrictionList [FrameworkRestriction.Portable("portable-wp80+win+wp81+wpa81")]) + FrameworkRestriction.And [getPortableRestriction("portable-net45+win8+wp8+wp81+wpa81"); FrameworkRestriction.NotAtLeast(DotNetFramework(FrameworkVersion.V4_5))] + |> ExplicitRestriction) [] let ``can detect explicit dependencies for WindowsAzure.Storage``() = let odata = parse "NuGetOData/WindowsAzure.Storage.xml" odata.PackageName |> shouldEqual "WindowsAzure.Storage" odata.DownloadUrl |> shouldEqual"https://www.nuget.org/api/v2/package/WindowsAzure.Storage/4.4.1-preview" - let dependencies = odata.Dependencies |> Array.ofList + let dependencies = odata|> NuGet.NuGetPackageCache.getDependencies |> Array.ofList dependencies.[0] |> shouldEqual (PackageName "Microsoft.Data.OData", DependenciesFileParser.parseVersionRequirement(">= 5.6.3"), - FrameworkRestrictionList [FrameworkRestriction.Exactly(DNXCore(FrameworkVersion.V5_0))]) + makeOrList [FrameworkRestriction.AtLeast(DNXCore(FrameworkVersion.V5_0))]) let vr,pr = match DependenciesFileParser.parseVersionRequirement(">= 4.0.0-beta-22231") with @@ -147,23 +148,24 @@ let ``can detect explicit dependencies for WindowsAzure.Storage``() = dependencies.[18] |> shouldEqual (PackageName "System.Net.Http", VersionRequirement(vr,PreReleaseStatus.All), - FrameworkRestrictionList [FrameworkRestriction.Exactly(DNXCore(FrameworkVersion.V5_0))]) + makeOrList [FrameworkRestriction.AtLeast(DNXCore(FrameworkVersion.V5_0))]) dependencies.[44] |> shouldEqual (PackageName "Newtonsoft.Json", DependenciesFileParser.parseVersionRequirement(">= 6.0.8"), - FrameworkRestrictionList [FrameworkRestriction.Exactly(WindowsPhoneSilverlight("v8.0")); FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_Client))]) + makeOrList [FrameworkRestriction.AtLeast(WindowsPhone WindowsPhoneVersion.V8); FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))]) [] let ``can ignore unknown frameworks``() = - parse "NuGetOData/BenchmarkDotNet-UnknownFramework.xml" + let parsed = parse "NuGetOData/BenchmarkDotNet-UnknownFramework.xml" + parsed |> shouldEqual { PackageName = "BenchmarkDotNet" DownloadUrl = "https://www.nuget.org/api/v2/package/BenchmarkDotNet/0.10.1" - Dependencies = + SerializedDependencies = [ PackageName "BenchmarkDotNet.Toolchains.Roslyn", DependenciesFileParser.parseVersionRequirement(">= 0.10.1"), - FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4_5)] + ">= net45" ] Unlisted = false LicenseUrl = "https://github.com/dotnet/BenchmarkDotNet/blob/master/LICENSE.md" diff --git a/tests/Paket.Tests/Nuspec/NuspecSpecs.fs b/tests/Paket.Tests/Nuspec/NuspecSpecs.fs index fc554255de..7ce8dadb8d 100644 --- a/tests/Paket.Tests/Nuspec/NuspecSpecs.fs +++ b/tests/Paket.Tests/Nuspec/NuspecSpecs.fs @@ -88,13 +88,13 @@ let ``can detect framework assemblies for Microsoft.Net.Http``() = |> shouldEqual [{ AssemblyName = "System.Net.Http" FrameworkRestrictions = - FrameworkRestrictionList + makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5)) FrameworkRestriction.Exactly(MonoTouch) FrameworkRestriction.Exactly(MonoAndroid)] } { AssemblyName = "System.Net.Http.WebRequest" FrameworkRestrictions = - FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] }] + makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] }] [] let ``can detect deps assemblies for RazorEngine``() = @@ -102,25 +102,25 @@ let ``can detect deps assemblies for RazorEngine``() = Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"RazorEngine.nuspec")).Dependencies |> shouldEqual [PackageName "Microsoft.AspNet.Razor",DependenciesFileParser.parseVersionRequirement("= 2.0.30506.0"), - FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_Client))] + makeOrList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4), DotNetFramework(FrameworkVersion.V4_5))] PackageName "Microsoft.AspNet.Razor",DependenciesFileParser.parseVersionRequirement(">= 3.0.0"), - FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))]] + makeOrList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))]] [] let ``can detect framework assemblies for FluentAssertions``() = //ensureDir() Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"FluentAssertions.nuspec")).FrameworkAssemblyReferences |> shouldEqual - [{ AssemblyName = "System.Xml"; FrameworkRestrictions = FrameworkRestrictionList [] } - { AssemblyName = "System.Xml.Linq"; FrameworkRestrictions = FrameworkRestrictionList [] } ] + [{ AssemblyName = "System.Xml"; FrameworkRestrictions = makeOrList [] } + { AssemblyName = "System.Xml.Linq"; FrameworkRestrictions = makeOrList [] } ] [] let ``can detect framework assemblies for SqlCLient``() = //ensureDir() Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"FSharp.Data.SqlClient.nuspec")).FrameworkAssemblyReferences |> shouldEqual - [{ AssemblyName = "System.Data"; FrameworkRestrictions = FrameworkRestrictionList [] } - { AssemblyName = "System.Xml"; FrameworkRestrictions = FrameworkRestrictionList [] } ] + [{ AssemblyName = "System.Data"; FrameworkRestrictions = makeOrList [] } + { AssemblyName = "System.Xml"; FrameworkRestrictions = makeOrList [] } ] [] let ``can detect license for SqlCLient``() = @@ -133,7 +133,7 @@ let ``can detect dependencies for SqlCLient``() = //ensureDir() Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"FSharp.Data.SqlClient.nuspec")).Dependencies |> shouldEqual - [PackageName "Microsoft.SqlServer.Types",DependenciesFileParser.parseVersionRequirement(">= 11.0.0"), FrameworkRestrictionList []] + [PackageName "Microsoft.SqlServer.Types",DependenciesFileParser.parseVersionRequirement(">= 11.0.0"), makeOrList []] [] let ``can detect reference files for SqlCLient``() = @@ -148,17 +148,17 @@ let ``can detect framework assemblies for Octokit``() = |> shouldEqual [{ AssemblyName = "System.Net.Http" FrameworkRestrictions = - FrameworkRestrictionList + makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5)) - FrameworkRestriction.Exactly(Windows "v4.5")] }] + FrameworkRestriction.Exactly(Windows WindowsVersion.V8)] }] [] let ``can detect framework assemblies for FSharp.Data.SqlEnumProvider``() = //ensureDir() Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"FSharp.Data.SqlEnumProvider.nuspec")).FrameworkAssemblyReferences |> shouldEqual - [{ AssemblyName = "System.Data"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_Client))] } - { AssemblyName = "System.Xml"; FrameworkRestrictions = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_Client))] }] + [{ AssemblyName = "System.Data"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4))] } + { AssemblyName = "System.Xml"; FrameworkRestrictions = makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4))] }] [] let ``can detect empty framework assemblies for ReadOnlyCollectionExtensions``() = @@ -176,7 +176,7 @@ let ``can detect empty dependencies for log4net``() = let ``can detect explicit dependencies for Fantomas``() = //ensureDir() Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"Fantomas.nuspec")).Dependencies - |> shouldEqual [PackageName "FSharp.Compiler.Service",DependenciesFileParser.parseVersionRequirement(">= 0.0.57"), FrameworkRestrictionList []] + |> shouldEqual [PackageName "FSharp.Compiler.Service",DependenciesFileParser.parseVersionRequirement(">= 0.0.57"), makeOrList []] [] let ``can detect explicit dependencies for ReadOnlyCollectionExtensions``() = @@ -184,11 +184,10 @@ let ``can detect explicit dependencies for ReadOnlyCollectionExtensions``() = Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"ReadOnlyCollectionExtensions.nuspec")).Dependencies |> shouldEqual [PackageName "LinqBridge",DependenciesFileParser.parseVersionRequirement(">= 1.3.0"), - FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V2))] + makeOrList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V2), DotNetFramework(FrameworkVersion.V3_5))] PackageName "ReadOnlyCollectionInterfaces",DependenciesFileParser.parseVersionRequirement("1.0.0"), - FrameworkRestrictionList - [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V2)) - FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V3_5))]] + makeOrList + [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V2))]] [] let ``can detect explicit dependencies for Microsoft.AspNetCore.Antiforgery``() = @@ -202,7 +201,7 @@ let ``can detect explicit dependencies for Microsoft.AspNetCore.Antiforgery``() deps.[0] |> shouldEqual (PackageName "Microsoft.AspNetCore.DataProtection", VersionRequirement(v,PreReleaseStatus.All), - FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)); FrameworkRestriction.AtLeast (DotNetStandard(DotNetStandardVersion.V1_3))]) + makeOrList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)); FrameworkRestriction.AtLeast (DotNetStandard(DotNetStandardVersion.V1_3))]) [] let ``can detect explicit dependencies for Microsoft.AspNetCore.Mvc.ViewFeatures``() = @@ -216,7 +215,7 @@ let ``can detect explicit dependencies for Microsoft.AspNetCore.Mvc.ViewFeatures deps.[0] |> shouldEqual (PackageName "Microsoft.AspNetCore.Antiforgery", VersionRequirement(v,PreReleaseStatus.All), - FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)); FrameworkRestriction.AtLeast (DotNetStandard(DotNetStandardVersion.V1_5))]) + makeOrList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)); FrameworkRestriction.AtLeast (DotNetStandard(DotNetStandardVersion.V1_5))]) [] let ``can detect framework assemblies for MathNet.Numerics``() = @@ -225,10 +224,10 @@ let ``can detect framework assemblies for MathNet.Numerics``() = |> shouldEqual [{ AssemblyName = "System.Numerics" FrameworkRestrictions = - FrameworkRestrictionList - [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_Client)) - FrameworkRestriction.Exactly(Windows("v4.5")) - FrameworkRestriction.Exactly(Silverlight("v5.0")) + makeOrList + [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4)) + FrameworkRestriction.Exactly(Windows WindowsVersion.V8) + FrameworkRestriction.Exactly(Silverlight SilverlightVersion.V5) FrameworkRestriction.Exactly(MonoAndroid) FrameworkRestriction.Exactly(MonoTouch)] }] @@ -240,16 +239,18 @@ let ``can detect dependencies for MathNet.Numerics``() = |> shouldEqual [ PackageName "TaskParallelLibrary", DependenciesFileParser.parseVersionRequirement(">= 1.0.2856.0"), - FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))] ] + makeOrList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4))] ] [] let ``can detect dependencies for MathNet.Numerics.FSharp``() = //ensureDir() - Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"MathNet.Numerics.FSharp.nuspec")).Dependencies - |> Seq.head + let s = + Nuspec.Load(Path.Combine(__SOURCE_DIRECTORY__,"MathNet.Numerics.FSharp.nuspec")).Dependencies + |> Seq.head + s |> shouldEqual (PackageName "MathNet.Numerics", - DependenciesFileParser.parseVersionRequirement("3.3.0"),FrameworkRestrictionList []) + DependenciesFileParser.parseVersionRequirement("3.3.0"),makeOrList []) [] let ``can detect explicit dependencies for WindowsAzure.Storage``() = @@ -260,9 +261,9 @@ let ``can detect explicit dependencies for WindowsAzure.Storage``() = |> shouldEqual (PackageName "Newtonsoft.Json", DependenciesFileParser.parseVersionRequirement(">= 5.0.8"), - FrameworkRestrictionList - [FrameworkRestriction.Exactly(WindowsPhoneSilverlight("v8.0")) - FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_Client))]) + makeOrList + [FrameworkRestriction.AtLeast(WindowsPhone WindowsPhoneVersion.V8) + FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))]) [] let ``can detect framework assemblies for Microsoft.Framework.Logging``() = @@ -271,7 +272,7 @@ let ``can detect framework assemblies for Microsoft.Framework.Logging``() = nuspec.FrameworkAssemblyReferences.[0].AssemblyName |> shouldEqual "System.Collections.Concurrent" nuspec.FrameworkAssemblyReferences.[0].FrameworkRestrictions |> shouldEqual - (FrameworkRestrictionList + (makeOrList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5)) FrameworkRestriction.Exactly(DNX(FrameworkVersion.V4_5_1))]) @@ -280,7 +281,7 @@ let ``can detect framework assemblies for Microsoft.Framework.Logging``() = let name,_,restrictions = nuspec.Dependencies.[2] name |> shouldEqual (PackageName "System.Collections.Concurrent") - restrictions |> shouldEqual (FrameworkRestrictionList [FrameworkRestriction.Exactly(DNXCore(FrameworkVersion.V5_0))]) + restrictions |> shouldEqual (makeOrList [FrameworkRestriction.AtLeast(DNXCore(FrameworkVersion.V5_0))]) [] let ``can detect explicit dependencies for FluentAssertions 4``() = @@ -291,7 +292,7 @@ let ``can detect explicit dependencies for FluentAssertions 4``() = |> shouldEqual (PackageName "System.Collections", DependenciesFileParser.parseVersionRequirement(">= 4.0.10"), - FrameworkRestrictionList [FrameworkRestriction.Exactly(DNXCore(FrameworkVersion.V5_0))]) + makeOrList [FrameworkRestriction.AtLeast(DNXCore(FrameworkVersion.V5_0))]) @@ -304,17 +305,14 @@ let ``can detect explicit dependencies for EasyNetQ``() = |> shouldEqual (PackageName "RabbitMQ.Client", DependenciesFileParser.parseVersionRequirement(">= 3.5.7"), - FrameworkRestrictionList []) + makeOrList []) deps.[1] |> shouldEqual (PackageName "Microsoft.Bcl", DependenciesFileParser.parseVersionRequirement(">= 1.1.10"), - FrameworkRestrictionList - [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V1)) - FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V1_1)) - FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V2)) - FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V3)) - FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V3_5)) - FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_Client)) - FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4)) ]) \ No newline at end of file + makeOrList + [FrameworkRestriction.And[ + FrameworkRestriction.NoRestriction + FrameworkRestriction.NotAtLeast(DotNetFramework(FrameworkVersion.V4_5))] + ]) \ No newline at end of file diff --git a/tests/Paket.Tests/Paket.Tests.fsproj b/tests/Paket.Tests/Paket.Tests.fsproj index 659375dd8c..44d6737181 100644 --- a/tests/Paket.Tests/Paket.Tests.fsproj +++ b/tests/Paket.Tests/Paket.Tests.fsproj @@ -96,6 +96,7 @@ + @@ -198,6 +199,7 @@ + diff --git a/tests/Paket.Tests/ProjectFile/ConditionSpecs.fs b/tests/Paket.Tests/ProjectFile/ConditionSpecs.fs index 692588feee..7d33f5aed3 100644 --- a/tests/Paket.Tests/ProjectFile/ConditionSpecs.fs +++ b/tests/Paket.Tests/ProjectFile/ConditionSpecs.fs @@ -11,8 +11,8 @@ let element x = [] let ``should detect framework version from path``() = - FrameworkDetection.DetectFromPath(@"..\RestSharp\lib\net4\RestSharp.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_Client)) - FrameworkDetection.DetectFromPath(@"..\Rx-Main\lib\net40\Rx.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_Client)) + FrameworkDetection.DetectFromPath(@"..\RestSharp\lib\net4\RestSharp.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4)) + FrameworkDetection.DetectFromPath(@"..\Rx-Main\lib\net40\Rx.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4)) FrameworkDetection.DetectFromPath(@"..\Rx-Main\lib\net45\Rx.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_5)) FrameworkDetection.DetectFromPath(@"..\Rx-Main\lib\net20\Rx.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V2)) FrameworkDetection.DetectFromPath(@"..\Rx-Main\lib\net35\Rx.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V3_5)) @@ -28,16 +28,16 @@ let ``should detect CLR version from path``() = [] let ``should detect client framework version from path``() = - FrameworkDetection.DetectFromPath(@"..\packages\Castle.Core\lib\net40-client\Castle.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_Client)) + FrameworkDetection.DetectFromPath(@"..\packages\Castle.Core\lib\net40-client\Castle.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4)) [] let ``should detect client framework version from Lib path``() = - FrameworkDetection.DetectFromPath(@"..\packages\Castle.Core\Lib\net40-client\Castle.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_Client)) + FrameworkDetection.DetectFromPath(@"..\packages\Castle.Core\Lib\net40-client\Castle.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4)) [] let ``should detect net40-full as net40``() = FrameworkDetection.DetectFromPath(@"..\packages\log4net\lib\net40-full\log4net.dll")|> element |> shouldEqual(DotNetFramework(FrameworkVersion.V4)) - FrameworkDetection.DetectFromPath(@"..\packages\log4net\lib\net40\log4net.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_Client)) + FrameworkDetection.DetectFromPath(@"..\packages\log4net\lib\net40\log4net.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4)) [] let ``should detect net451``() = @@ -45,14 +45,15 @@ let ``should detect net451``() = [] let ``should detect Silverlight version from path``() = - FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl5\RestSharp.Silverlight.dll")|> element |> shouldEqual (Silverlight("v5.0")) - FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl4\RestSharp.Silverlight.dll")|> element |> shouldEqual (Silverlight("v4.0")) - FrameworkDetection.DetectFromPath(@"..\..\packages\SpecFlow\lib\sl3\Specflow.Silverlight.dll")|> element |> shouldEqual (Silverlight("v3.0")) + FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl5\RestSharp.Silverlight.dll")|> element |> shouldEqual (Silverlight SilverlightVersion.V5) + FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl4\RestSharp.Silverlight.dll")|> element |> shouldEqual (Silverlight SilverlightVersion.V4) + FrameworkDetection.DetectFromPath(@"..\..\packages\SpecFlow\lib\sl3\Specflow.Silverlight.dll")|> element |> shouldEqual (Silverlight SilverlightVersion.V3) [] let ``should detect WindowsPhone version from path``() = - FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl4-wp71\RestSharp.WindowsPhone.dll")|> element |> shouldEqual (WindowsPhoneSilverlight("v7.1")) - FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl4-wp\TechTalk.SpecFlow.WindowsPhone7.dll")|> element |> shouldEqual (WindowsPhoneSilverlight("v7.1")) + FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl4-wp75\RestSharp.WindowsPhone.dll")|> element |> shouldEqual (WindowsPhone WindowsPhoneVersion.V7_5) + FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl4-wp71\RestSharp.WindowsPhone.dll")|> element |> shouldEqual (WindowsPhone WindowsPhoneVersion.V7_1) + FrameworkDetection.DetectFromPath(@"..\..\packages\RestSharp\lib\sl4-wp\TechTalk.SpecFlow.WindowsPhone7.dll")|> element |> shouldEqual (WindowsPhone WindowsPhoneVersion.V7_1) [] let ``should detect framework version from uppercase path``() = @@ -73,6 +74,6 @@ let ``should detect with spaces``() = [] let ``should detect 35, 40 and 45``() = FrameworkDetection.DetectFromPath(@"..\packages\FSharpx.Core\lib\35\FSharp.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V3_5)) - FrameworkDetection.DetectFromPath(@"..\packages\FSharpx.Core\lib\40\FSharp.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_Client)) + FrameworkDetection.DetectFromPath(@"..\packages\FSharpx.Core\lib\40\FSharp.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4)) FrameworkDetection.DetectFromPath(@"..\packages\FSharpx.Core\lib\45\FSharp.Core.dll")|> element |> shouldEqual (DotNetFramework(FrameworkVersion.V4_5)) \ No newline at end of file diff --git a/tests/Paket.Tests/ProjectFile/OutputSpecs.fs b/tests/Paket.Tests/ProjectFile/OutputSpecs.fs index ffc08e0357..555d56994f 100644 --- a/tests/Paket.Tests/ProjectFile/OutputSpecs.fs +++ b/tests/Paket.Tests/ProjectFile/OutputSpecs.fs @@ -36,7 +36,7 @@ let ``should detect target framework for Project1 proj file``() = let ``should detect target framework for Project2 proj file``() = ensureDir () ProjectFile.TryLoad("./ProjectFile/TestData/Project2.fsprojtest").Value.GetTargetProfile() - |> shouldEqual (SinglePlatform(DotNetFramework(FrameworkVersion.V4_Client))) + |> shouldEqual (SinglePlatform(DotNetFramework(FrameworkVersion.V4))) [] let ``should detect output path for proj file`` diff --git a/tests/Paket.Tests/ProjectFile/TargetFrameworkSpecs.fs b/tests/Paket.Tests/ProjectFile/TargetFrameworkSpecs.fs index d11024a365..8d8e070229 100644 --- a/tests/Paket.Tests/ProjectFile/TargetFrameworkSpecs.fs +++ b/tests/Paket.Tests/ProjectFile/TargetFrameworkSpecs.fs @@ -5,30 +5,37 @@ open NUnit.Framework open FsUnit open Paket.TestHelpers -let TestData: obj[][] = +let portable = TargetProfile.FindPortable [ DotNetFramework FrameworkVersion.V4_5; Windows WindowsVersion.V8; WindowsPhone WindowsPhoneVersion.V8; WindowsPhoneApp WindowsPhoneAppVersion.V8_1 ] + +let TestData: obj[][] = [| // project file name, // expected TargetProfile // expected TargetProfile.ToString // expected TargetFramework [|"Project2.fsprojtest"; - (SinglePlatform(DotNetFramework FrameworkVersion.V4_Client)); + (SinglePlatform(DotNetFramework FrameworkVersion.V4)); "net40"; - (Some(DotNetFramework FrameworkVersion.V4_Client))|]; + (DotNetFramework FrameworkVersion.V4)|]; [|"Empty.fsprojtest"; (SinglePlatform(DotNetFramework FrameworkVersion.V4)); - "net40-full"; - (Some(DotNetFramework FrameworkVersion.V4))|]; + "net40"; + (DotNetFramework FrameworkVersion.V4)|]; [|"NewSilverlightClassLibrary.csprojtest"; - (SinglePlatform(Silverlight("v5.0"))); - "sl50"; - (Some(Silverlight "v5.0"))|]; + (SinglePlatform(Silverlight SilverlightVersion.V5)); + "sl5"; + (Silverlight SilverlightVersion.V5)|]; [|"FSharp.Core.Fluent-3.1.fsprojtest"; - (PortableProfile("Profile259", [ DotNetFramework FrameworkVersion.V4_5; Windows "v4.5"; WindowsPhoneSilverlight "v8.0"; WindowsPhoneApp "v8.1" ])); - "portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1"; - (Some(DotNetFramework FrameworkVersion.V4_5))|]; + portable; + "portable-net45+win8+wp8+wpa81"; + (DotNetFramework FrameworkVersion.V4_5)|]; |] - + +[] +let ``should detect profile259`` () = + portable + |> shouldEqual (PortableProfile PortableProfileType.Profile259) + [] [] let ``should detect the correct framework on test projects`` projectFile expectedProfile expectedProfileString expectedTargetFramework = @@ -36,5 +43,4 @@ let ``should detect the correct framework on test projects`` projectFile expecte let p = ProjectFile.TryLoad("./ProjectFile/TestData/" + projectFile).Value p.GetTargetProfile() |> shouldEqual expectedProfile p.GetTargetProfile().ToString() |> shouldEqual expectedProfileString - p.GetTargetFramework() |> shouldEqual expectedTargetFramework diff --git a/tests/Paket.Tests/ReferencesFile/ReferencesFileSpecs.fs b/tests/Paket.Tests/ReferencesFile/ReferencesFileSpecs.fs index c5e07960fc..56a09929f1 100644 --- a/tests/Paket.Tests/ReferencesFile/ReferencesFileSpecs.fs +++ b/tests/Paket.Tests/ReferencesFile/ReferencesFileSpecs.fs @@ -230,31 +230,36 @@ xUnit import_targets: false""" |> shouldEqual (normalizeLineEndings expected) -let refFileContentWithMultipleSettings = """Castle.Windsor copy_local: false, import_targets: false, framework: net35, >= net40 +let legacyRefFileContentWithMultipleSettings = """Castle.Windsor copy_local: false, import_targets: false, framework: net35, >= net40 Newtonsoft.Json content: none, framework: net40 xUnit import_targets: false""" +let refFileContentWithMultipleSettings = """Castle.Windsor copy_local: false, import_targets: false, restriction: || (== net35) (>= net40) +Newtonsoft.Json content: none, restriction: == net40 +xUnit import_targets: false""" + [] let ``should parse and serialize lines with multiple settings settings correctly``() = - let refFile = ReferencesFile.FromLines(toLines refFileContentWithMultipleSettings) - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Length |> shouldEqual 3 - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Head.Name |> shouldEqual (PackageName "Castle.Windsor") - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Head.Settings.CopyLocal |> shouldEqual (Some false) - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Head.Settings.ImportTargets |> shouldEqual (Some false) - - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Name |> shouldEqual (PackageName "Newtonsoft.Json") - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Settings.CopyLocal |> shouldEqual None - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Settings.ImportTargets |> shouldEqual None - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Settings.OmitContent |> shouldEqual (Some ContentCopySettings.Omit) - - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Name |> shouldEqual (PackageName "xUnit") - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Settings.CopyLocal |> shouldEqual None - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Settings.ImportTargets |> shouldEqual (Some false) - refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Settings.OmitContent |> shouldEqual None - - refFile.ToString() - |> normalizeLineEndings - |> shouldEqual (normalizeLineEndings refFileContentWithMultipleSettings) + for refFileContent in [legacyRefFileContentWithMultipleSettings; refFileContentWithMultipleSettings] do + let refFile = ReferencesFile.FromLines(toLines refFileContent) + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Length |> shouldEqual 3 + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Head.Name |> shouldEqual (PackageName "Castle.Windsor") + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Head.Settings.CopyLocal |> shouldEqual (Some false) + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Head.Settings.ImportTargets |> shouldEqual (Some false) + + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Name |> shouldEqual (PackageName "Newtonsoft.Json") + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Settings.CopyLocal |> shouldEqual None + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Settings.ImportTargets |> shouldEqual None + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Head.Settings.OmitContent |> shouldEqual (Some ContentCopySettings.Omit) + + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Name |> shouldEqual (PackageName "xUnit") + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Settings.CopyLocal |> shouldEqual None + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Settings.ImportTargets |> shouldEqual (Some false) + refFile.Groups.[Constants.MainDependencyGroup].NugetPackages.Tail.Tail.Head.Settings.OmitContent |> shouldEqual None + + refFile.ToString() + |> normalizeLineEndings + |> shouldEqual (normalizeLineEndings refFileContentWithMultipleSettings) [] diff --git a/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs b/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs index 4be4207423..55e39c6d35 100644 --- a/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs +++ b/tests/Paket.Tests/Resolver/ConflictGraphSpecs.fs @@ -28,7 +28,7 @@ let graph = let defaultPackage = { Name = PackageName "" Parent = PackageRequirementSource.DependenciesFile "" - Graph = [] + Graph = Set.empty Sources = [] VersionRequirement = VersionRequirement(VersionRange.Exactly "1.0", PreReleaseStatus.No) Settings = InstallSettings.Default diff --git a/tests/Paket.Tests/Resolver/ConflictSourcesSpecs.fs b/tests/Paket.Tests/Resolver/ConflictSourcesSpecs.fs index ee229ed8da..25bf4baa81 100644 --- a/tests/Paket.Tests/Resolver/ConflictSourcesSpecs.fs +++ b/tests/Paket.Tests/Resolver/ConflictSourcesSpecs.fs @@ -23,7 +23,7 @@ let ``should resolve source files with correct sha``() = { Name = name ResolverStrategyForDirectDependencies = Some ResolverStrategy.Max ResolverStrategyForTransitives = Some ResolverStrategy.Max - Graph = [] + Graph = Set.empty Sources = [] Parent = Requirements.PackageRequirementSource.DependenciesFile "" Settings = InstallSettings.Default diff --git a/tests/Paket.Tests/Resolver/DependencyGroupsAndRestrictions.fs b/tests/Paket.Tests/Resolver/DependencyGroupsAndRestrictions.fs index 2c0d7a73fd..22502d58ec 100644 --- a/tests/Paket.Tests/Resolver/DependencyGroupsAndRestrictions.fs +++ b/tests/Paket.Tests/Resolver/DependencyGroupsAndRestrictions.fs @@ -6,10 +6,11 @@ open FsUnit open TestHelpers open Paket.Domain open Paket.PackageResolver +open Paket.Requirements let resolve graph updateMode (cfg : DependenciesFile) = let groups = [Constants.MainDependencyGroup, None ] |> Map.ofSeq - cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph,PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() + cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph, (fun _ _ _ _ -> []),PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() let graph1 = GraphOfNuspecs [ @@ -216,8 +217,47 @@ nuget Marten""" getVersion resolved.[PackageName "Npgsql"] |> shouldEqual "3.1.4" let graph6 = - graph1 @ GraphOfNuspecs [ + """ + + + Chessie + 0.6.0 + + + + + + + + + + + + + + + """ + """ + + + FSharp.Core + 4.0.0.1 + + + """ + """ + + + FSharp.Core + 4.0.1.7-alpha + + + + + + +""" """ @@ -253,12 +293,251 @@ nuget Chessie""" getVersion netStandard |> shouldEqual "1.6.0" // Don't install netstandard to net45 Requirements.isTargetMatchingRestrictions - (Requirements.getRestrictionList netStandard.Settings.FrameworkRestrictions, + (Requirements.getExplicitRestriction netStandard.Settings.FrameworkRestrictions, (TargetProfile.SinglePlatform (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_5))) |> shouldEqual false // Don't install netstandard to net463 Requirements.isTargetMatchingRestrictions - (Requirements.getRestrictionList netStandard.Settings.FrameworkRestrictions, + (Requirements.getExplicitRestriction netStandard.Settings.FrameworkRestrictions, (TargetProfile.SinglePlatform (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4_6_3))) |> shouldEqual false - // This also tests that "UnknownPackage" is not pulled unexpectedly (because this dependency is never relevant) \ No newline at end of file + // This also tests that "UnknownPackage" is not pulled unexpectedly (because this dependency is never relevant) + + + +let graph7 = + GraphOfNuspecs [ + """ + + + Nancy.Serialization.JsonNet + 1.4.1 + Andreas Håkansson, Steven Robbins and contributors + Andreas Håkansson, Steven Robbins and contributors + https://github.com/NancyFx/Nancy.Serialization.JsonNet/blob/master/license.txt + http://nancyfx.org + http://nancyfx.org/nancy-nuget.png + false + Provides JSON (de)serialization support using Newtonsoft.JsonNet. + Nancy is a lightweight web framework for the .Net platform, inspired by Sinatra. Nancy aim at delivering a low ceremony approach to building light, fast web applications. + Andreas Håkansson, Steven Robbins and contributors + en-US + Nancy Json JsonNet + + + + + + + """ + """ + + + Newtonsoft.Json + 10.0.2 + Json.NET + James Newton-King + James Newton-King + false + https://raw.github.com/JamesNK/Newtonsoft.Json/master/LICENSE.md + http://www.newtonsoft.com/json + http://www.newtonsoft.com/content/images/nugeticon.png + Json.NET is a popular high-performance JSON framework for .NET + en-US + json + + + + + + + + + + + + + + + + + + + + + + + + + """ + """ + + + Nancy + 1.4.3 + Andreas Håkansson, Steven Robbins and contributors + Andreas Håkansson, Steven Robbins and contributors + https://github.com/NancyFx/Nancy/blob/master/license.txt + http://nancyfx.org + http://nancyfx.org/nancy-nuget.png + false + Nancy is a lightweight web framework for the .Net platform, inspired by Sinatra. Nancy aim at delivering a low ceremony approach to building light, fast web applications. + Nancy is a lightweight web framework for the .Net platform, inspired by Sinatra. Nancy aim at delivering a low ceremony approach to building light, fast web applications. + Andreas Håkansson, Steven Robbins and contributors + en-US + Nancy + + + """ ] + +[] +let ``i001213 should not delegate restriction of transitive when globally no restriction is given``() = + let config = """ +framework: >= net40 + +source https://nuget.org/api/v2 + +nuget Newtonsoft.Json redirects: on +nuget Nancy.Serialization.JsonNet ~> 1.2 framework: >= net451""" + let resolved = + DependenciesFile.FromSource(config) + |> resolve graph7 UpdateMode.UpdateAll + let newtonsoft = resolved.[PackageName "Newtonsoft.Json"] + let nancy = resolved.[PackageName "Nancy.Serialization.JsonNet"] + getVersion newtonsoft |> shouldEqual "10.0.2" + getVersion nancy |> shouldEqual "1.4.1" + + (FrameworkRestriction.AtLeast (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4)).IsSubsetOf + (Requirements.getExplicitRestriction newtonsoft.Settings.FrameworkRestrictions) + |> shouldEqual true + + // install netstandard to net40 + Requirements.isTargetMatchingRestrictions + (Requirements.getExplicitRestriction newtonsoft.Settings.FrameworkRestrictions, + (TargetProfile.SinglePlatform (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4))) + |> shouldEqual true +[] +let ``i001213 should delegate restriction of transitive when package is not given``() = + let config = """ +framework: >= net40 + +source https://nuget.org/api/v2 + +nuget Nancy.Serialization.JsonNet ~> 1.2 framework: >= net451""" + let resolved = + DependenciesFile.FromSource(config) + |> resolve graph7 UpdateMode.UpdateAll + let newtonsoft = resolved.[PackageName "Newtonsoft.Json"] + let nancy = resolved.[PackageName "Nancy.Serialization.JsonNet"] + getVersion newtonsoft |> shouldEqual "10.0.2" + getVersion nancy |> shouldEqual "1.4.1" + + // don't install newtonsoft to net40, because restriction should be propagated. + Requirements.isTargetMatchingRestrictions + (Requirements.getExplicitRestriction newtonsoft.Settings.FrameworkRestrictions, + (TargetProfile.SinglePlatform (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4))) + |> shouldEqual false + + + + +let graph8 = + GraphOfNuspecs [ + """ + + + MathNet.Numerics.FSharp + 3.2.3 + Math.NET Numerics for F# + Christoph Ruegg, Marcus Cuda, Jurgen Van Gael + Christoph Ruegg, Marcus Cuda, Jurgen Van Gael + http://numerics.mathdotnet.com/docs/License.html + http://numerics.mathdotnet.com/ + http://www.mathdotnet.com/images/MathNet128.png + false + Math.NET Numerics is the numerical foundation of the Math.NET project, aiming to provide methods and algorithms for numerical computations in science, engineering and every day use. Supports F# 3.0 on .Net 4.0, .Net 3.5 and Mono on Windows, Linux and Mac; Silverlight 5, WindowsPhone/SL 8, WindowsPhone 8.1 and Windows 8 with PCL Portable Profiles 47 and 328; Android/iOS with Xamarin. + F# Modules for Math.NET Numerics, providing methods and algorithms for numerical computations in science, engineering and every day use. + Bug fix: MatrixNormal distribution: density for non-square matrices ~Evelina Gabasova + fsharp F# math numeric statistics probability integration interpolation regression solve fit linear algebra matrix fft + + + + + + + + + """ + """ + + + MathNet.Numerics + 3.2.3 + Math.NET Numerics + Christoph Ruegg, Marcus Cuda, Jurgen Van Gael + Christoph Ruegg, Marcus Cuda, Jurgen Van Gael + http://numerics.mathdotnet.com/docs/License.html + http://numerics.mathdotnet.com/ + http://www.mathdotnet.com/images/MathNet128.png + false + Math.NET Numerics is the numerical foundation of the Math.NET project, aiming to provide methods and algorithms for numerical computations in science, engineering and every day use. Supports .Net 4.0, .Net 3.5 and Mono on Windows, Linux and Mac; Silverlight 5, WindowsPhone/SL 8, WindowsPhone 8.1 and Windows 8 with PCL Portable Profiles 47 and 328; Android/iOS with Xamarin. + Math.NET Numerics, providing methods and algorithms for numerical computations in science, engineering and every day use. + Bug fix: MatrixNormal distribution: density for non-square matrices ~Evelina Gabasova + math numeric statistics probability integration interpolation regression solve fit linear algebra matrix fft + + + + + + + + + + + + """ + """ + + + 1.0.2856.0 + Microsoft Corporation + Microsoft Corporation + http://go.microsoft.com/fwlink/?LinkID=186234 + http://msdn.microsoft.com/en-us/library/dd460717.aspx + http://i.msdn.microsoft.com/ee402630.NET_lg.png + TaskParallelLibrary + Task Parallel Library for .NET 3.5 + true + The package includes: +* Task<T> for executing asynchronous operations. +* Concurrent Collections such as ConcurrentStack, ConcurentQueue ad ConcurrentDictionary. +* PLINQ for writing parallel queries. +* additional Threading operations such as Barrier,SpinLock and SpinWait. + A complete and official Microsoft backport of the Task Parallel Library (TPL) for .NET 3.5. + This backport was shipped with the Reactive Extensions (Rx) library up until v1.0.2856.0. It can be downloaded from http://www.microsoft.com/download/en/details.aspx?id=24940 . + en-us + tpl plinq pfx task parallel extensions .net35 backport + + + """ + ] + +[] +let ``i000140 should properly resolve framework dependent dependencies``() = + let config = """ +source https://nuget.org/api/v2 + +nuget MathNet.Numerics.FSharp ~> 3.2.1""" + let resolved = + DependenciesFile.FromSource(config) + |> resolve graph8 UpdateMode.UpdateAll + let tpl = resolved.[PackageName "TaskParallelLibrary"] + let numeric = resolved.[PackageName "MathNet.Numerics"] + getVersion numeric |> shouldEqual "3.2.3" + getVersion tpl |> shouldEqual "1.0.2856.0" + + // don't install tpl to net40, because restriction should be propagated. + Requirements.isTargetMatchingRestrictions + (Requirements.getExplicitRestriction tpl.Settings.FrameworkRestrictions, + (TargetProfile.SinglePlatform (FrameworkIdentifier.DotNetFramework FrameworkVersion.V4))) + |> shouldEqual false diff --git a/tests/Paket.Tests/Resolver/GlobalOptimisticStrategySpecs.fs b/tests/Paket.Tests/Resolver/GlobalOptimisticStrategySpecs.fs index 5a6521bd79..dd83cc0375 100644 --- a/tests/Paket.Tests/Resolver/GlobalOptimisticStrategySpecs.fs +++ b/tests/Paket.Tests/Resolver/GlobalOptimisticStrategySpecs.fs @@ -9,7 +9,7 @@ open Paket.PackageResolver let resolve graph updateMode (cfg : DependenciesFile) = let groups = [Constants.MainDependencyGroup, None ] |> Map.ofSeq - cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph,PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() + cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph, (fun _ _ _ _ -> []),PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() let graph = OfSimpleGraph [ diff --git a/tests/Paket.Tests/Resolver/GlobalPessimisticStrategySpecs.fs b/tests/Paket.Tests/Resolver/GlobalPessimisticStrategySpecs.fs index 43c489c4f0..bf0b047c23 100644 --- a/tests/Paket.Tests/Resolver/GlobalPessimisticStrategySpecs.fs +++ b/tests/Paket.Tests/Resolver/GlobalPessimisticStrategySpecs.fs @@ -9,7 +9,7 @@ open Paket.PackageResolver let resolve graph updateMode (cfg : DependenciesFile) = let groups = [Constants.MainDependencyGroup, None ] |> Map.ofSeq - cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph,PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() + cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph, (fun _ _ _ _ -> []),PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() let graph = OfSimpleGraph [ diff --git a/tests/Paket.Tests/Resolver/PropertyTests.fs b/tests/Paket.Tests/Resolver/PropertyTests.fs index f984625142..a270cb2703 100644 --- a/tests/Paket.Tests/Resolver/PropertyTests.fs +++ b/tests/Paket.Tests/Resolver/PropertyTests.fs @@ -135,7 +135,7 @@ let ``if it resolves then, it should satisfy all deps. if not we have a real con failwithf "brute force found %A" resolution let conflicts = conflict.GetConflicts() - conflicts |> List.isEmpty |> not + conflicts |> Set.isEmpty |> not with | exn when exn.Message.Contains "brute force" |> not -> match bruteForce (g,deps) with diff --git a/tests/Paket.Tests/Resolver/ResolverRestrictionTests.fs b/tests/Paket.Tests/Resolver/ResolverRestrictionTests.fs new file mode 100644 index 0000000000..60714bf653 --- /dev/null +++ b/tests/Paket.Tests/Resolver/ResolverRestrictionTests.fs @@ -0,0 +1,2 @@ +module ResolverRestrictionTests + diff --git a/tests/Paket.Tests/Resolver/StrategySpecs.fs b/tests/Paket.Tests/Resolver/StrategySpecs.fs index 5796227756..8be2e207d8 100644 --- a/tests/Paket.Tests/Resolver/StrategySpecs.fs +++ b/tests/Paket.Tests/Resolver/StrategySpecs.fs @@ -9,7 +9,7 @@ open Paket.PackageResolver let resolve graph updateMode (cfg : DependenciesFile) = let groups = [Constants.MainDependencyGroup, None ] |> Map.ofSeq - cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph,PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() + cfg.Resolve(true,noSha1,VersionsFromGraphAsSeq graph, (fun _ _ _ _ -> []),PackageDetailsFromGraph graph,(fun _ _ -> None),groups,updateMode).[Constants.MainDependencyGroup].ResolvedPackages.GetModelOrFail() let graph = OfSimpleGraph [ diff --git a/tests/Paket.Tests/Simplifier/BasicScenarioSpecs.fs b/tests/Paket.Tests/Simplifier/BasicScenarioSpecs.fs index eca8760ae2..f5e93c6bcd 100644 --- a/tests/Paket.Tests/Simplifier/BasicScenarioSpecs.fs +++ b/tests/Paket.Tests/Simplifier/BasicScenarioSpecs.fs @@ -191,6 +191,7 @@ nuget C 1.0""" |> shouldEqual (normalizeLineEndings expected) [] +[] let ``should simplify framework restrictions in main group``() = let before = """source https://www.nuget.org/api/v2/ @@ -204,7 +205,7 @@ nuget Autofac.WebApi2 3.4.0 framework: >= net45 nuget Autofac.WebApi2.Owin 3.2.0 framework: >= net45""" let expected = """source https://www.nuget.org/api/v2/ -framework >= net45 +restriction: >= net45 nuget angularjs 1.4.3 nuget AngularTemplates.Compile 1.0.0 @@ -233,6 +234,16 @@ nuget Autofac.Owin 3.1.0 framework: >= net40 nuget Autofac.WebApi 3.1.0 framework: >= net45 nuget Autofac.WebApi2 3.4.0 framework: >= net45 nuget Autofac.WebApi2.Owin 3.2.0 framework: >= net45""" + let after = """source https://www.nuget.org/api/v2/ + +nuget angularjs 1.4.3 restriction: >= net45 +nuget AngularTemplates.Compile 1.0.0 restriction: >= net45 +nuget Antlr 3.4.1.9004 restriction: >= net45 +nuget Autofac 3.5.0 restriction: >= net45 +nuget Autofac.Owin 3.1.0 restriction: >= net40 +nuget Autofac.WebApi 3.1.0 restriction: >= net45 +nuget Autofac.WebApi2 3.4.0 restriction: >= net45 +nuget Autofac.WebApi2.Owin 3.2.0 restriction: >= net45""" let originalLockFile = DependenciesFile.FromSource(before) originalLockFile.SimplifyFrameworkRestrictions().ToString() @@ -240,6 +251,7 @@ nuget Autofac.WebApi2.Owin 3.2.0 framework: >= net45""" |> shouldEqual (normalizeLineEndings before) [] +[] let ``should simplify framework restrictions in every group``() = let before = """source https://www.nuget.org/api/v2/ @@ -256,7 +268,7 @@ nuget Autofac.WebApi2 3.4.0 framework: >= net40 nuget Autofac.WebApi2.Owin 3.2.0 framework: >= net40""" let expected = """source https://www.nuget.org/api/v2/ -framework >= net45 +restriction: >= net45 nuget angularjs 1.4.3 nuget AngularTemplates.Compile 1.0.0 @@ -265,7 +277,7 @@ nuget Autofac 3.5.0 group Build source https://www.nuget.org/api/v2/ -framework >= net40 +restriction: >= net40 nuget Autofac.Owin 3.1.0 nuget Autofac.WebApi 3.1.0 nuget Autofac.WebApi2 3.4.0 @@ -285,8 +297,9 @@ let ``should not simplify framework restrictions in empty file``() = originalLockFile.SimplifyFrameworkRestrictions().ToString() |> normalizeLineEndings |> shouldEqual (normalizeLineEndings before) - + [] +[] let ``should simplify multiple framework restrictions in every group``() = let before = """source https://www.nuget.org/api/v2/ @@ -303,7 +316,7 @@ nuget Autofac.WebApi2 3.4.0 framework: sl5, sl4 nuget Autofac.WebApi2.Owin 3.2.0 framework: sl4, sl5""" let expected = """source https://www.nuget.org/api/v2/ -framework net40, net45 +restriction: || (net40) (net45) nuget angularjs 1.4.3 nuget AngularTemplates.Compile 1.0.0 @@ -312,7 +325,8 @@ nuget Autofac 3.5.0 group Build source https://www.nuget.org/api/v2/ -framework sl40, sl50 +restriction: || (sl40) (sl50) + nuget Autofac.Owin 3.1.0 nuget Autofac.WebApi 3.1.0 nuget Autofac.WebApi2 3.4.0 @@ -325,6 +339,7 @@ nuget Autofac.WebApi2.Owin 3.2.0""" |> shouldEqual (normalizeLineEndings expected) [] +[] let ``should simplify subset of framework restrictions in every group``() = let before = """source https://www.nuget.org/api/v2/ @@ -341,19 +356,19 @@ nuget Autofac.WebApi2 3.4.0 framework: sl5, sl4, >= net45 nuget Autofac.WebApi2.Owin 3.2.0 framework: sl4, sl5""" let expected = """source https://www.nuget.org/api/v2/ -framework net40, net45 +restriction: || (net40) (net45) -nuget angularjs 1.4.3 framework: net20 +nuget angularjs 1.4.3 restriction: net20 nuget AngularTemplates.Compile 1.0.0 nuget Antlr 3.4.1.9004 nuget Autofac 3.5.0 group Build source https://www.nuget.org/api/v2/ -framework sl40, sl50 +restriction: || (sl4) (sl5) nuget Autofac.Owin 3.1.0 nuget Autofac.WebApi 3.1.0 -nuget Autofac.WebApi2 3.4.0 framework: >= net45 +nuget Autofac.WebApi2 3.4.0 restriction: >= net45 nuget Autofac.WebApi2.Owin 3.2.0""" diff --git a/tests/Paket.Tests/TestHelpers.fs b/tests/Paket.Tests/TestHelpers.fs index a00c3aa59b..0e2087b655 100644 --- a/tests/Paket.Tests/TestHelpers.fs +++ b/tests/Paket.Tests/TestHelpers.fs @@ -9,6 +9,15 @@ open System.Xml open System.IO open Paket.Domain +let makeOrList (l:_ list) = + if l.IsEmpty then FrameworkRestriction.NoRestriction + else Seq.fold FrameworkRestriction.combineRestrictionsWithOr FrameworkRestriction.EmptySet l + |> ExplicitRestriction + +let getPortableRestriction s = + let pf = PlatformMatching.extractPlatforms s + FrameworkRestriction.AtLeastPortable(s, pf.Value.Platforms) + type GraphDependency = string * VersionRequirement * FrameworkRestrictions type DependencyGraph = list @@ -16,7 +25,7 @@ type DependencyGraph = list) : DependencyGraph = g |> Seq.map (fun (x, y, (rqs)) -> - x, y, rqs |> List.map (fun (a,b) -> (a, b, FrameworkRestrictionList [])), RuntimeGraph.Empty) + x, y, rqs |> List.map (fun (a,b) -> (a, b, ExplicitRestriction FrameworkRestriction.NoRestriction)), RuntimeGraph.Empty) |> Seq.toList let OfGraphWithRestriction (g:seq) : DependencyGraph = @@ -35,7 +44,7 @@ let GraphOfNuspecs (g:seq) : DependencyGraph = let OfGraphWithRuntimeDeps (g:seq) : DependencyGraph = g |> Seq.map (fun (x, y, rqs, run) -> - x, y, rqs |> List.map (fun (a,b) -> (a, b, FrameworkRestrictionList [])), run) + x, y, rqs |> List.map (fun (a,b) -> (a, b, ExplicitRestriction FrameworkRestriction.NoRestriction)), run) |> Seq.toList @@ -52,18 +61,17 @@ let PackageDetailsFromGraph (graph : DependencyGraph) sources groupName (package LicenseUrl = "" Unlisted = false DirectDependencies = Set.ofList dependencies } + |> async.Return -let VersionsFromGraph (graph : DependencyGraph) sources resolverStrategy groupName packageName = +let VersionsFromGraph (graph : DependencyGraph) sources groupName packageName = let versions = graph |> Seq.filter (fun (p, _, _, _) -> (PackageName p) = packageName) |> Seq.map (fun (_, v, _, _) -> SemVer.Parse v) - |> Seq.toList - |> List.map (fun v -> v,sources) + |> Seq.map (fun v -> v,sources) - match resolverStrategy with - | ResolverStrategy.Max -> List.sortDescending versions - | ResolverStrategy.Min -> List.sort versions + versions + |> async.Return let GetRuntimeGraphFromGraph (graph : DependencyGraph) groupName (package:ResolvedPackage) = graph @@ -75,9 +83,8 @@ let GetRuntimeGraphFromGraph (graph : DependencyGraph) groupName (package:Resolv |> Some -let VersionsFromGraphAsSeq (graph : DependencyGraph) sources resolverStrategy groupName packageName = - VersionsFromGraph graph sources resolverStrategy groupName packageName - |> Seq.ofList +let VersionsFromGraphAsSeq (graph : DependencyGraph) sources groupName packageName = + VersionsFromGraph graph sources groupName packageName let safeResolve graph (dependencies : (string * VersionRange) list) = let sources = [ PackageSource.NuGetV2Source "" ] @@ -87,20 +94,20 @@ let safeResolve graph (dependencies : (string * VersionRange) list) = { Name = PackageName n VersionRequirement = VersionRequirement(v, PreReleaseStatus.No) Parent = PackageRequirementSource.DependenciesFile "" - Graph = [] + Graph = Set.empty Sources = sources Settings = InstallSettings.Default ResolverStrategyForDirectDependencies = Some ResolverStrategy.Max ResolverStrategyForTransitives = Some ResolverStrategy.Max }) |> Set.ofList - PackageResolver.Resolve(VersionsFromGraphAsSeq graph, PackageDetailsFromGraph graph, Constants.MainDependencyGroup, None, None, FrameworkRestrictionList [], packages, UpdateMode.UpdateAll) + PackageResolver.Resolve(VersionsFromGraphAsSeq graph, (fun _ _ _ _ -> []), PackageDetailsFromGraph graph, Constants.MainDependencyGroup, None, None, ExplicitRestriction FrameworkRestriction.NoRestriction, packages, UpdateMode.UpdateAll) let resolve graph dependencies = (safeResolve graph dependencies).GetModelOrFail() let ResolveWithGraphR(dependenciesFile:DependenciesFile,getSha1,getVersionsF, getPackageDetailsF, getRuntimeGraph) = let groups = [Constants.MainDependencyGroup, None ] |> Map.ofSeq - dependenciesFile.Resolve(true,getSha1,getVersionsF,getPackageDetailsF,getRuntimeGraph,groups,UpdateMode.UpdateAll) + dependenciesFile.Resolve(true,getSha1,getVersionsF,(fun _ _ _ _ -> []),getPackageDetailsF,getRuntimeGraph,groups,UpdateMode.UpdateAll) let ResolveWithGraph(dependenciesFile:DependenciesFile,getSha1,getVersionsF, getPackageDetailsF) = ResolveWithGraphR(dependenciesFile,getSha1,getVersionsF, getPackageDetailsF, (fun _ _ -> None)) diff --git a/tests/Paket.Tests/Versioning/DependencySetSpecs.fs b/tests/Paket.Tests/Versioning/DependencySetSpecs.fs index f24b2ed2fb..4dd06f261a 100644 --- a/tests/Paket.Tests/Versioning/DependencySetSpecs.fs +++ b/tests/Paket.Tests/Versioning/DependencySetSpecs.fs @@ -8,262 +8,210 @@ open FsUnit open Paket.PackageResolver open Paket.Requirements open Paket.Domain - -[] -let ``should optimize 2 restriction set with only exactly``() = - let original = - [PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P2"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))]] - - let expected = - [PackageName("P1"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P2"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))]] - - original - |> optimizeDependencies - |> shouldEqual expected - -[] -let ``should optimize 2 restriction set with only exactly and client framework``() = - let original = - [PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_Client))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P2"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))]] - - let expected = - [PackageName("P1"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P2"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))]] - - original - |> optimizeDependencies - |> shouldEqual expected - -[] -let ``should optimize 2 restriction sets with between``() = - let original = - [PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P2"), VersionRequirement.AllReleases, [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_Client))]] - - let expected = - [PackageName("P1"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P2"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_Client))]] - - original - |> optimizeDependencies - |> shouldEqual expected +open Paket.TestHelpers [] let ``empty set filtered with empty restrictions should give empty set``() = Set.empty - |> DependencySetFilter.filterByRestrictions (FrameworkRestrictionList []) + |> DependencySetFilter.filterByRestrictions (ExplicitRestriction FrameworkRestriction.NoRestriction) |> shouldEqual Set.empty [] let ``filtered with empty restrictions should give full set``() = let set = - [PackageName("P1"), VersionRequirement.AllReleases, FrameworkRestrictionList [] - PackageName("P2"), VersionRequirement.AllReleases, FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P3"), VersionRequirement.AllReleases, FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))]] + [PackageName("P1"), VersionRequirement.AllReleases, ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P2"), VersionRequirement.AllReleases, ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P3"), VersionRequirement.AllReleases, ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5)))] |> Set.ofList set - |> DependencySetFilter.filterByRestrictions (FrameworkRestrictionList []) + |> DependencySetFilter.filterByRestrictions (ExplicitRestriction FrameworkRestriction.NoRestriction) |> shouldEqual set [] let ``filtered with empty should not remove netstandard``() = let set = - [PackageName("P1"), VersionRequirement.AllReleases, FrameworkRestrictionList [] - PackageName("P2"), VersionRequirement.AllReleases, FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P3"), VersionRequirement.AllReleases, FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)); FrameworkRestriction.Exactly (DotNetStandard(DotNetStandardVersion.V1_3))]] + [PackageName("P1"), VersionRequirement.AllReleases, ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P2"), VersionRequirement.AllReleases, ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P3"), VersionRequirement.AllReleases, makeOrList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)); FrameworkRestriction.Exactly (DotNetStandard(DotNetStandardVersion.V1_3))]] |> Set.ofList set - |> DependencySetFilter.filterByRestrictions (FrameworkRestrictionList []) + |> DependencySetFilter.filterByRestrictions (ExplicitRestriction FrameworkRestriction.NoRestriction) |> shouldEqual set [] let ``filtered with concrete restriction should filter non-matching``() = let original = - [PackageName("P1"), VersionRequirement.AllReleases,FrameworkRestrictionList [] - PackageName("P2"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P3"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P4"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P5"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P6"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P7"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3),DotNetFramework(FrameworkVersion.V3_5))]] + [PackageName("P1"), VersionRequirement.AllReleases,ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P2"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P3"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P4"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P5"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P6"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P7"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3),DotNetFramework(FrameworkVersion.V3_5)))] |> Set.ofList let expected = - [PackageName("P1"), VersionRequirement.AllReleases,FrameworkRestrictionList [] - PackageName("P2"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P6"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))]] + [PackageName("P1"), VersionRequirement.AllReleases,ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P2"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P6"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2)))] |> Set.ofList original - |> DependencySetFilter.filterByRestrictions (FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))]) + |> DependencySetFilter.filterByRestrictions (ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4)))) |> shouldEqual expected [] let ``filtered with AtLeast restriction should filter non-matching``() = let original = - [PackageName("P1"), VersionRequirement.AllReleases,FrameworkRestrictionList [] - PackageName("P2"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P3"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P4"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P5"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P6"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P7"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3),DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P8"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P9"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2))]] + [PackageName("P1"), VersionRequirement.AllReleases,ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P2"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P3"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P4"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P5"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P6"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P7"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3),DotNetFramework(FrameworkVersion.V3_5))) + PackageName("P8"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))) + PackageName("P9"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2)))] |> Set.ofList let expected = - [PackageName("P1"), VersionRequirement.AllReleases,FrameworkRestrictionList [] - PackageName("P2"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P3"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P4"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P5"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P6"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P8"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P9"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2))]] + [PackageName("P1"), VersionRequirement.AllReleases,ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P2"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P3"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P4"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P5"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P6"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P8"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))) + PackageName("P9"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2)))] |> Set.ofList - - original - |> DependencySetFilter.filterByRestrictions ( FrameworkRestrictionList[FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))]) - |> shouldEqual expected + let result = + original + |> DependencySetFilter.filterByRestrictions ( ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4)))) + |> Seq.toArray + result + |> shouldEqual (expected |> Seq.toArray) [] let ``filtered with Between restriction should filter non-matching`` () = let original = - [PackageName("P01"), VersionRequirement.AllReleases,FrameworkRestrictionList [] - PackageName("P02"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P03"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P04"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P05"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P06"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P07"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3),DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P08"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P09"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P10"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5_1),DotNetFramework(FrameworkVersion.V4_6))] - PackageName("P11"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5_1))] - PackageName("P12"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P13"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))] - PackageName("P14"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1))]] + [PackageName("P01"), VersionRequirement.AllReleases,ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P02"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P03"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P04"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P05"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P06"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P07"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3),DotNetFramework(FrameworkVersion.V3_5))) + PackageName("P08"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))) + PackageName("P09"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P10"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5_1),DotNetFramework(FrameworkVersion.V4_6))) + PackageName("P11"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5_1))) + PackageName("P12"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))) + PackageName("P13"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))) + PackageName("P14"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)))] |> Set.ofList let expected = - [PackageName("P01"), VersionRequirement.AllReleases,FrameworkRestrictionList [] - PackageName("P02"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))] - PackageName("P03"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P04"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P05"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P06"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P08"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P09"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2))] - PackageName("P13"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))]] + [PackageName("P01"), VersionRequirement.AllReleases,ExplicitRestriction FrameworkRestriction.NoRestriction + PackageName("P02"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4))) + PackageName("P03"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P04"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5))) + PackageName("P05"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P06"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P08"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))) + PackageName("P09"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V3_5),DotNetFramework(FrameworkVersion.V4_5_2))) + PackageName("P13"), VersionRequirement.AllReleases,ExplicitRestriction (FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4)))] |> Set.ofList original - |> DependencySetFilter.filterByRestrictions (FrameworkRestrictionList [FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_1))]) + |> DependencySetFilter.filterByRestrictions (ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5_1)))) |> shouldEqual expected [] +[] let ``should optimize ZendeskApi_v2 ``() = let original = - [PackageName("Newtonsoft.Json"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("Newtonsoft.Json"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))] - PackageName("AsyncCTP"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))] - PackageName("Newtonsoft.Json"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("Newtonsoft.Json"), VersionRequirement.AllReleases, [FrameworkRestriction.Portable "portable-net45+sl40+wp71+win80"] - PackageName("Microsoft.Bcl.Async"), VersionRequirement.AllReleases, [FrameworkRestriction.Portable "portable-net45+sl40+wp71+win80"]] + [PackageName("Newtonsoft.Json"), (), PlatformMatching.forceExtractPlatforms "net35" + PackageName("Newtonsoft.Json"), (), PlatformMatching.forceExtractPlatforms "net4" + PackageName("AsyncCTP"), (), PlatformMatching.forceExtractPlatforms "net4" + PackageName("Newtonsoft.Json"), (), PlatformMatching.forceExtractPlatforms "net45" + PackageName("Newtonsoft.Json"), (), PlatformMatching.forceExtractPlatforms "portable-net45+sl40+wp71+win80" + PackageName("Microsoft.Bcl.Async"),(), PlatformMatching.forceExtractPlatforms "portable-net45+sl40+wp71+win80"] let expected = - [PackageName("Newtonsoft.Json"), VersionRequirement.AllReleases, - FrameworkRestrictionList - [FrameworkRestriction.Portable "portable-net45+sl40+wp71+win80" + [PackageName("Newtonsoft.Json"), (), + makeOrList + [getPortableRestriction "portable-net45+sl40+wp71+win80" FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("AsyncCTP"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4))] - PackageName("Microsoft.Bcl.Async"), VersionRequirement.AllReleases,FrameworkRestrictionList [FrameworkRestriction.Portable "portable-net45+sl40+wp71+win80"]] - - original - |> optimizeDependencies + PackageName("AsyncCTP"), (),ExplicitRestriction (FrameworkRestriction.Between (DotNetFramework(FrameworkVersion.V4), DotNetFramework(FrameworkVersion.V4_5))) + PackageName("Microsoft.Bcl.Async"), (),ExplicitRestriction (getPortableRestriction "portable-net45+sl40+wp71+win80")] + let result = + addFrameworkRestrictionsToDependencies original [ + PlatformMatching.forceExtractPlatforms "net35" + PlatformMatching.forceExtractPlatforms "net40" + PlatformMatching.forceExtractPlatforms "net45" + PlatformMatching.forceExtractPlatforms "portable-net45+sl40+wp71+win80" ] + result |> shouldEqual expected [] let ``should optimize real world restrictions``() = let original = - [PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V2))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5_1))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_6))]] + [PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net20" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net35" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net45" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net451" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net46"] let expected = - [PackageName("P1"), VersionRequirement.AllReleases, - FrameworkRestrictionList - [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V2)) - FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V3_5)) - FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5)) - FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5_1)) - FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_6))]] - - let result = optimizeDependencies original + [PackageName("P1"), (), + makeOrList + [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V2))]] + + let result = + addFrameworkRestrictionsToDependencies original + [ PlatformMatching.forceExtractPlatforms "net2" + PlatformMatching.forceExtractPlatforms "net35" + PlatformMatching.forceExtractPlatforms "net45" + PlatformMatching.forceExtractPlatforms "net451" + PlatformMatching.forceExtractPlatforms "net46" ] result |> shouldEqual expected [] let ``should optimize real world restrictions 2``() = let original = - [PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V2))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_Client))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5_1))] - PackageName("P1"), VersionRequirement.AllReleases, [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_6))]] + [PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net20" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net4" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net45" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net451" + PackageName("P1"), (), PlatformMatching.forceExtractPlatforms "net46"] let expected = - [PackageName("P1"), VersionRequirement.AllReleases, - FrameworkRestrictionList - [FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V2)) - FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_Client)) - FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5)) - FrameworkRestriction.Exactly (DotNetFramework(FrameworkVersion.V4_5_1)) - FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_6))]] - - let result = optimizeDependencies original + [PackageName("P1"), (), + makeOrList + [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V2))]] + + let result = + addFrameworkRestrictionsToDependencies original + [ PlatformMatching.forceExtractPlatforms "net2" + PlatformMatching.forceExtractPlatforms "net4" + PlatformMatching.forceExtractPlatforms "net45" + PlatformMatching.forceExtractPlatforms "net451" + PlatformMatching.forceExtractPlatforms "net46" ] result |> shouldEqual expected [] let ``should optimize real world restrictions 3``() = let original = - [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_Client)) + [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4)) FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1))] - let expected = [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_Client))] + let expected = FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4)) - let result = optimizeRestrictions original + let result = makeOrList original |> getExplicitRestriction result |> shouldEqual expected - - - -[] -let ``should optimize real world .NET Standard restrictions``() = - let original = - [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)) - FrameworkRestriction.AtLeast (DotNetStandard(DotNetStandardVersion.V1_1)) - FrameworkRestriction.AtLeast (DotNetStandard(DotNetStandardVersion.V1_3))] - - let expected = - [FrameworkRestriction.AtLeast (DotNetFramework(FrameworkVersion.V4_5_1)) - FrameworkRestriction.AtLeast (DotNetStandard(DotNetStandardVersion.V1_1))] - - let result = optimizeRestrictions original - result |> shouldEqual expected \ No newline at end of file diff --git a/tests/Paket.Tests/Versioning/FrameworkCompatibilitySpecs.fs b/tests/Paket.Tests/Versioning/FrameworkCompatibilitySpecs.fs index 19100c5e63..8810f97ad2 100644 --- a/tests/Paket.Tests/Versioning/FrameworkCompatibilitySpecs.fs +++ b/tests/Paket.Tests/Versioning/FrameworkCompatibilitySpecs.fs @@ -30,6 +30,12 @@ open Paket.Requirements [] let ``net46 should be compatible with netstandard13``() = - (DotNetFramework FrameworkVersion.V4_6).IsCompatible (DotNetStandard DotNetStandardVersion.V1_3) + (SinglePlatform (DotNetFramework FrameworkVersion.V4_6)).IsAtLeast (SinglePlatform (DotNetStandard DotNetStandardVersion.V1_3)) + |> shouldEqual true + + (SinglePlatform (DotNetStandard DotNetStandardVersion.V1_3)).IsSupportedBy (SinglePlatform (DotNetFramework FrameworkVersion.V4_6)) + |> shouldEqual true + + (SinglePlatform (DotNetStandard DotNetStandardVersion.V1_3)).IsSmallerThan (SinglePlatform (DotNetFramework FrameworkVersion.V4_6)) |> shouldEqual true diff --git a/tests/Paket.Tests/Versioning/FrameworkRestrictionTests.fs b/tests/Paket.Tests/Versioning/FrameworkRestrictionTests.fs new file mode 100644 index 0000000000..b8a0deafae --- /dev/null +++ b/tests/Paket.Tests/Versioning/FrameworkRestrictionTests.fs @@ -0,0 +1,264 @@ +module Paket.Requirements.FrameworkRestrictionTests + +open Paket +open FsUnit +open NUnit.Framework +open Paket.Requirements + +[] +let ``Simplify && (true) (< net45)`` () = + let toSimplify = + (FrameworkRestriction.And[ + FrameworkRestriction.NoRestriction + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4_5)]) + toSimplify + |> shouldEqual (FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4_5)) + +[] +let ``IsSubset works for unknown Portables`` () = + let p = PlatformMatching.forceExtractPlatforms "portable-net45+win8+wp8+wp81+wpa81" + let t = p.ToTargetProfile.Value + let r = FrameworkRestriction.AtLeastPlatform t + r.IsSubsetOf r + |> shouldEqual true + +[] +let ``Simplify || (>= net45) (>= portable-net45+win8+wp8+wp81+wpa81)`` () = + // because that is a custom portable profile! + let portable = (PlatformMatching.forceExtractPlatforms "portable-net45+win8+wp8+wp81+wpa81").ToTargetProfile.Value + let atLeastPortable = FrameworkRestriction.AtLeastPlatform portable + + // this was the underlying bug + atLeastPortable.RepresentedFrameworks + |> shouldContain (SinglePlatform (DotNetFramework FrameworkVersion.V4_5)) + + let formula = FrameworkRestriction.Or [ atLeastPortable; FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4_5) ] + + formula + |> shouldEqual (atLeastPortable) + +[] +let ``CustomProfile is Supported by its Platforms``() = + let unknownProfile = + (PlatformMatching.forceExtractPlatforms "portable-net45+monoandroid10+monotouch10+xamarinios10").ToTargetProfile.Value + + unknownProfile.IsSupportedBy (SinglePlatform (DotNetFramework FrameworkVersion.V4_5)) + |> shouldEqual true + unknownProfile.IsSupportedBy (SinglePlatform (DotNetFramework FrameworkVersion.V4)) + |> shouldEqual false + + unknownProfile.IsSupportedBy (SinglePlatform (MonoAndroid)) + |> shouldEqual true + unknownProfile.IsSupportedBy (SinglePlatform (MonoTouch)) + |> shouldEqual true + unknownProfile.IsSupportedBy (SinglePlatform (Silverlight SilverlightVersion.V5)) + |> shouldEqual false + +[] +let ``__unknowntfm__ should not match everything`` () = + try + let model = + InstallModel.CreateFromLibs(Paket.Domain.PackageName "Rx-XAML", SemVer.Parse "2.2.4", FrameworkRestriction.NoRestriction, + [ { Paket.NuGet.UnparsedPackageFile.FullPath = @"..\Rx-XAML\lib\__unknowntfm__\System.Reactive.Windows.Threading.dll" + Paket.NuGet.UnparsedPackageFile.PathWithinPackage = "lib/__unknowntfm__/System.Reactive.Windows.Threading.dll" } ], + [], + [], + { References = NuspecReferences.All + OfficialName = "Reactive Extensions - XAML Support Library" + Version = "2.2.4" + Dependencies = [] + LicenseUrl = "" + IsDevelopmentDependency = false + FrameworkAssemblyReferences = []}) + let target = PortableProfile PortableProfileType.Profile344 + let newModel = model.ApplyFrameworkRestrictions (FrameworkRestriction.ExactlyPlatform target) + newModel.GetCompileReferences target |> Seq.toArray + |> shouldEqual [||] + with e -> + // Throwing is OK as well. + () + +[] +let ``Profile 158 should not support itself``() = + SupportCalculation.isSupportedNotEqual Profile158 Profile158 + |> shouldEqual false +[] +let ``Profile 158 should not support Profile 78, as there is no silverlight on 78``() = + SupportCalculation.isSupportedNotEqual Profile158 Profile78 + |> shouldEqual false + SupportCalculation.isSupportedNotEqual Profile78 Profile158 + |> shouldEqual true +[] +let ``Profile 344 should support Profile 336, as it has the same frameworks but is lower``() = + SupportCalculation.isSupportedNotEqual Profile336 Profile344 + |> shouldEqual false + SupportCalculation.isSupportedNotEqual Profile344 Profile336 + |> shouldEqual true + +[] +let ``Generate Support Table``() = + // TODO: Should we include this? + let mutable supportMap = SupportCalculation.createInitialSupportMap() + supportMap <- SupportCalculation.optimizeSupportMap supportMap + + supportMap + |> SupportCalculation.toSeq + |> Seq.iter (fun (p, supported) -> + System.Diagnostics.Debug.WriteLine(sprintf "| %s ->" p.ProfileName) + System.Diagnostics.Debug.WriteLine(" [ ") + supported + |> List.iter (fun p -> + System.Diagnostics.Debug.WriteLine(sprintf " %s" p.ProfileName)) + + System.Diagnostics.Debug.WriteLine(" ] ")) + + System.Diagnostics.Debug.WriteLine(" --- Finished") + +[] +let ``Unknown Portables are detected correctly``() = + PlatformMatching.forceExtractPlatforms "portable-monotouch+monoandroid" + |> function { Platforms = o } -> TargetProfile.FindPortable o + |> shouldEqual (PortableProfile (PortableProfileType.UnsupportedProfile [MonoAndroid; MonoTouch])) +[] +let ``Portables are detected correctly``() = + // http://nugettoolsdev.azurewebsites.net/4.0.0/parse-framework?framework=portable-net451%2Bwin81%2Bwpa81%2Bwaspt2 + let portables = + [ "net40" + "portable-monotouch+monoandroid" + "portable-net40+sl5+win8+wp8+wpa81"; "portable-net45+winrt45+wp8+wpa81" + "portable-win81+wpa81" + "portable-windows8+net45+wp8" + "sl5"; "win8" + "wp8" ] + |> List.map PlatformMatching.forceExtractPlatforms + |> List.map (function { Platforms = [ h] } -> SinglePlatform h | {Platforms = o} -> TargetProfile.FindPortable o) + let expected = + [ SinglePlatform (DotNetFramework FrameworkVersion.V4); + PortableProfile (PortableProfileType.UnsupportedProfile [MonoAndroid; MonoTouch]) + PortableProfile (PortableProfileType.Profile328); PortableProfile (PortableProfileType.Profile259) + PortableProfile (PortableProfileType.Profile32) + PortableProfile (PortableProfileType.Profile78) + SinglePlatform (Silverlight SilverlightVersion.V5); SinglePlatform (Windows WindowsVersion.V8) + SinglePlatform (WindowsPhone WindowsPhoneVersion.V8) ] + portables + |> shouldEqual expected + +[] +let ``PlatformMatching works with portable ``() = + // portable-net40-sl4 + let l = (KnownTargetProfiles.FindPortableProfile "Profile18").PlatformsSupporting + // portable-net45-sl5 + let needPortable = KnownTargetProfiles.FindPortableProfile "Profile24" + + l + |> shouldContain needPortable + +[] +let ``Simplify && (&& (>= net40-full) (< net46) (>= net20)``() = + let toSimplify = + (FrameworkRestriction.And[ + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4) + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4_6) + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V2)]) + toSimplify + |> shouldEqual (FrameworkRestriction.Between (DotNetFramework FrameworkVersion.V4, DotNetFramework FrameworkVersion.V4_6)) + +[] +let ``Simplify <|| (&& (net452) (native)) (native)>`` () = + let toSimplify = + (FrameworkRestriction.Or[ + FrameworkRestriction.And[ + FrameworkRestriction.Exactly (DotNetFramework FrameworkVersion.V4_5_2) + FrameworkRestriction.Exactly (Native(NoBuildMode,NoPlatform))] + FrameworkRestriction.Exactly (Native(NoBuildMode,NoPlatform))]) + toSimplify + |> shouldEqual (FrameworkRestriction.Exactly (Native(NoBuildMode,NoPlatform))) + +[] +let ``Simplify (>=net20) && (>=net20)``() = + let toSimplify = + (FrameworkRestriction.And[ + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V2) + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V2)]) + toSimplify + |> shouldEqual (FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V2)) + +[] +let ``Simplify (>=net20) || (>=net20)``() = + let toSimplify = + (FrameworkRestriction.Or[ + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V2) + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V2)]) + toSimplify + |> shouldEqual (FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V2)) + +[] +let ``Simplify || (&& (< net40) (< net35)) (&& (< net40) (>= net35)) (>= net40))``() = + // Test simplify || (&& (< net40) (< net35)) (&& (< net40) (>= net35)) (>= net40)) + let smaller = + (FrameworkRestriction.And[ + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4) + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V3_5)]) + let between = + (FrameworkRestriction.And[ + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4) + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V3_5)]) + let rest = FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4) + + let combined = FrameworkRestriction.Or [ smaller ; between; rest ] + combined + |> shouldEqual FrameworkRestriction.NoRestriction + +[] +let ``Empty set should be empty``() = + FrameworkRestriction.EmptySet.RepresentedFrameworks.IsEmpty + |> shouldEqual true + +[] +let ``NoRestriction set should not be empty``() = + FrameworkRestriction.NoRestriction.RepresentedFrameworks.IsEmpty + |> shouldEqual false + +[] +let ``combineOr can simplify the NoRestriction set``() = + let left = + (FrameworkRestriction.Or + [FrameworkRestriction.And + [ FrameworkRestriction.And + [ FrameworkRestriction.NoRestriction + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V3_5)] + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4)] + FrameworkRestriction.And + [FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V3_5) + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4)]]) + let right = FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4) + FrameworkRestriction.combineRestrictionsWithOr left right + |> shouldEqual FrameworkRestriction.NoRestriction + +[] +let ``combineOr can simplify disjunct sets``() = + let left = + FrameworkRestriction.And[ + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4_5_1) + FrameworkRestriction.NotAtLeast (DotNetFramework FrameworkVersion.V4_6_2)] + let right = FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4_6_2) + // we can simplify this expression to >=net451 because they are disjunct + let combined = FrameworkRestriction.combineRestrictionsWithOr left right + + combined + |> shouldEqual (FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4_5_1)) + +[] +let ``combineOr needs to consider partly disjunct sets``() = + let left = + FrameworkRestriction.And[ + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4_5_1) + FrameworkRestriction.NotAtLeast (DotNetStandard DotNetStandardVersion.V1_3)] + let right = FrameworkRestriction.AtLeast (DotNetStandard DotNetStandardVersion.V1_3) + // Logic says this is >= net451 but it is >= net451 || >= netstandard13 + FrameworkRestriction.combineRestrictionsWithOr left right + |> shouldEqual (FrameworkRestriction.Or[ + FrameworkRestriction.AtLeast (DotNetFramework FrameworkVersion.V4_5_1) + FrameworkRestriction.AtLeast (DotNetStandard DotNetStandardVersion.V1_3)]) + + diff --git a/tests/Paket.Tests/Versioning/RestrictionApplicationSpecs.fs b/tests/Paket.Tests/Versioning/RestrictionApplicationSpecs.fs index 29724281a1..6576bb2455 100644 --- a/tests/Paket.Tests/Versioning/RestrictionApplicationSpecs.fs +++ b/tests/Paket.Tests/Versioning/RestrictionApplicationSpecs.fs @@ -14,13 +14,13 @@ module TestTargetProfiles = 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 @@ -34,19 +34,19 @@ module TestTargetProfiles = let DotNetUnityProfiles = DotNetUnityVersions |> List.map (DotNetUnity >> SinglePlatform) let WindowsProfiles = - [SinglePlatform(Windows "v4.5") - SinglePlatform(Windows "v4.5.1")] + [SinglePlatform(Windows WindowsVersion.V8) + SinglePlatform(Windows WindowsVersion.V8_1)] let SilverlightProfiles = - [SinglePlatform(Silverlight "v3.0") - SinglePlatform(Silverlight "v4.0") - SinglePlatform(Silverlight "v5.0")] + [SinglePlatform(Silverlight SilverlightVersion.V3) + SinglePlatform(Silverlight SilverlightVersion.V4) + SinglePlatform(Silverlight SilverlightVersion.V5)] let WindowsPhoneSilverlightProfiles = - [SinglePlatform(WindowsPhoneSilverlight "v7.0") - SinglePlatform(WindowsPhoneSilverlight "v7.1") - SinglePlatform(WindowsPhoneSilverlight "v8.0") - SinglePlatform(WindowsPhoneSilverlight "v8.1")] + [SinglePlatform(WindowsPhone WindowsPhoneVersion.V7) + SinglePlatform(WindowsPhone WindowsPhoneVersion.V7_5) + SinglePlatform(WindowsPhone WindowsPhoneVersion.V8) + SinglePlatform(WindowsPhone WindowsPhoneVersion.V8_1)] let AllProfiles = DotNetFrameworkProfiles @ @@ -58,36 +58,36 @@ module TestTargetProfiles = SinglePlatform(MonoTouch) SinglePlatform(XamariniOS) SinglePlatform(XamarinMac) - SinglePlatform(WindowsPhoneApp "v8.1") - ] + SinglePlatform(WindowsPhoneApp WindowsPhoneAppVersion.V8_1) + ]|> Set.ofList [] let ``>= net10 contains all but only dotnet versions (#1124)`` () = /// https://github.com/fsprojects/Paket/issues/1124 - let restrictions = [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V1))] + let restrictions = FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V1)) let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles - restricted |> shouldEqual TestTargetProfiles.DotNetFrameworkProfiles + restricted |> shouldEqual (TestTargetProfiles.DotNetFrameworkProfiles |> Set.ofList) [] let ``>= net452 contains 4.5.2 and following versions`` () = - let restrictions = [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5_2))] + 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 + let expected = [FrameworkVersion.V4_5_2; FrameworkVersion.V4_5_3; FrameworkVersion.V4_6] |> List.map dotnet |> Set.ofList 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 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 + let expected = [FrameworkVersion.V4; FrameworkVersion.V4_5] |> List.map dotnet|> Set.ofList restricted |> shouldEqual expected [] let ``>= sl30 contains all but only silverlight versions`` () = - let restrictions = [FrameworkRestriction.AtLeast(Silverlight "v3.0")] + let restrictions = FrameworkRestriction.AtLeast(Silverlight SilverlightVersion.V3) let restricted = applyRestrictionsToTargets restrictions TestTargetProfiles.AllProfiles - restricted |> shouldEqual TestTargetProfiles.SilverlightProfiles \ No newline at end of file + restricted |> shouldEqual (TestTargetProfiles.SilverlightProfiles|> Set.ofList) \ No newline at end of file diff --git a/tests/Paket.Tests/Versioning/RestrictionFilterSpecs.fs b/tests/Paket.Tests/Versioning/RestrictionFilterSpecs.fs index 505014b638..af2bbefc76 100644 --- a/tests/Paket.Tests/Versioning/RestrictionFilterSpecs.fs +++ b/tests/Paket.Tests/Versioning/RestrictionFilterSpecs.fs @@ -11,123 +11,113 @@ open Paket.Requirements [] let ``should filter net45 and >= net40``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] + let l1 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) + let l2 = ExplicitRestriction (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))) filterRestrictions l1 l2 |> shouldEqual l2 [] let ``should filter >= net40 and net45``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] + let l1 = ExplicitRestriction (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))) + let l2 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) filterRestrictions l1 l2 |> shouldEqual l1 [] let ``should filter >= net40 and net40``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_Client))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_Client))] + let l1 = ExplicitRestriction (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4))) + let l2 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) filterRestrictions l1 l2 |> shouldEqual l1 [] let ``should filter >=net40 and >= net45``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))] + let l1 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) + let l2 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4_5))) filterRestrictions l1 l2 |> shouldEqual l2 -[] -let ``should filter >= net40 and portable``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Portable("abc")] - - filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList []) - [] let ``should filter >= net40 and >= net20 < net46``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4_6))] + let l1 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) + let l2 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4_6))) filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6))]) + |> shouldEqual (ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6)))) [] let ``should filter >= net40 and >= net45 < net46``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_6))] + let l1 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) + let l2 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_6))) filterRestrictions l1 l2 |> shouldEqual l2 [] let ``should filter >= net40 and >= net20 < net40``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4))] + let l1 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) + let l2 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4))) filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList []) + |> shouldEqual (ExplicitRestriction FrameworkRestriction.EmptySet) [] let ``should filter net45 and >= net40 < net46``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6))] + let l1 = ExplicitRestriction (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))) + let l2 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6))) filterRestrictions l1 l2 |> shouldEqual l1 [] let ``should filter net45 and >= net40 < net45``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5))] + let l1 = ExplicitRestriction (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))) + let l2 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5))) filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList []) + |> shouldEqual (ExplicitRestriction FrameworkRestriction.EmptySet) [] let ``should filter >= net40 < net46 and net45``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] + let l1 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6))) + let l2 = ExplicitRestriction (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))) filterRestrictions l1 l2 |> shouldEqual l2 [] let ``should filter >= net40 < net45 and net45``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))] + let l1 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_5))) + let l2 = ExplicitRestriction (FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5))) filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList []) + |> shouldEqual (ExplicitRestriction FrameworkRestriction.EmptySet) [] let ``should filter >= net20 < net46 and >= net40``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4_6))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] + let l1 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4_6))) + let l2 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6))]) + |> shouldEqual (ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4),DotNetFramework(FrameworkVersion.V4_6)))) [] let ``should filter >= net45 < net46 and >= net40``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_6))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] + let l1 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V4_5),DotNetFramework(FrameworkVersion.V4_6))) + let l2 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) filterRestrictions l1 l2 |> shouldEqual l1 [] let ``should filter >= net20 < net40 and >= net40``() = - let l1 = FrameworkRestrictionList [FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))] + let l1 = ExplicitRestriction (FrameworkRestriction.Between(DotNetFramework(FrameworkVersion.V2),DotNetFramework(FrameworkVersion.V4))) + let l2 = ExplicitRestriction (FrameworkRestriction.AtLeast(DotNetFramework(FrameworkVersion.V4))) filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList []) + |> shouldEqual (ExplicitRestriction FrameworkRestriction.EmptySet) [] let ``should not filter native, net452``() = - FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform)).IsSameCategoryAs(FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform))) |> shouldEqual (Some true) - - let l1 = FrameworkRestrictionList [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5_2)); FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform))] - let l2 = FrameworkRestrictionList [FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform))] + let l1 = ExplicitRestriction (FrameworkRestriction.Or [FrameworkRestriction.Exactly(DotNetFramework(FrameworkVersion.V4_5_2)); FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform))]) + let l2 = ExplicitRestriction (FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform))) filterRestrictions l1 l2 - |> shouldEqual (FrameworkRestrictionList [FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform))]) + |> shouldEqual (ExplicitRestriction (FrameworkRestriction.Exactly(Native(NoBuildMode,NoPlatform))))