diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln index 4343cabcc..be6b9bf42 100644 --- a/Microsoft.DotNet.Cli.sln +++ b/Microsoft.DotNet.Cli.sln @@ -221,6 +221,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{ build\templates\templates.csproj = build\templates\templates.csproj EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-back-compat.Tests", "test\dotnet-back-compat.Tests\dotnet-back-compat.Tests.csproj", "{A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1509,6 +1511,30 @@ Global {CACA427D-5A71-45E6-88DC-3E2DB6C4D52D}.RelWithDebInfo|x64.Build.0 = Release|Any CPU {CACA427D-5A71-45E6-88DC-3E2DB6C4D52D}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU {CACA427D-5A71-45E6-88DC-3E2DB6C4D52D}.RelWithDebInfo|x86.Build.0 = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Debug|x64.ActiveCfg = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Debug|x64.Build.0 = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Debug|x86.ActiveCfg = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Debug|x86.Build.0 = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.MinSizeRel|x86.Build.0 = Debug|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Release|Any CPU.Build.0 = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Release|x64.ActiveCfg = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Release|x64.Build.0 = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Release|x86.ActiveCfg = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.Release|x86.Build.0 = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6}.RelWithDebInfo|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1577,5 +1603,6 @@ Global {CACA427D-5A71-45E6-88DC-3E2DB6C4D52D} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} {3275D006-54C8-4C64-A537-B9941C5D2F0C} = {89905EC4-BC0F-443B-8ADF-691321F10108} {DE4D1AEB-871B-4E7C-945A-453F9A490C06} = {89905EC4-BC0F-443B-8ADF-691321F10108} + {A4C198B4-D46E-4CA8-87DF-B2B206DCCAE6} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} EndGlobalSection EndGlobal diff --git a/src/dotnet/commands/dotnet-migrate/MigrateCommandParser.cs b/src/dotnet/commands/dotnet-migrate/MigrateCommandParser.cs index f5f5c771f..f878b67f2 100644 --- a/src/dotnet/commands/dotnet-migrate/MigrateCommandParser.cs +++ b/src/dotnet/commands/dotnet-migrate/MigrateCommandParser.cs @@ -29,15 +29,19 @@ namespace Microsoft.DotNet.Cli description: LocalizableStrings.CmdProjectArgumentDescription), CommonOptions.HelpOption(), Create.Option("-t|--template-file", - LocalizableStrings.CmdTemplateDescription), + LocalizableStrings.CmdTemplateDescription, + Accept.ExactlyOneArgument()), Create.Option("-v|--sdk-package-version", - LocalizableStrings.CmdVersionDescription), + LocalizableStrings.CmdVersionDescription, + Accept.ExactlyOneArgument()), Create.Option("-x|--xproj-file", - LocalizableStrings.CmdXprojFileDescription), + LocalizableStrings.CmdXprojFileDescription, + Accept.ExactlyOneArgument()), Create.Option("-s|--skip-project-references", LocalizableStrings.CmdSkipProjectReferencesDescription), Create.Option("-r|--report-file", - LocalizableStrings.CmdReportFileDescription), + LocalizableStrings.CmdReportFileDescription, + Accept.ExactlyOneArgument()), Create.Option("--format-report-file-json", LocalizableStrings.CmdReportOutputDescription), Create.Option("--skip-backup", diff --git a/test/Microsoft.DotNet.Cli.Tests.sln b/test/Microsoft.DotNet.Cli.Tests.sln index f6e479323..30e4e2f60 100644 --- a/test/Microsoft.DotNet.Cli.Tests.sln +++ b/test/Microsoft.DotNet.Cli.Tests.sln @@ -74,6 +74,8 @@ Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "dotnet-add-package.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-store.Tests", "dotnet-store.Tests\dotnet-store.Tests.csproj", "{04B21F0F-E645-44E3-868B-3C97E435FB74}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-back-compat.Tests", "dotnet-back-compat.Tests\dotnet-back-compat.Tests.csproj", "{27351B2F-325B-4843-9F4C-BC53FD06A7B5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -480,6 +482,30 @@ Global {04B21F0F-E645-44E3-868B-3C97E435FB74}.Release|x64.Build.0 = Release|Any CPU {04B21F0F-E645-44E3-868B-3C97E435FB74}.Release|x86.ActiveCfg = Release|Any CPU {04B21F0F-E645-44E3-868B-3C97E435FB74}.Release|x86.Build.0 = Release|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Debug|x64.ActiveCfg = Debug|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Debug|x64.Build.0 = Debug|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Debug|x86.ActiveCfg = Debug|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Debug|x86.Build.0 = Debug|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Release|Any CPU.Build.0 = Release|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Release|x64.ActiveCfg = Release|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Release|x64.Build.0 = Release|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Release|x86.ActiveCfg = Release|Any CPU + {7CA9ECD0-9284-496B-890F-94B63ECB37EC}.Release|x86.Build.0 = Release|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Debug|x64.ActiveCfg = Debug|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Debug|x64.Build.0 = Debug|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Debug|x86.ActiveCfg = Debug|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Debug|x86.Build.0 = Debug|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Release|Any CPU.Build.0 = Release|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Release|x64.ActiveCfg = Release|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Release|x64.Build.0 = Release|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Release|x86.ActiveCfg = Release|Any CPU + {27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/test/dotnet-back-compat.Tests/GivenThatWeWantToBeBackwardsCompatibleWith1xProjects.cs b/test/dotnet-back-compat.Tests/GivenThatWeWantToBeBackwardsCompatibleWith1xProjects.cs new file mode 100644 index 000000000..e104f4abf --- /dev/null +++ b/test/dotnet-back-compat.Tests/GivenThatWeWantToBeBackwardsCompatibleWith1xProjects.cs @@ -0,0 +1,93 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using FluentAssertions; +using Microsoft.DotNet.Tools.Test.Utilities; +using Xunit; +using System.Linq; +using System.Xml.Linq; + +namespace Microsoft.DotNet.Cli.Build.Tests +{ + public class GivenThatWeWantToBeBackwardsCompatibleWith1xProjects : TestBase + { + [Theory] + [InlineData("netcoreapp1.0")] + [InlineData("netcoreapp1.1")] + public void ItRestoresBuildsAndRuns(string target) + { + + var testAppName = "TestAppSimple"; + var testInstance = TestAssets.Get(testAppName) + .CreateInstance(testAppName + "_" + target.Replace('.', '_')) + .WithSourceFiles(); + + // Replace the 'TargetFramework' + ChangeProjectTargetFramework(testInstance.Root.GetFile($"{testAppName}.csproj"), target); + + new RestoreCommand() + .WithWorkingDirectory(testInstance.Root) + .Execute() + .Should().Pass(); + + new BuildCommand() + .WithWorkingDirectory(testInstance.Root) + .Execute() + .Should().Pass(); + + var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; + + var outputDll = testInstance.Root.GetDirectory("bin", configuration, target) + .GetFile($"{testAppName}.dll"); + + new DotnetCommand() + .ExecuteWithCapturedOutput(outputDll.FullName) + .Should().Pass() + .And.HaveStdOutContaining("Hello World"); + } + + [Theory] + [InlineData("netstandard1.3")] + [InlineData("netstandard1.6")] + public void ItRestoresBuildsAndPacks(string target) + { + + var testAppName = "TestAppSimple"; + var testInstance = TestAssets.Get(testAppName) + .CreateInstance(testAppName + "_" + target.Replace('.', '_')) + .WithSourceFiles(); + + // Replace the 'TargetFramework' + ChangeProjectTargetFramework(testInstance.Root.GetFile($"{testAppName}.csproj"), target); + + new RestoreCommand() + .WithWorkingDirectory(testInstance.Root) + .Execute() + .Should().Pass(); + + new BuildCommand() + .WithWorkingDirectory(testInstance.Root) + .Execute() + .Should().Pass(); + + new PackCommand() + .WithWorkingDirectory(testInstance.Root) + .Execute() + .Should().Pass(); + } + + + void ChangeProjectTargetFramework(FileInfo projectFile, string target) + { + var projectXml = XDocument.Load(projectFile.ToString()); + var ns = projectXml.Root.Name.Namespace; + var propertyGroup = projectXml.Root.Elements(ns + "PropertyGroup").First(); + var rootNamespaceElement = propertyGroup.Element(ns + "TargetFramework"); + rootNamespaceElement.SetValue(target); + projectXml.Save(projectFile.ToString()); + } + + } +} diff --git a/test/dotnet-back-compat.Tests/dotnet-back-compat.Tests.csproj b/test/dotnet-back-compat.Tests/dotnet-back-compat.Tests.csproj new file mode 100644 index 000000000..0b7b9fa26 --- /dev/null +++ b/test/dotnet-back-compat.Tests/dotnet-back-compat.Tests.csproj @@ -0,0 +1,20 @@ + + + + + $(CliTargetFramework) + $(CLI_SharedFrameworkVersion) + true + dotnet-back-compat.Tests + + + + + + + + + + + + diff --git a/test/dotnet.Tests/ParserTests/MigrateParserTests.cs b/test/dotnet.Tests/ParserTests/MigrateParserTests.cs new file mode 100644 index 000000000..814333dd0 --- /dev/null +++ b/test/dotnet.Tests/ParserTests/MigrateParserTests.cs @@ -0,0 +1,58 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using FluentAssertions; +using Microsoft.DotNet.Cli.CommandLine; +using Microsoft.DotNet.Tools.Migrate; +using Xunit; +using Xunit.Abstractions; +using Parser = Microsoft.DotNet.Cli.Parser; + +namespace Microsoft.DotNet.Tests.ParserTests +{ + public class MigrateParserTests + { + public MigrateParserTests(ITestOutputHelper output) + { + this.output = output; + } + + private readonly ITestOutputHelper output; + + [Fact] + public void MigrateParserConstructMigrateCommandWithoutError() + { + var command = Parser.Instance; + + var result = command.Parse("dotnet migrate --skip-backup -s " + + "-x \"C:\\ConsoleAppOnCore_1\\ConsoleAppOnCore_1.xproj\" " + + "\"C:\\ConsoleAppOnCore_1\\project.json\" " + + "-r \"C:\\report.wfw\" " + + "--format-report-file-json"); + + Action a = () => result["dotnet"]["migrate"].Value(); + a.ShouldNotThrow(); + } + + [Fact] + public void MigrateParseGetResultCorrectlyAsFollowing() + { + var command = Parser.Instance; + + var result = command.Parse("dotnet migrate --skip-backup -s " + + "-x \"C:\\ConsoleAppOnCore_1\\ConsoleAppOnCore_1.xproj\" " + + "\"C:\\ConsoleAppOnCore_1\\project.json\" " + + "-r \"C:\\report.wfw\" " + + "--format-report-file-json"); + + result["dotnet"]["migrate"]["skip-backup"].Value().Should().BeTrue(); + result["dotnet"]["migrate"]["skip-project-references"].Value().Should().BeTrue(); + result["dotnet"]["migrate"]["format-report-file-json"].Value().Should().BeTrue(); + result["dotnet"]["migrate"]["xproj-file"].Value().Should().Be("C:\\ConsoleAppOnCore_1\\ConsoleAppOnCore_1.xproj"); + result["dotnet"]["migrate"]["report-file"].Value().Should().Be("C:\\report.wfw"); + result["dotnet"]["migrate"].Arguments.Contains("C:\\ConsoleAppOnCore_1\\project.json").Should().BeTrue(); + } + } +} \ No newline at end of file