From fe0a63d510dbe3b3b450af9ed31848f60755c274 Mon Sep 17 00:00:00 2001 From: Lukas Rieger Date: Tue, 10 Jul 2018 22:52:08 +0200 Subject: [PATCH 1/3] Add environment variable flag to enable netsdk2 compatibility --- src/Paket.Core/Versioning/FrameworkHandling.fs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Paket.Core/Versioning/FrameworkHandling.fs b/src/Paket.Core/Versioning/FrameworkHandling.fs index f04bd19dcc..e1090dfe2f 100644 --- a/src/Paket.Core/Versioning/FrameworkHandling.fs +++ b/src/Paket.Core/Versioning/FrameworkHandling.fs @@ -6,6 +6,15 @@ open System.Diagnostics open Logging +type HandlingMode = NativeSupport | ToolingSupport + +module private DotnetTooling = + let mode = + if Environment.GetEnvironmentVariable("PAKET_SUPER_DUPER_SECRET_SWITCH_ENABLE_TOOLING_2") = "1" then + ToolingSupport + else + NativeSupport + /// The .NET Standard version. // Each time a new version is added NuGetPackageCache.CurrentCacheVersion should be bumped. [] @@ -592,7 +601,11 @@ type FrameworkIdentifier = | 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 ] | DotNetFramework FrameworkVersion.V4_6 -> [ DotNetFramework FrameworkVersion.V4_5_3; DotNetStandard DotNetStandardVersion.V1_3 ] - | DotNetFramework FrameworkVersion.V4_6_1 -> [ DotNetFramework FrameworkVersion.V4_6; DotNetStandard DotNetStandardVersion.V1_4 ] + | DotNetFramework FrameworkVersion.V4_6_1 -> + match DotnetTooling.mode with + | NativeSupport -> [ DotNetFramework FrameworkVersion.V4_6; DotNetStandard DotNetStandardVersion.V1_4 ] + // .NET Standard 2.0 will propagate "down", so we don't need any switches on the subsequent frameworks + | ToolingSupport -> [ DotNetFramework FrameworkVersion.V4_6; DotNetStandard DotNetStandardVersion.V2_0 ] | DotNetFramework FrameworkVersion.V4_6_2 -> [ DotNetFramework FrameworkVersion.V4_6_1; DotNetStandard DotNetStandardVersion.V1_5 ] | DotNetFramework FrameworkVersion.V4_6_3 -> [ DotNetFramework FrameworkVersion.V4_6_2 ] | DotNetFramework FrameworkVersion.V4_7 -> [ DotNetFramework FrameworkVersion.V4_6_3] From 35746cfacfbd65b145ef42442a482093225afd35 Mon Sep 17 00:00:00 2001 From: Lukas Rieger Date: Wed, 5 Dec 2018 16:35:28 +0100 Subject: [PATCH 2/3] enable support for .NET Fx 4.6.1 <-> .NET Standard 2 through app.config key "EnableNetFx461NetStandard2Support" or command line argument "--enablenetfx461netstandard2support" --- src/Paket.Bootstrapper/ArgumentParser.cs | 9 ++++-- src/Paket.Bootstrapper/BootstrapperOptions.cs | 6 ++-- .../Versioning/FrameworkHandling.fs | 31 +++++++++++++------ src/Paket/Commands.fs | 2 ++ src/Paket/Paket.fsproj | 1 + src/Paket/Program.fs | 18 +++++++++++ 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/Paket.Bootstrapper/ArgumentParser.cs b/src/Paket.Bootstrapper/ArgumentParser.cs index 9e00b8d0d9..f33d9e8bc7 100644 --- a/src/Paket.Bootstrapper/ArgumentParser.cs +++ b/src/Paket.Bootstrapper/ArgumentParser.cs @@ -32,6 +32,7 @@ public static class CommandArgs } public static class AppSettingKeys { + public const string EnableNetFx461NetStandard2Support = "EnableNetFx461NetStandard2Support"; public const string PreferNuget = "PreferNuget"; public const string ForceNuget = "ForceNuget"; public const string NugetSource = "NugetSource"; @@ -115,7 +116,7 @@ public static BootstrapperOptions ParseArgumentsAndConfigurations(IEnumerable(commandArgs); + options.RunArgs.AddRange(new List(commandArgs)); commandArgs.Clear(); // Don't check more than twice a day @@ -205,6 +206,10 @@ private static NameValueCollection ReadSettings(string configFilePath) private static void FillOptionsFromAppSettings(BootstrapperOptions options, NameValueCollection appSettings) { + if (appSettings.IsTrue(AppSettingKeys.EnableNetFx461NetStandard2Support)) + { + options.RunArgs.Add("--enablenetfx461netstandard2support"); + } if (appSettings.IsTrue(AppSettingKeys.PreferNuget)) { options.PreferNuget = true; @@ -249,7 +254,7 @@ private static void FillRunOptionsFromArguments(BootstrapperOptions options, Lis if (runIndex != -1) { options.Run = true; - options.RunArgs = commandArgs.GetRange(runIndex + 1, commandArgs.Count - runIndex - 1); + options.RunArgs.AddRange(commandArgs.GetRange(runIndex + 1, commandArgs.Count - runIndex - 1)); commandArgs.RemoveRange(runIndex, commandArgs.Count - runIndex); } } diff --git a/src/Paket.Bootstrapper/BootstrapperOptions.cs b/src/Paket.Bootstrapper/BootstrapperOptions.cs index 3c8596184c..35dbb879e4 100644 --- a/src/Paket.Bootstrapper/BootstrapperOptions.cs +++ b/src/Paket.Bootstrapper/BootstrapperOptions.cs @@ -9,18 +9,18 @@ public BootstrapperOptions() { Verbosity = Verbosity.Normal; DownloadArguments = new DownloadArguments(); - RunArgs = Enumerable.Empty(); + RunArgs = new List(); UnprocessedCommandArgs = Enumerable.Empty(); } public DownloadArguments DownloadArguments { get; set; } - + public Verbosity Verbosity { get; set; } public bool ForceNuget { get; set; } public bool PreferNuget { get; set; } public bool ShowHelp { get; set; } public bool Run { get; set; } - public IEnumerable RunArgs { get; set; } + public List RunArgs { get; set; } public IEnumerable UnprocessedCommandArgs { get; set; } } } \ No newline at end of file diff --git a/src/Paket.Core/Versioning/FrameworkHandling.fs b/src/Paket.Core/Versioning/FrameworkHandling.fs index 11354b40c9..58bfc164d5 100644 --- a/src/Paket.Core/Versioning/FrameworkHandling.fs +++ b/src/Paket.Core/Versioning/FrameworkHandling.fs @@ -6,14 +6,25 @@ open System.Diagnostics open Logging -type HandlingMode = NativeSupport | ToolingSupport +/// how to handle compatibility between .NET-FX <-> .NET +[] +type ToolingSupportMode = + +/// only support framework mappings which are in-box. +/// This means .NET Standard 2 is only supported from 4.7.1 onwards. +| NativeSupport + +/// support .NET Standard 2 from .NET Framework 4.6.1 onwards. +/// This requires a supported SDK during compilation, otherwise you may get successfull compilations, but errors at runtime. Use at your own risk. +| ToolingSupportNetSDK2 + + +module DotnetToolingSupport = + /// Change how paket handles the .NET-FX <-> .NET Standard compatibility tables. + /// Changing this flag influences resolution and lockfile generation. + /// You should only ever change it in MAIN then not touch it at runtime. + let mutable mode = ToolingSupportMode.NativeSupport -module private DotnetTooling = - let mode = - if Environment.GetEnvironmentVariable("PAKET_SUPER_DUPER_SECRET_SWITCH_ENABLE_TOOLING_2") = "1" then - ToolingSupport - else - NativeSupport /// The .NET Standard version. // Each time a new version is added NuGetPackageCache.CurrentCacheVersion should be bumped. @@ -627,10 +638,10 @@ type FrameworkIdentifier = | DotNetFramework FrameworkVersion.V4_5_3 -> [ DotNetFramework FrameworkVersion.V4_5_2; DotNetStandard DotNetStandardVersion.V1_2 ] | DotNetFramework FrameworkVersion.V4_6 -> [ DotNetFramework FrameworkVersion.V4_5_3; DotNetStandard DotNetStandardVersion.V1_3 ] | DotNetFramework FrameworkVersion.V4_6_1 -> - match DotnetTooling.mode with - | NativeSupport -> [ DotNetFramework FrameworkVersion.V4_6; DotNetStandard DotNetStandardVersion.V1_4 ] + match DotnetToolingSupport.mode with + | ToolingSupportMode.NativeSupport -> [ DotNetFramework FrameworkVersion.V4_6; DotNetStandard DotNetStandardVersion.V1_4 ] // .NET Standard 2.0 will propagate "down", so we don't need any switches on the subsequent frameworks - | ToolingSupport -> [ DotNetFramework FrameworkVersion.V4_6; DotNetStandard DotNetStandardVersion.V2_0 ] + | ToolingSupportMode.ToolingSupportNetSDK2 -> [ DotNetFramework FrameworkVersion.V4_6; DotNetStandard DotNetStandardVersion.V2_0 ] | DotNetFramework FrameworkVersion.V4_6_2 -> [ DotNetFramework FrameworkVersion.V4_6_1; DotNetStandard DotNetStandardVersion.V1_5 ] | DotNetFramework FrameworkVersion.V4_6_3 -> [ DotNetFramework FrameworkVersion.V4_6_2 ] | DotNetFramework FrameworkVersion.V4_7 -> [ DotNetFramework FrameworkVersion.V4_6_3] diff --git a/src/Paket/Commands.fs b/src/Paket/Commands.fs index f477f784ff..ebee18c223 100644 --- a/src/Paket/Commands.fs +++ b/src/Paket/Commands.fs @@ -652,6 +652,7 @@ type Command = | [] Verbose | [] Log_File of path:string | [] From_Bootstrapper + | [] EnableNetFx461NetStandard2Support // subcommands | [] Add of ParseResults | [] Github of ParseResults @@ -720,6 +721,7 @@ with | Verbose -> "print detailed information to the console" | Version -> "show Paket version" | From_Bootstrapper -> "call coming from the '--run' feature of the bootstrapper" + | EnableNetFx461NetStandard2Support -> "enable mapping when called from the bootstrapper. do not use manually." let commandParser = ArgumentParser.Create(programName = "paket", errorHandler = new ProcessExiter(), checkStructure = false) diff --git a/src/Paket/Paket.fsproj b/src/Paket/Paket.fsproj index e022ab341f..141b0b5ee8 100644 --- a/src/Paket/Paket.fsproj +++ b/src/Paket/Paket.fsproj @@ -79,6 +79,7 @@ + diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs index 7e3bc771d1..efc2f60cff 100644 --- a/src/Paket/Program.fs +++ b/src/Paket/Program.fs @@ -13,6 +13,16 @@ open PackageSources let sw = Stopwatch.StartNew() +type System.Collections.Specialized.NameValueCollection with + member this.GetKey(key:string) = + if this <> null && this.AllKeys |> Array.contains key then + this.Get(key) + else + null + member this.IsTrue(key:string) = + let v = this.GetKey(key) + String.equalsIgnoreCase v "true" + type PaketExiter() = interface IExiter with member __.Name = "paket exiter" @@ -848,6 +858,7 @@ let handleCommand silent command = | Verbose | Silent | From_Bootstrapper + | EnableNetFx461NetStandard2Support | Version | Log_File _ -> failwithf "internal error: this code should never be reached." @@ -864,7 +875,12 @@ let main() = try let args = Environment.GetCommandLineArgs() + let appSettings = System.Configuration.ConfigurationManager.AppSettings + if appSettings.IsTrue("EnableNetFx461NetStandard2Support") || + args |> Array.contains "--enablenetfx461netstandard2support" then + DotnetToolingSupport.mode <- ToolingSupportMode.ToolingSupportNetSDK2 match args with + | [| _; "restore" |] | [| _; "--from-bootstrapper"; "--enablenetfx461netstandard2support"; "restore" |] | [| _; "restore" |] | [| _; "--from-bootstrapper"; "restore" |] -> // Global restore fast route, see https://github.com/fsprojects/Argu/issues/90 processWithValidationEx @@ -872,6 +888,7 @@ let main() = false (fun _ -> true) (fun _ -> Dependencies.Locate().Restore()) () + | [| _; "restore"; "--project"; project |] | [| _; "--from-bootstrapper"; "--enablenetfx461netstandard2support"; "restore"; "--project"; project |] | [| _; "restore"; "--project"; project |] | [| _; "--from-bootstrapper"; "restore"; "--project"; project |] -> // Project restore fast route, see https://github.com/fsprojects/Argu/issues/90 processWithValidationEx @@ -879,6 +896,7 @@ let main() = false (fun _ -> true) (fun _ -> Dependencies.Locate().Restore(false, None, project, false, false, false, None)) () + | [| _; "install" |] | [| _; "--from-bootstrapper"; "--enablenetfx461netstandard2support"; "install" |] | [| _; "install" |] | [| _; "--from-bootstrapper"; "install" |] -> // Global restore fast route, see https://github.com/fsprojects/Argu/issues/90 processWithValidationEx From 913ce5806e88f1073f55e8361ad5ae7e26a73e1b Mon Sep 17 00:00:00 2001 From: Lukas Rieger Date: Fri, 3 May 2019 18:37:27 +0200 Subject: [PATCH 3/3] add test #3447 netfx461 should support netstandard20 if the appconfig flag is set --- .../Paket.IntegrationTests/InstallSpecs.fs | 9 +++++++++ integrationtests/Paket.IntegrationTests/TestHelper.fs | 10 ++++++++++ .../i003447-netfx461-ns20/before/paket.dependencies | 5 +++++ 3 files changed, 24 insertions(+) create mode 100644 integrationtests/scenarios/i003447-netfx461-ns20/before/paket.dependencies diff --git a/integrationtests/Paket.IntegrationTests/InstallSpecs.fs b/integrationtests/Paket.IntegrationTests/InstallSpecs.fs index 88291ca749..5567e44c27 100644 --- a/integrationtests/Paket.IntegrationTests/InstallSpecs.fs +++ b/integrationtests/Paket.IntegrationTests/InstallSpecs.fs @@ -450,6 +450,15 @@ let ``#3062 install should use external lock file``() = newLockFile.Groups.[GroupName "main"].Resolution.ContainsKey (PackageName "FAKE") |> shouldEqual true newLockFile.Groups.[GroupName "main"].Resolution.[PackageName "Machine.Specifications"].Version |> shouldEqual (SemVer.Parse "0.12") +[] +let ``#3447 netfx461 should support netstandard20 if the appconfig flag is set``() = + let newLockFile = installWithNfx461compat "i003447-netfx461-ns20" + // the dependencies file contains a restriction "framework: net461". So without the flag, the lock file contains only the one package because the dependencies for ns20 have been ignored. + // If the flag works correctly, then the lock file should contain all the microsoft asp.net core packages. + // The strategy is min, so the resolution should be stable regarding the versions. + newLockFile.Groups.[GroupName "main"].Resolution.ContainsKey (PackageName "Microsoft.AspNetCore.Server.Kestrel.Core") |> shouldEqual true + newLockFile.Groups.[GroupName "main"].Resolution.[PackageName "Microsoft.AspNetCore.Server.Kestrel.Core"].Version |> shouldEqual (SemVer.Parse "2.1.2") + #if INTERACTIVE ;; diff --git a/integrationtests/Paket.IntegrationTests/TestHelper.fs b/integrationtests/Paket.IntegrationTests/TestHelper.fs index 81453c6ad6..301e730130 100644 --- a/integrationtests/Paket.IntegrationTests/TestHelper.fs +++ b/integrationtests/Paket.IntegrationTests/TestHelper.fs @@ -214,8 +214,18 @@ let installEx checkZeroWarn scenario = #endif LockFile.LoadFrom(Path.Combine(scenarioTempPath scenario,"paket.lock")) +let installExWithNfx461compat checkZeroWarn scenario = + #if INTERACTIVE + paket "install --verbose" scenario |> printfn "%s" + #else + paketEx checkZeroWarn "--enablenetfx461netstandard2support install" scenario |> ignore + #endif + LockFile.LoadFrom(Path.Combine(scenarioTempPath scenario,"paket.lock")) + let install scenario = installEx false scenario +let installWithNfx461compat scenario = installExWithNfx461compat false scenario + let restore scenario = paketEx false "restore" scenario |> ignore let updateShouldFindPackageConflict packageName scenario = diff --git a/integrationtests/scenarios/i003447-netfx461-ns20/before/paket.dependencies b/integrationtests/scenarios/i003447-netfx461-ns20/before/paket.dependencies new file mode 100644 index 0000000000..54e13d9e50 --- /dev/null +++ b/integrationtests/scenarios/i003447-netfx461-ns20/before/paket.dependencies @@ -0,0 +1,5 @@ +source https://api.nuget.org/v3/index.json +storage: none +framework: net461 + +nuget Microsoft.AspNetCore 2.1.2 strategy:min