From b0554d3ff3b60205d01fe6d5a09356cd90c069f3 Mon Sep 17 00:00:00 2001 From: Bryan Thornbury Date: Tue, 23 Aug 2016 13:50:05 -0700 Subject: [PATCH] PR Feedback --- Microsoft.DotNet.Cli.sln | 11 +- .../Program.cs | 0 .../echoscript.cmd | 0 .../echoscript.sh | 0 .../project.json | 0 .../ConstantPackageNames.cs | 17 ++ .../DefaultMigrationRuleSet.cs | 3 +- .../MSBuildExtensions.cs | 41 ++-- ...icrosoft.DotNet.ProjectJsonMigration.xproj | 2 +- .../MigrationError.cs | 30 +++ .../MigrationErrorCodes.cs | 35 ++++ .../MigrationRuleInputs.cs | 4 +- .../MigrationSettings.cs | 23 --- .../MigrationTrace.cs | 54 +++--- .../Models/ItemMetadataValue.cs | 13 +- .../Models/ProjectProperty.cs | 14 -- .../ProjectMigrator.cs | 101 +++++++--- .../Properties/AssemblyInfo.cs | 5 +- .../Rules/IMigrationRule.cs | 13 +- .../Rules/MigrateBuildOptionsRule.cs | 45 ++--- .../Rules/MigrateConfigurationsRule.cs | 34 ++-- .../Rules/MigrateProjectDependenciesRule.cs | 57 +++--- .../Rules/MigratePublishOptionsRule.cs | 27 +-- .../Rules/MigrateRootOptionsRule.cs | 15 +- .../Rules/MigrateRuntimeOptionsRule.cs | 14 +- .../Rules/MigrateScriptsRule.cs | 43 ++--- .../Rules/MigrateTFMRule.cs | 25 +-- .../MigrateXprojProjectReferencesRule.cs | 8 +- .../Rules/SaveOutputProjectRule.cs | 11 +- .../Rules/TemporaryMutateProjectJsonRule.cs | 23 +-- .../project.json | 8 - .../transforms/AddBoolPropertyTransform.cs | 25 --- .../transforms/AddItemTransform.cs | 28 ++- .../transforms/AddPropertyTransform.cs | 2 +- .../transforms/AddStringPropertyTransform.cs | 25 --- .../transforms/ConditionalTransform.cs | 2 +- .../transforms/ITransform.cs | 2 +- .../transforms/ITransformApplicator.cs | 2 +- .../transforms/IncludeContextTransform.cs | 13 +- .../transforms/TransformApplicator.cs | 12 +- src/dotnet/Properties/AssemblyInfo.cs | 3 +- .../commands/dotnet-migrate/MigrateCommand.cs | 36 ++-- src/dotnet/commands/dotnet-migrate/Program.cs | 5 +- .../dotnet-migrate/ProjectJsonParser.cs | 17 +- .../TemporaryDotnetNewTemplateProject.cs | 35 ++-- .../GivenAProjectMigrator.cs | 90 +++++++++ .../GivenMSBuildExtensions.cs | 27 ++- .../MSBuild.exe | 1 + .../MSBuild.exe.config | 2 +- ...ft.DotNet.ProjectJsonMigration.Tests.xproj | 6 +- .../ProjectJsonBuilder.cs | 9 +- .../GivenThatIWantToMigrateBuildOptions.cs | 13 +- .../GivenThatIWantToMigrateConfigurations.cs | 11 +- ...enThatIWantToMigrateProjectDependencies.cs | 5 +- .../GivenThatIWantToMigratePublishOptions.cs | 7 +- .../GivenThatIWantToMigrateRuntimeOptions.cs | 1 + .../Rules/GivenThatIWantToMigrateScripts.cs | 11 +- .../Rules/GivenThatIWantToMigrateTFMs.cs | 3 +- .../TemporaryProjectFileRuleRunner.cs | 1 + .../Transforms/GivenAConditionalTransform.cs | 1 + .../Transforms/GivenATransformApplicator.cs | 29 +-- .../GivenAnAddBoolPropertyTransform.cs | 39 ---- .../Transforms/GivenAnAddItemTransform.cs | 2 + .../Transforms/GivenAnAddPropertyTransform.cs | 1 + .../GivenAnAddStringPropertyTransform.cs | 57 ------ .../GivenAnIncludeContextTransformation.cs | 1 + .../Commands/NewCommand.cs | 6 + .../GivenThatIWantToMigrateTestApps.cs | 181 +++++++++++------- test/dotnet-migrate.Tests/MSBuild.exe | 1 + test/dotnet-migrate.Tests/MSBuild.exe.config | 1 + .../dotnet-migrate.Tests.xproj | 21 ++ test/dotnet-migrate.Tests/project.json | 39 ++++ 72 files changed, 769 insertions(+), 680 deletions(-) rename TestAssets/TestProjects/{TestAppWithMigrateAbleScripts => TestAppWithMigrateableScripts}/Program.cs (100%) rename TestAssets/TestProjects/{TestAppWithMigrateAbleScripts => TestAppWithMigrateableScripts}/echoscript.cmd (100%) rename TestAssets/TestProjects/{TestAppWithMigrateAbleScripts => TestAppWithMigrateableScripts}/echoscript.sh (100%) rename TestAssets/TestProjects/{TestAppWithMigrateAbleScripts => TestAppWithMigrateableScripts}/project.json (100%) create mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/ConstantPackageNames.cs create mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs create mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/MigrationErrorCodes.cs delete mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/Models/ProjectProperty.cs delete mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddBoolPropertyTransform.cs delete mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddStringPropertyTransform.cs create mode 100644 test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs delete mode 100644 test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddBoolPropertyTransform.cs delete mode 100644 test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddStringPropertyTransform.cs rename test/{Microsoft.DotNet.ProjectJsonMigration.Tests/Scenarios => dotnet-migrate.Tests}/GivenThatIWantToMigrateTestApps.cs (52%) create mode 100644 test/dotnet-migrate.Tests/MSBuild.exe create mode 100644 test/dotnet-migrate.Tests/MSBuild.exe.config create mode 100644 test/dotnet-migrate.Tests/dotnet-migrate.Tests.xproj create mode 100644 test/dotnet-migrate.Tests/project.json diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln index 6adc5857c..319430b98 100644 --- a/Microsoft.DotNet.Cli.sln +++ b/Microsoft.DotNet.Cli.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED2FE3E2-F7E7-4389-8231-B65123F2076F}" EndProject @@ -104,8 +104,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "update-dependencies", "buil EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel.Loader", "src\Microsoft.DotNet.ProjectModel.Loader\Microsoft.DotNet.ProjectModel.Loader.xproj", "{1C599FFD-FB52-4279-A8E5-465D3EC499E1}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectModel.Loader.Tests", "test\Microsoft.DotNet.ProjectModel.Loader.Tests\Microsoft.DotNet.ProjectModel.Loader.Tests.xproj", "{5DF6C9DA-6909-4EC0-909E-6913580BB4A4}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Configurer", "src\Microsoft.DotNet.Configurer\Microsoft.DotNet.Configurer.xproj", "{E5ED47EF-BF25-4DA9-A7FE-290C642CBF0F}" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Configurer.UnitTests", "test\Microsoft.DotNet.Configurer.UnitTests\Microsoft.DotNet.Configurer.UnitTests.xproj", "{4C3B06D5-B6D5-4E5B-A44F-3EBE52A1C759}" @@ -156,6 +154,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "publish", "publish", "{27B1 build\publish\PublishContent.targets = build\publish\PublishContent.targets EndProjectSection EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectJsonMigration", "src\Microsoft.DotNet.ProjectJsonMigration\Microsoft.DotNet.ProjectJsonMigration.xproj", "{0E083818-2320-4388-8007-4F720FD5C634}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.ProjectJsonMigration.Tests", "test\Microsoft.DotNet.ProjectJsonMigration.Tests\Microsoft.DotNet.ProjectJsonMigration.Tests.xproj", "{1F2EF070-AC5F-4078-AFB0-65745AC691B9}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-migrate.Tests", "test\dotnet-migrate.Tests\dotnet-migrate.Tests.xproj", "{1F2EF070-AC5F-4078-AFB0-65745AC691B9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -931,6 +935,7 @@ Global {A16958E1-24C7-4F1E-B317-204AD91625DD} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {BD7833F8-3209-4682-BF75-B4BCA883E279} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {DCDFE282-03DE-4DBC-B90C-CC3CE3EC8162} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} + {688870C8-9843-4F9E-8576-D39290AD0F25} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} {65741CB1-8AEE-4C66-8198-10A7EA0E4258} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} {713CBFBB-5392-438D-B766-A9A585EF1BB8} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} {60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} diff --git a/TestAssets/TestProjects/TestAppWithMigrateAbleScripts/Program.cs b/TestAssets/TestProjects/TestAppWithMigrateableScripts/Program.cs similarity index 100% rename from TestAssets/TestProjects/TestAppWithMigrateAbleScripts/Program.cs rename to TestAssets/TestProjects/TestAppWithMigrateableScripts/Program.cs diff --git a/TestAssets/TestProjects/TestAppWithMigrateAbleScripts/echoscript.cmd b/TestAssets/TestProjects/TestAppWithMigrateableScripts/echoscript.cmd similarity index 100% rename from TestAssets/TestProjects/TestAppWithMigrateAbleScripts/echoscript.cmd rename to TestAssets/TestProjects/TestAppWithMigrateableScripts/echoscript.cmd diff --git a/TestAssets/TestProjects/TestAppWithMigrateAbleScripts/echoscript.sh b/TestAssets/TestProjects/TestAppWithMigrateableScripts/echoscript.sh similarity index 100% rename from TestAssets/TestProjects/TestAppWithMigrateAbleScripts/echoscript.sh rename to TestAssets/TestProjects/TestAppWithMigrateableScripts/echoscript.sh diff --git a/TestAssets/TestProjects/TestAppWithMigrateAbleScripts/project.json b/TestAssets/TestProjects/TestAppWithMigrateableScripts/project.json similarity index 100% rename from TestAssets/TestProjects/TestAppWithMigrateAbleScripts/project.json rename to TestAssets/TestProjects/TestAppWithMigrateableScripts/project.json diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ConstantPackageNames.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ConstantPackageNames.cs new file mode 100644 index 000000000..b2d1d0777 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ConstantPackageNames.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectModel; +using System.IO; +using Newtonsoft.Json.Linq; +using System.Text; + +namespace Microsoft.DotNet.ProjectJsonMigration +{ + public class ConstantPackageNames + { + public const string CSdkPackageName = "Microsoft.DotNet.Core.Sdk"; + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/DefaultMigrationRuleSet.cs b/src/Microsoft.DotNet.ProjectJsonMigration/DefaultMigrationRuleSet.cs index be900ff02..7801a11d6 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/DefaultMigrationRuleSet.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/DefaultMigrationRuleSet.cs @@ -9,6 +9,7 @@ using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.Cli; using System.Linq; using System.IO; +using Microsoft.DotNet.ProjectJsonMigration.Rules; using Newtonsoft.Json; namespace Microsoft.DotNet.ProjectJsonMigration @@ -33,7 +34,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration { foreach (var rule in Rules) { - MigrationTrace.Instance.WriteLine($"{nameof(DefaultMigrationRuleSet)}: Executing migration rule {nameof(rule)}"); + MigrationTrace.Instance.WriteLine($"{nameof(DefaultMigrationRuleSet)}: Executing migration rule {rule.GetType().Name}"); rule.Apply(migrationSettings, migrationRuleInputs); } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MSBuildExtensions.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MSBuildExtensions.cs index a25306535..241092ec5 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/MSBuildExtensions.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MSBuildExtensions.cs @@ -18,29 +18,25 @@ namespace Microsoft.DotNet.ProjectJsonMigration public static IEnumerable PropertiesWithoutConditions( this ProjectRootElement projectRoot) { - return projectRoot.Properties - .Where(p => p.Condition == string.Empty - && p.AllParents.Count(parent => parent.Condition != string.Empty) == 0); + return ElementsWithoutConditions(projectRoot.Properties); } public static IEnumerable ItemsWithoutConditions( this ProjectRootElement projectRoot) { - return projectRoot.Items - .Where(p => string.IsNullOrEmpty(p.Condition) - && p.AllParents.All(parent => string.IsNullOrEmpty(parent.Condition))); + return ElementsWithoutConditions(projectRoot.Items); } public static IEnumerable Includes( this ProjectItemElement item) { - return item.Include.Equals(string.Empty) ? Enumerable.Empty() : item.Include.Split(';'); + return SplitSemicolonDelimitedValues(item.Include); } public static IEnumerable Excludes( this ProjectItemElement item) { - return item.Exclude.Equals(string.Empty) ? Enumerable.Empty() : item.Exclude.Split(';'); + return SplitSemicolonDelimitedValues(item.Exclude); } public static IEnumerable AllConditions(this ProjectElement projectElement) @@ -48,7 +44,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration return new string[] { projectElement.Condition }.Concat(projectElement.AllParents.Select(p=> p.Condition)); } - public static IEnumerable CommonIncludes(this ProjectItemElement item, ProjectItemElement otherItem) + public static IEnumerable IntersectIncludes(this ProjectItemElement item, ProjectItemElement otherItem) { return item.Includes().Intersect(otherItem.Includes()); } @@ -58,14 +54,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration item.Include = string.Join(";", item.Includes().Except(includesToRemove)); } - public static void AddIncludes(this ProjectItemElement item, IEnumerable includes) + public static void UnionIncludes(this ProjectItemElement item, IEnumerable includesToAdd) { - item.Include = string.Join(";", item.Includes().Union(includes)); + item.Include = string.Join(";", item.Includes().Union(includesToAdd)); } - public static void AddExcludes(this ProjectItemElement item, IEnumerable excludes) + public static void UnionExcludes(this ProjectItemElement item, IEnumerable excludesToAdd) { - item.Exclude = string.Join(";", item.Excludes().Union(excludes)); + item.Exclude = string.Join(";", item.Excludes().Union(excludesToAdd)); } public static ProjectMetadataElement GetMetadataWithName(this ProjectItemElement item, string name) @@ -78,9 +74,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration return metadata.Value.Equals(otherMetadata.Value, StringComparison.Ordinal); } - public static void AddMetadata(this ProjectItemElement item, ICollection metadatas) + public static void AddMetadata(this ProjectItemElement item, ICollection metadataElements) { - foreach (var metadata in metadatas) + foreach (var metadata in metadataElements) { item.AddMetadata(metadata); } @@ -103,12 +99,23 @@ namespace Microsoft.DotNet.ProjectJsonMigration throw new Exception("Cannot merge metadata with the same name and different values"); } - if (existingMetadata == null) + if (existingMetadata == default(ProjectMetadataElement)) { - Console.WriteLine(metadata.Name); + MigrationTrace.Instance.WriteLine($"{nameof(AddMetadata)}: Adding metadata to {item.ItemType} item: {{ {metadata.Name}, {metadata.Value} }}"); item.AddMetadata(metadata.Name, metadata.Value); } } + private static IEnumerable SplitSemicolonDelimitedValues(string combinedValue) + { + return string.IsNullOrEmpty(combinedValue) ? Enumerable.Empty() : combinedValue.Split(';'); + } + + private static IEnumerable ElementsWithoutConditions(IEnumerable elements) where T : ProjectElement + { + return elements + .Where(e => string.IsNullOrEmpty(e.Condition) + && e.AllParents.All(parent => string.IsNullOrEmpty(parent.Condition))); + } } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.xproj b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.xproj index 0bc54ed18..095a39599 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.xproj +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.xproj @@ -4,7 +4,7 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 0E083818-2320-4388-8007-4F720FD5C634 Microsoft.DotNet.ProjectJsonMigration diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs new file mode 100644 index 000000000..39398640c --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs @@ -0,0 +1,30 @@ +using System; + +namespace Microsoft.DotNet.ProjectJsonMigration +{ + public class MigrationError + { + public string ErrorCode { get; } + + public string GeneralErrorReason { get; } + + public string Message { get; } + + public MigrationError(string errorCode, string generalErrorReason, string message) + { + ErrorCode = errorCode; + GeneralErrorReason = generalErrorReason; + Message = message; + } + + public void Throw() + { + throw new Exception(GetFormattedErrorMessage()); + } + + public string GetFormattedErrorMessage() + { + return $"{ErrorCode}::{GeneralErrorReason}: {Message}"; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationErrorCodes.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationErrorCodes.cs new file mode 100644 index 000000000..132d51ab2 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationErrorCodes.cs @@ -0,0 +1,35 @@ +using System; + +namespace Microsoft.DotNet.ProjectJsonMigration +{ + public static partial class MigrationErrorCodes + { + public static Func MIGRATE1011 + => (message) => new MigrationError(nameof(MIGRATE1011), "Deprecated Project", message); + + public static Func MIGRATE1012 + => (message) => new MigrationError(nameof(MIGRATE1012), "Project not Restored", message); + + public static Func MIGRATE1013 + => (message) => new MigrationError(nameof(MIGRATE1013), "No Project", message); + + public static Func MIGRATE1014 + => (message) => new MigrationError(nameof(MIGRATE1014), "Unresolved Dependency", message); + + public static Func MIGRATE1015 + => (message) => new MigrationError(nameof(MIGRATE1015), "File Overwrite", message); + + public static Func MIGRATE1016 + => (message) => new MigrationError(nameof(MIGRATE1016), "Unsupported Script Variable", message); + + // Potentially Temporary (Point in Time) Errors + public static Func MIGRATE20011 + => (message) => new MigrationError(nameof(MIGRATE20011), "Multi-TFM", message); + + public static Func MIGRATE20012 + => (message) => new MigrationError(nameof(MIGRATE20012), "Configuration Exclude", message); + + public static Func MIGRATE20013 + => (message) => new MigrationError(nameof(MIGRATE20013), "Non-Csharp App", message); + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationRuleInputs.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationRuleInputs.cs index 45dde00d0..177cfc1c3 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationRuleInputs.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationRuleInputs.cs @@ -33,12 +33,12 @@ namespace Microsoft.DotNet.ProjectJsonMigration public MigrationRuleInputs( IEnumerable projectContexts, - ProjectRootElement outputProject, + ProjectRootElement outputMSBuildProject, ProjectItemGroupElement commonItemGroup, ProjectPropertyGroupElement commonPropertyGroup) { ProjectContexts = projectContexts; - OutputMSBuildProject = outputProject; + OutputMSBuildProject = outputMSBuildProject; CommonItemGroup = commonItemGroup; CommonPropertyGroup = commonPropertyGroup; } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs index 10d7646ba..093980649 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs @@ -20,17 +20,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration public string SdkPackageVersion { get; } public ProjectRootElement MSBuildProjectTemplate { get; } - public MigrationSettings( - string projectDirectory, - string outputDirectory, - string sdkPackageVersion) - { - ProjectDirectory = projectDirectory; - OutputDirectory = outputDirectory; - SdkPackageVersion = sdkPackageVersion; - MSBuildProjectTemplate = null; - } - public MigrationSettings( string projectDirectory, string outputDirectory, @@ -42,17 +31,5 @@ namespace Microsoft.DotNet.ProjectJsonMigration SdkPackageVersion = sdkPackageVersion; MSBuildProjectTemplate = msBuildProjectTemplate; } - - public MigrationSettings( - string projectDirectory, - string outputDirectory, - string sdkPackageVersion, - string msbuildProjectTemplateFilePath) - { - ProjectDirectory = projectDirectory; - OutputDirectory = outputDirectory; - SdkPackageVersion = sdkPackageVersion; - MSBuildProjectTemplate = ProjectRootElement.Open(msbuildProjectTemplateFilePath); - } } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationTrace.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationTrace.cs index 05cd7e7db..717ed0741 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationTrace.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationTrace.cs @@ -3,43 +3,35 @@ using System.Text.RegularExpressions; namespace Microsoft.DotNet.ProjectJsonMigration { - public class MigrationTrace - { - public static MigrationTrace Instance { get; set; } - - static MigrationTrace () + public class MigrationTrace { - Instance = new MigrationTrace(); - } + public static MigrationTrace Instance { get; set; } - public string EnableEnvironmentVariable => "DOTNET_MIGRATION_TRACE"; + static MigrationTrace () + { + Instance = new MigrationTrace(); + } - public bool IsEnabled - { - get - { + public string EnableEnvironmentVariable => "DOTNET_MIGRATION_TRACE"; + + public bool IsEnabled + { + get + { #if DEBUG - return true; + return true; #else - return Environment.GetEnvironmentVariable(EnableEnvironmentVariable) != null; + return Environment.GetEnvironmentVariable(EnableEnvironmentVariable) != null; #endif - } - } + } + } - public void Write(string message) - { - if (IsEnabled) - { - Console.Write(message); - } + public void WriteLine(string message) + { + if (IsEnabled) + { + Console.WriteLine(message); + } + } } - - public void WriteLine(string message) - { - if (IsEnabled) - { - Console.WriteLine(message); - } - } - } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Models/ItemMetadataValue.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Models/ItemMetadataValue.cs index 536defd6d..1e257d65c 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Models/ItemMetadataValue.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Models/ItemMetadataValue.cs @@ -1,16 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +// 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; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Models { public class ItemMetadataValue { public string MetadataName { get; } - private string _metadataValue; - private Func _metadataValueFunc; + private readonly string _metadataValue; + private readonly Func _metadataValueFunc; public ItemMetadataValue(string metadataName, string metadataValue) { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Models/ProjectProperty.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Models/ProjectProperty.cs deleted file mode 100644 index 9b7ddc395..000000000 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Models/ProjectProperty.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Microsoft.DotNet.ProjectJsonMigration -{ - public class ProjectProperty - { - public string Name { get; } - public string Value { get; } - - public ProjectProperty(string name, string value) - { - Name = name; - Value = value; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs index b89c9f03b..6877f4793 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs @@ -9,6 +9,8 @@ using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.Cli; using System.Linq; using System.IO; +using Microsoft.DotNet.ProjectJsonMigration.Rules; +using Microsoft.DotNet.Tools.Common; using Newtonsoft.Json.Linq; namespace Microsoft.DotNet.ProjectJsonMigration @@ -24,30 +26,34 @@ namespace Microsoft.DotNet.ProjectJsonMigration // - Migrating Deprecated project.jsons // - Configuration dependent source exclusion - public void Migrate(MigrationSettings migrationSettings) - { - var projectDirectory = migrationSettings.ProjectDirectory; - EnsureDirectoryExists(migrationSettings.OutputDirectory); + private readonly IMigrationRule _ruleSet; - var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings); - VerifyInputs(migrationRuleInputs); - - new DefaultMigrationRuleSet().Apply(migrationSettings, migrationRuleInputs); + public ProjectMigrator() : this(new DefaultMigrationRuleSet()) { } + + public ProjectMigrator(IMigrationRule ruleSet) + { + _ruleSet = ruleSet; } - private void EnsureDirectoryExists(string outputDirectory) + public void Migrate(MigrationSettings migrationSettings) { - if (!Directory.Exists(outputDirectory)) - { - Directory.CreateDirectory(outputDirectory); - } + var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings); + VerifyInputs(migrationRuleInputs, migrationSettings); + + SetupOutputDirectory(migrationSettings.ProjectDirectory, migrationSettings.OutputDirectory); + + _ruleSet.Apply(migrationSettings, migrationRuleInputs); } private MigrationRuleInputs ComputeMigrationRuleInputs(MigrationSettings migrationSettings) { var projectContexts = ProjectContext.CreateContextForEachFramework(migrationSettings.ProjectDirectory); - var templateMSBuildProject = migrationSettings.MSBuildProjectTemplate ?? ProjectRootElement.Create(); + var templateMSBuildProject = migrationSettings.MSBuildProjectTemplate; + if (templateMSBuildProject == null) + { + throw new Exception("Expected non-null MSBuildProjectTemplate in MigrationSettings"); + } var propertyGroup = templateMSBuildProject.AddPropertyGroup(); var itemGroup = templateMSBuildProject.AddItemGroup(); @@ -55,29 +61,80 @@ namespace Microsoft.DotNet.ProjectJsonMigration return new MigrationRuleInputs(projectContexts, templateMSBuildProject, itemGroup, propertyGroup); } - private void VerifyInputs(MigrationRuleInputs migrationRuleInputs) + private void VerifyInputs(MigrationRuleInputs migrationRuleInputs, MigrationSettings migrationSettings) { - VerifyProject(migrationRuleInputs.ProjectContexts); + VerifyProject(migrationRuleInputs.ProjectContexts, migrationSettings.ProjectDirectory); } - private void VerifyProject(IEnumerable projectContexts) + private void VerifyProject(IEnumerable projectContexts, string projectDirectory) { if (projectContexts.Count() > 1) { - throw new Exception("MultiTFM projects currently not supported."); + MigrationErrorCodes.MIGRATE20011($"Multi-TFM projects currently not supported.").Throw(); } - if (projectContexts.Count() == 0) + if (!projectContexts.Any()) { - throw new Exception("No projects found"); + MigrationErrorCodes.MIGRATE1013($"No projects found in {projectDirectory}").Throw(); } - if (projectContexts.First().LockFile == null) + var defaultProjectContext = projectContexts.First(); + + if (defaultProjectContext.LockFile == null) { - throw new Exception("Restore must be run prior to project migration."); + MigrationErrorCodes.MIGRATE1012( + $"project.lock.json not found in {projectDirectory}, please run dotnet restore before doing migration").Throw(); + } + + var diagnostics = defaultProjectContext.ProjectFile.Diagnostics; + if (diagnostics.Any()) + { + MigrationErrorCodes.MIGRATE1011( + $"{projectDirectory}{Environment.NewLine}{string.Join(Environment.NewLine, diagnostics.Select(d => d.Message))}") + .Throw(); + } + + var compilerName = + defaultProjectContext.ProjectFile.GetCompilerOptions(defaultProjectContext.TargetFramework, "_") + .CompilerName; + if (!compilerName.Equals("csc", StringComparison.OrdinalIgnoreCase)) + { + MigrationErrorCodes.MIGRATE20013( + $"Cannot migrate project {defaultProjectContext.ProjectFile.ProjectFilePath} using compiler {compilerName}").Throw(); } } + private void SetupOutputDirectory(string projectDirectory, string outputDirectory) + { + if (!Directory.Exists(outputDirectory)) + { + Directory.CreateDirectory(outputDirectory); + } + + if (projectDirectory != outputDirectory) + { + CopyProjectToOutputDirectory(projectDirectory, outputDirectory); + } + } + + private void CopyProjectToOutputDirectory(string projectDirectory, string outputDirectory) + { + var sourceFilePaths = Directory.EnumerateFiles(projectDirectory, "*", SearchOption.AllDirectories); + + foreach (var sourceFilePath in sourceFilePaths) + { + var relativeFilePath = PathUtility.GetRelativePath(projectDirectory, sourceFilePath); + var destinationFilePath = Path.Combine(outputDirectory, relativeFilePath); + var destinationDirectory = Path.GetDirectoryName(destinationFilePath); + + if (!Directory.Exists(destinationDirectory)) + { + Directory.CreateDirectory(destinationDirectory); + } + + File.Copy(sourceFilePath, destinationFilePath); + } + } } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Properties/AssemblyInfo.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Properties/AssemblyInfo.cs index 9ede032e7..d766b835c 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Properties/AssemblyInfo.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Properties/AssemblyInfo.cs @@ -1,3 +1,6 @@ -using System.Runtime.CompilerServices; +// 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.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Microsoft.DotNet.ProjectJsonMigration.Tests")] diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/IMigrationRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/IMigrationRule.cs index a6283e180..36cc3715c 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/IMigrationRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/IMigrationRule.cs @@ -1,18 +1,7 @@ // 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Cli; -using System.Linq; -using System.IO; -using Newtonsoft.Json; - -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public interface IMigrationRule { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs index c66ce8005..cca260cd6 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateBuildOptionsRule.cs @@ -3,38 +3,31 @@ using System; using System.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli; using System.Linq; -using System.IO; -using Newtonsoft.Json; +using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; +using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel.Files; -using Microsoft.DotNet.Cli.Utils; using Newtonsoft.Json.Linq; +using NuGet.Frameworks; -using Project = Microsoft.DotNet.ProjectModel.Project; - -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { // TODO: Should All build options be protected by a configuration condition? // This will prevent the entire merge issue altogether and sidesteps the problem of having a duplicate include with different excludes... public class MigrateBuildOptionsRule : IMigrationRule { private AddPropertyTransform[] EmitEntryPointTransforms - => new AddPropertyTransform[] + => new [] { new AddPropertyTransform("OutputType", "Exe", compilerOptions => compilerOptions.EmitEntryPoint != null && compilerOptions.EmitEntryPoint.Value), - new AddPropertyTransform("TargetExt", ".dll", - compilerOptions => compilerOptions.EmitEntryPoint != null && compilerOptions.EmitEntryPoint.Value), new AddPropertyTransform("OutputType", "Library", compilerOptions => compilerOptions.EmitEntryPoint == null || !compilerOptions.EmitEntryPoint.Value) }; private AddPropertyTransform[] KeyFileTransforms - => new AddPropertyTransform[] + => new [] { new AddPropertyTransform("AssemblyOriginatorKeyFile", compilerOptions => compilerOptions.KeyFile, @@ -123,7 +116,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration private IncludeContextTransform CopyToOutputFilesTransform => new IncludeContextTransform("Content", transformMappings: true) - .WithMetadata("CopyToOutputDirectory", "PreserveNewest"); + .WithMetadata("CopyToOutputDirectory", "PreserveNewest"); private Func> CompileFilesTransformExecute => (compilerOptions, projectDirectory) => @@ -137,14 +130,15 @@ namespace Microsoft.DotNet.ProjectJsonMigration (compilerOptions, projectDirectory) => CopyToOutputFilesTransform.Transform(GetCopyToOutputIncludeContext(compilerOptions, projectDirectory)); - private string _configuration; - private ProjectPropertyGroupElement _configurationPropertyGroup; - private ProjectItemGroupElement _configurationItemGroup; + private readonly string _configuration; + private readonly NuGetFramework _framework; + private readonly ProjectPropertyGroupElement _configurationPropertyGroup; + private readonly ProjectItemGroupElement _configurationItemGroup; private List> _propertyTransforms; private List>> _includeContextTransformExecutes; - private ITransformApplicator _transformApplicator; + private readonly ITransformApplicator _transformApplicator; public MigrateBuildOptionsRule(ITransformApplicator transformApplicator = null) { @@ -154,11 +148,13 @@ namespace Microsoft.DotNet.ProjectJsonMigration public MigrateBuildOptionsRule( string configuration, + NuGetFramework framework, ProjectPropertyGroupElement configurationPropertyGroup, ProjectItemGroupElement configurationItemGroup, ITransformApplicator transformApplicator = null) { _configuration = configuration; + _framework = framework; _configurationPropertyGroup = configurationPropertyGroup; _configurationItemGroup = configurationItemGroup; _transformApplicator = transformApplicator ?? new TransformApplicator(); @@ -207,7 +203,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration var compilerOptions = projectContext.ProjectFile.GetCompilerOptions(projectContext.TargetFramework, null); var configurationCompilerOptions = - projectContext.ProjectFile.GetCompilerOptions(projectContext.TargetFramework, _configuration); + projectContext.ProjectFile.GetCompilerOptions(_framework, _configuration); // If we're in a configuration, we need to be careful not to overwrite values from BuildOptions // without a configuration @@ -293,10 +289,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration if (configurationHasAdditionalExclude) { - Console.WriteLine("EXCLUDE"); - Console.WriteLine(item1.Exclude); - Console.WriteLine(item2Excludes.ToString()); - throw new Exception("Unable to migrate projects with excluded files in configurations."); + MigrationTrace.Instance.WriteLine(item1.Exclude); + MigrationTrace.Instance.WriteLine(item2Excludes.ToString()); + + MigrationErrorCodes.MIGRATE20012("Unable to migrate projects with excluded files in configurations.") + .Throw(); } } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateConfigurationsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateConfigurationsRule.cs index c9b85916c..7bcef379a 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateConfigurationsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateConfigurationsRule.cs @@ -3,16 +3,11 @@ using System; using System.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Cli; using System.Linq; -using System.IO; -using Newtonsoft.Json; +using Microsoft.Build.Construction; +using NuGet.Frameworks; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public class MigrateConfigurationsRule : IMigrationRule { @@ -21,19 +16,29 @@ namespace Microsoft.DotNet.ProjectJsonMigration var projectContext = migrationRuleInputs.DefaultProjectContext; var configurations = projectContext.ProjectFile.GetConfigurations().ToList(); + var frameworks = new List(); + frameworks.Add(null); + frameworks.AddRange(projectContext.ProjectFile.GetTargetFrameworks().Select(t => t.FrameworkName)); + if (!configurations.Any()) { return; } - foreach (var configuration in configurations) + var frameworkConfigurationCombinations = frameworks.SelectMany(f => configurations, Tuple.Create); + + foreach (var entry in frameworkConfigurationCombinations) { - MigrateConfiguration(configuration, migrationSettings, migrationRuleInputs); + var framework = entry.Item1; + var configuration = entry.Item2; + + MigrateConfiguration(configuration, framework, migrationSettings, migrationRuleInputs); } } private void MigrateConfiguration( - string configuration, + string configuration, + NuGetFramework framework, MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) { @@ -43,10 +48,15 @@ namespace Microsoft.DotNet.ProjectJsonMigration var itemGroup = CreateItemGroupAtEndOfProject(csproj); var configurationCondition = $" '$(Configuration)' == '{configuration}' "; + if (framework != null) + { + configurationCondition += + $" and '$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion)' == '{framework.DotNetFrameworkName}' "; + } propertyGroup.Condition = configurationCondition; itemGroup.Condition = configurationCondition; - new MigrateBuildOptionsRule(configuration, propertyGroup, itemGroup) + new MigrateBuildOptionsRule(configuration, framework, propertyGroup, itemGroup) .Apply(migrationSettings, migrationRuleInputs); propertyGroup.RemoveIfEmpty(); diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs index 0b78b044e..8caa29d62 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs @@ -1,29 +1,24 @@ // 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Cli; -using System.Linq; using System.IO; -using Newtonsoft.Json; +using System.Linq; +using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; +using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.Tools.Common; -using Project = Microsoft.DotNet.ProjectModel.Project; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public class MigrateProjectDependenciesRule : IMigrationRule { private readonly ITransformApplicator _transformApplicator; private string _projectDirectory; - public MigrateProjectDependenciesRule(TransformApplicator transformApplicator = null) + public MigrateProjectDependenciesRule(ITransformApplicator transformApplicator = null) { _transformApplicator = transformApplicator ?? new TransformApplicator(); } @@ -38,29 +33,34 @@ namespace Microsoft.DotNet.ProjectJsonMigration var projectDependencyTransformResults = projectExports.Select(projectExport => ProjectDependencyTransform.Transform(projectExport)); - var propertyTransformResults = new [] + + if (projectDependencyTransformResults.Any()) + { + AddPropertyTransformsToCommonPropertyGroup(migrationRuleInputs.CommonPropertyGroup); + AddProjectDependenciesToNewItemGroup(csproj.AddItemGroup(), projectDependencyTransformResults); + } + } + + private void AddProjectDependenciesToNewItemGroup(ProjectItemGroupElement itemGroup, IEnumerable projectDependencyTransformResults) + { + foreach (var projectDependencyTransformResult in projectDependencyTransformResults) + { + _transformApplicator.Execute(projectDependencyTransformResult, itemGroup); + } + } + + private void AddPropertyTransformsToCommonPropertyGroup(ProjectPropertyGroupElement commonPropertyGroup) + { + var propertyTransformResults = new[] { AutoUnifyTransform.Transform(true), DesignTimeAutoUnifyTransform.Transform(true) }; - if (projectDependencyTransformResults.Any()) + foreach (var propertyTransformResult in propertyTransformResults) { - // Use a new item group for the project references, but the common for properties - var propertyGroup = migrationRuleInputs.CommonPropertyGroup; - var itemGroup = csproj.AddItemGroup(); - - foreach (var projectDependencyTransformResult in projectDependencyTransformResults) - { - _transformApplicator.Execute(projectDependencyTransformResult, itemGroup); - } - - foreach (var propertyTransformResult in propertyTransformResults) - { - _transformApplicator.Execute(propertyTransformResult, propertyGroup); - } + _transformApplicator.Execute(propertyTransformResult, commonPropertyGroup); } - } private AddPropertyTransform AutoUnifyTransform => new AddPropertyTransform( @@ -79,7 +79,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration { if (!export.Library.Resolved) { - throw new Exception("Cannot migrate unresolved project dependency, please ensure restore has been run."); + MigrationErrorCodes.MIGRATE1014( + $"Unresolved project dependency ({export.Library.Identity.Name})").Throw(); } var projectFile = ((ProjectDescription)export.Library).Project.ProjectFilePath; diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePublishOptionsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePublishOptionsRule.cs index 52a00095e..53c6b30d0 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePublishOptionsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePublishOptionsRule.cs @@ -1,25 +1,16 @@ // 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Cli; using System.Linq; -using System.IO; -using Newtonsoft.Json; -using Microsoft.DotNet.ProjectModel.Files; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public class MigratePublishOptionsRule : IMigrationRule { private readonly ITransformApplicator _transformApplicator; - public MigratePublishOptionsRule(TransformApplicator transformApplicator = null) + public MigratePublishOptionsRule(ITransformApplicator transformApplicator = null) { _transformApplicator = transformApplicator ?? new TransformApplicator(); } @@ -29,16 +20,13 @@ namespace Microsoft.DotNet.ProjectJsonMigration var csproj = migrationRuleInputs.OutputMSBuildProject; var projectContext = migrationRuleInputs.DefaultProjectContext; - var transformResults = new[] - { - CopyToOutputFilesTransform.Transform(projectContext.ProjectFile.PublishOptions) - }; + var transformResult = CopyToOutputFilesTransform.Transform(projectContext.ProjectFile.PublishOptions); - if (transformResults.Any(t => t != null && t.Any())) + if (transformResult != null && transformResult.Any()) { var itemGroup = migrationRuleInputs.CommonItemGroup; _transformApplicator.Execute( - CopyToOutputFilesTransform.Transform(projectContext.ProjectFile.PublishOptions), + transformResult, itemGroup, mergeExisting: true); } @@ -46,7 +34,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration private IncludeContextTransform CopyToOutputFilesTransform => new IncludeContextTransform("Content", transformMappings: true) - .WithMetadata("CopyToOutputDirectory", "None") - .WithMetadata("CopyToPublishDirectory", "PreserveNewest"); + .WithMetadata("CopyToPublishDirectory", "PreserveNewest"); } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRootOptionsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRootOptionsRule.cs index 357c1901e..23c329d68 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRootOptionsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRootOptionsRule.cs @@ -1,27 +1,18 @@ // 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli; using System.Linq; -using System.IO; -using Newtonsoft.Json; -using Microsoft.DotNet.ProjectModel.Files; -using NuGet.Versioning; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; using Project = Microsoft.DotNet.ProjectModel.Project; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public class MigrateRootOptionsRule : IMigrationRule { private readonly ITransformApplicator _transformApplicator; private readonly AddPropertyTransform[] _transforms; - public MigrateRootOptionsRule(TransformApplicator transformApplicator = null) + public MigrateRootOptionsRule(ITransformApplicator transformApplicator = null) { _transformApplicator = transformApplicator ?? new TransformApplicator(); diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRuntimeOptionsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRuntimeOptionsRule.cs index 3b59c7a63..e865fe39a 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRuntimeOptionsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateRuntimeOptionsRule.cs @@ -1,18 +1,9 @@ // 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Cli; -using System.Linq; using System.IO; -using Newtonsoft.Json; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public class MigrateRuntimeOptionsRule : IMigrationRule { @@ -28,7 +19,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration { if (File.Exists(outputRuntimeOptionsFile)) { - throw new Exception("Runtime options file already exists. Has migration already been run?"); + MigrationErrorCodes.MIGRATE1015( + $"{outputRuntimeOptionsFile} already exists. Has migration already been run?").Throw(); } File.WriteAllText(outputRuntimeOptionsFile, raw); diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateScriptsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateScriptsRule.cs index 9eb18cf72..8eb776b91 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateScriptsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateScriptsRule.cs @@ -1,20 +1,13 @@ // 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli; using System.Linq; -using System.IO; +using Microsoft.Build.Construction; using Microsoft.DotNet.Cli.Utils.CommandParsing; -using Newtonsoft.Json; -using Microsoft.DotNet.ProjectModel.Files; -using Microsoft.DotNet.Tools.Common; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public class MigrateScriptsRule : IMigrationRule { @@ -23,7 +16,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration private readonly ITransformApplicator _transformApplicator; - public MigrateScriptsRule(TransformApplicator transformApplicator = null) + public MigrateScriptsRule(ITransformApplicator transformApplicator = null) { _transformApplicator = transformApplicator ?? new TransformApplicator(); } @@ -49,7 +42,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration var count = 0; foreach (var scriptCommand in scriptCommands) { - var scriptExtensionPropertyName = AddScriptExtension(propertyGroup, scriptCommand, (++count).ToString()); + var scriptExtensionPropertyName = AddScriptExtension(propertyGroup, scriptCommand, $"{scriptSetName}_{++count}"); AddExec(target, FormatScriptCommand(scriptCommand, scriptExtensionPropertyName)); } @@ -131,8 +124,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration { if (msbuildMapping == null) { - throw new Exception( - $"{scriptVariableName} is currently an unsupported script variable for project migration"); + MigrationErrorCodes.MIGRATE1016( + $"{scriptVariableName} is currently an unsupported script variable for project migration") + .Throw(); } command = command.Replace($"%{scriptVariableName}%", msbuildMapping); @@ -152,7 +146,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration var targetName = $"{scriptSetName[0].ToString().ToUpper()}{string.Concat(scriptSetName.Skip(1))}Script"; var targetHookInfo = ScriptSetToMSBuildHookTargetMap[scriptSetName]; - var target = csproj.AddTarget(targetName); + var target = csproj.CreateTargetElement(targetName); + csproj.InsertBeforeChild(target, csproj.LastChild); if (targetHookInfo.IsRunBefore) { target.BeforeTargets = targetHookInfo.TargetName; @@ -186,12 +181,12 @@ namespace Microsoft.DotNet.ProjectJsonMigration { "compile:ResponseFile", null }, // Not migrated { "compile:CompilerExitCode", null }, // Not migrated { "compile:RuntimeOutputDir", null }, // Not migrated - { "compile:RuntimeIdentifier", null },// TODO: Need Rid in CSProj + { "compile:RuntimeIdentifier", null },// Not Migrated { "publish:TargetFramework", null }, // TODO: Need Short framework name in CSProj - { "publish:Runtime", null }, // TODO: Need Rid in CSProj + { "publish:Runtime", "$(RuntimeIdentifier)" }, - { "compile:FullTargetFramework", "$(TargetFrameworkIdentifier)=$(TargetFrameworkVersion)" }, + { "compile:FullTargetFramework", "$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion)" }, { "compile:Configuration", "$(Configuration)" }, { "compile:OutputFile", "$(TargetPath)" }, { "compile:OutputDir", "$(TargetDir)" }, @@ -199,10 +194,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration { "publish:ProjectPath", "$(MSBuildThisFileDirectory)" }, { "publish:Configuration", "$(Configuration)" }, { "publish:OutputPath", "$(TargetDir)" }, - { "publish:FullTargetFramework", "$(TargetFrameworkIdentifier)=$(TargetFrameworkVersion)" }, + { "publish:FullTargetFramework", "$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion)" }, { "project:Directory", "$(MSBuildProjectDirectory)" }, - { "project:Name", "$(MSBuildThisFileName)" }, + { "project:Name", "$(AssemblyName)" }, { "project:Version", "$(Version)" } }; @@ -211,14 +206,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration public bool IsRunBefore { get; } public string TargetName { get; } - public string BeforeAfterTarget - { - get - { - return IsRunBefore ? "BeforeTargets" : "AfterTargets"; - } - } - public TargetHookInfo(bool isRunBefore, string targetName) { IsRunBefore = isRunBefore; diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs index 343c33667..b1ed6af73 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs @@ -1,11 +1,15 @@ -using System; -using System.Text; +// 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.Globalization; -using Microsoft.Build.Construction; using System.Linq; +using System.Text; +using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; using NuGet.Frameworks; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { // TODO: Support Multi-TFM public class MigrateTFMRule : IMigrationRule @@ -13,7 +17,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration private readonly ITransformApplicator _transformApplicator; private readonly AddPropertyTransform[] _transforms; - public MigrateTFMRule(TransformApplicator transformApplicator = null) + public MigrateTFMRule(ITransformApplicator transformApplicator = null) { _transformApplicator = transformApplicator ?? new TransformApplicator(); @@ -43,14 +47,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration private void CleanExistingProperties(ProjectRootElement csproj) { var existingPropertiesToRemove = new string[] { "TargetFrameworkIdentifier", "TargetFrameworkVersion" }; - foreach (var propertyName in existingPropertiesToRemove) - { - var properties = csproj.Properties.Where(p => p.Name == propertyName); + var properties = csproj.Properties.Where(p => existingPropertiesToRemove.Contains(p.Name)); - foreach (var property in properties) - { - property.Parent.RemoveChild(property); - } + foreach (var property in properties) + { + property.Parent.RemoveChild(property); } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateXprojProjectReferencesRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateXprojProjectReferencesRule.cs index 1b5eee495..1d51ea51a 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateXprojProjectReferencesRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateXprojProjectReferencesRule.cs @@ -1,16 +1,12 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { - // TODO: XProj ProjectToProject references public class MigrateXprojProjectReferencesRule : IMigrationRule { public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) { - throw new NotImplementedException(); + throw new NotImplementedException("TODO: XProj ProjectToProject references"); } } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs index adfba4fbb..78c06692a 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs @@ -1,18 +1,9 @@ // 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli; -using System.Linq; using System.IO; -using Newtonsoft.Json; -using Microsoft.DotNet.ProjectModel.Files; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public class SaveOutputProjectRule : IMigrationRule { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/TemporaryMutateProjectJsonRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/TemporaryMutateProjectJsonRule.cs index c15f751b6..3de53b547 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/TemporaryMutateProjectJsonRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/TemporaryMutateProjectJsonRule.cs @@ -1,14 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using System.IO; -using Newtonsoft.Json.Linq; -using System.Text; +// 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. -namespace Microsoft.DotNet.ProjectJsonMigration +using System; +using System.IO; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Microsoft.DotNet.ProjectJsonMigration.Rules { /// /// This rule is temporary while project.json still exists in the new project system. @@ -21,9 +19,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration /// public class TemporaryMutateProjectJsonRule : IMigrationRule { - private static string s_sdkPackageName => "Microsoft.DotNet.Core.Sdk"; - - public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) { bool shouldRenameOldProject = PathsAreEqual(migrationSettings.OutputDirectory, migrationSettings.ProjectDirectory); @@ -44,7 +39,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration } var json = CreateDestinationProjectFile(sourceProjectFile, destinationProjectFile); - InjectSdkReference(json, s_sdkPackageName, migrationSettings.SdkPackageVersion); + InjectSdkReference(json, ConstantPackageNames.CSdkPackageName, migrationSettings.SdkPackageVersion); RemoveRuntimesNode(json); File.WriteAllText(destinationProjectFile, json.ToString()); diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/project.json b/src/Microsoft.DotNet.ProjectJsonMigration/project.json index 3dcdf68d5..01713004a 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/project.json +++ b/src/Microsoft.DotNet.ProjectJsonMigration/project.json @@ -13,20 +13,12 @@ "Microsoft.DotNet.ProjectModel": { "target": "project" }, - "Microsoft.Win32.Registry": { - "version": "4.0.0", - "exclude": "compile" - }, - "MSBuild": "0.1.0-preview-00029-160805", "Microsoft.Build.Framework": "0.1.0-preview-00029-160805", - "Microsoft.Build.Tasks.Core": "0.1.0-preview-00029-160805", "Microsoft.Build.Utilities.Core": "0.1.0-preview-00029-160805", - "Microsoft.Build.Targets": "0.1.0-preview-00029-160805", "Microsoft.Build": "0.1.0-preview-00029-160805", }, "frameworks": { "netcoreapp1.0": { - "imports": ["dnxcore50","netstandardapp1.5","portable-net45+win8", "portable-net45+wp80+win8+wpa81+dnxcore50"] } } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddBoolPropertyTransform.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddBoolPropertyTransform.cs deleted file mode 100644 index d137d7f36..000000000 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddBoolPropertyTransform.cs +++ /dev/null @@ -1,25 +0,0 @@ -// 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Cli; -using System.Linq; -using System.IO; -using Newtonsoft.Json; - -namespace Microsoft.DotNet.ProjectJsonMigration -{ - public class AddBoolPropertyTransform : AddPropertyTransform - { - public AddBoolPropertyTransform(string propertyName) - : base(propertyName, b => b.ToString(), b => b) { } - - public AddBoolPropertyTransform(string propertyName, Func condition) - : base(propertyName, b => b.ToString(), condition) { } - } -} diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddItemTransform.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddItemTransform.cs index fde54f3ed..0d09e6bce 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddItemTransform.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddItemTransform.cs @@ -10,32 +10,30 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli; using System.Linq; using System.IO; +using Microsoft.DotNet.ProjectJsonMigration.Models; using Newtonsoft.Json; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { public class AddItemTransform : ConditionalTransform { - private ProjectRootElement _itemObjectGenerator = ProjectRootElement.Create(); + private readonly ProjectRootElement _itemObjectGenerator = ProjectRootElement.Create(); - private string _itemName; - private string _includeValue; - private string _excludeValue; + private readonly string _itemName; + private readonly string _includeValue; + private readonly string _excludeValue; - private Func _includeValueFunc; - private Func _excludeValueFunc; - - private bool _mergeExisting; + private readonly Func _includeValueFunc; + private readonly Func _excludeValueFunc; - private List> _metadata = new List>(); + private readonly List> _metadata = new List>(); public AddItemTransform( string itemName, IEnumerable includeValues, IEnumerable excludeValues, - Func condition, - bool mergeExisting = false) - : this(itemName, string.Join(";", includeValues), string.Join(";", excludeValues), condition, mergeExisting) { } + Func condition) + : this(itemName, string.Join(";", includeValues), string.Join(";", excludeValues), condition) { } public AddItemTransform( string itemName, @@ -77,14 +75,12 @@ namespace Microsoft.DotNet.ProjectJsonMigration string itemName, string includeValue, string excludeValue, - Func condition, - bool mergeExisting=false) + Func condition) : base(condition) { _itemName = itemName; _includeValue = includeValue; _excludeValue = excludeValue; - _mergeExisting = mergeExisting; } public AddItemTransform WithMetadata(string metadataName, string metadataValue) diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddPropertyTransform.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddPropertyTransform.cs index 48231ee40..f2cb30fea 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddPropertyTransform.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddPropertyTransform.cs @@ -12,7 +12,7 @@ using System.Linq; using System.IO; using Newtonsoft.Json; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { public class AddPropertyTransform : ConditionalTransform { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddStringPropertyTransform.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddStringPropertyTransform.cs deleted file mode 100644 index facca2e4d..000000000 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/AddStringPropertyTransform.cs +++ /dev/null @@ -1,25 +0,0 @@ -// 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.Collections.Generic; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Cli; -using System.Linq; -using System.IO; -using Newtonsoft.Json; - -namespace Microsoft.DotNet.ProjectJsonMigration -{ - public class AddStringPropertyTransform : AddPropertyTransform - { - public AddStringPropertyTransform(string propertyName) - : base(propertyName, s => s, s => !string.IsNullOrEmpty(s)) { } - - public AddStringPropertyTransform(string propertyName, Func condition) - : base(propertyName, s => s, s => !string.IsNullOrEmpty(s) && condition(s)) { } - } -} diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ConditionalTransform.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ConditionalTransform.cs index 0ccd10225..ca60d3f65 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ConditionalTransform.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ConditionalTransform.cs @@ -12,7 +12,7 @@ using System.Linq; using System.IO; using Newtonsoft.Json; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { public abstract class ConditionalTransform : ITransform { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransform.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransform.cs index ab9b37804..bdeaf18d0 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransform.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransform.cs @@ -1,6 +1,6 @@ using Microsoft.Build.Construction; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { public interface ITransform { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransformApplicator.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransformApplicator.cs index b2c7bf307..6435551ed 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransformApplicator.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/ITransformApplicator.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Microsoft.Build.Construction; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { public interface ITransformApplicator { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/IncludeContextTransform.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/IncludeContextTransform.cs index c935d34e5..0fd5e43fc 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/IncludeContextTransform.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/IncludeContextTransform.cs @@ -6,8 +6,9 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.Build.Construction; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.ProjectJsonMigration.Models; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { public class IncludeContextTransform : ConditionalTransform> { @@ -15,9 +16,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration // - Partially solved, what if the resolved glob is a directory? // TODO: Support mappings - private string _itemName; + private readonly string _itemName; private bool _transformMappings; - private List> _metadata = new List>(); + private readonly List> _metadata = new List>(); private AddItemTransform[] _transformSet; public IncludeContextTransform( @@ -27,8 +28,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration { _itemName = itemName; _transformMappings = transformMappings; - - CreateTransformSet(); } public IncludeContextTransform WithMetadata(string metadataName, string metadataValue) @@ -84,7 +83,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration includeExcludeTransformation.WithMetadata(metadata); } - _transformSet = new AddItemTransform[] + _transformSet = new [] { includeFilesExcludeFilesTransformation, includeExcludeTransformation @@ -138,6 +137,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration public override IEnumerable ConditionallyTransform(IncludeContext source) { + CreateTransformSet(); + return _transformSet.Select(t => t.Transform(source)); } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/TransformApplicator.cs b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/TransformApplicator.cs index 6a13154a3..97280eaa2 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/transforms/TransformApplicator.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/transforms/TransformApplicator.cs @@ -12,7 +12,7 @@ using System.Linq; using System.IO; using Newtonsoft.Json; -namespace Microsoft.DotNet.ProjectJsonMigration +namespace Microsoft.DotNet.ProjectJsonMigration.Transforms { public class TransformApplicator : ITransformApplicator { @@ -126,19 +126,19 @@ namespace Microsoft.DotNet.ProjectJsonMigration throw new InvalidOperationException("Cannot merge items of different types."); } - if (!item.CommonIncludes(existingItem).Any()) + if (!item.IntersectIncludes(existingItem).Any()) { throw new InvalidOperationException("Cannot merge items without a common include."); } - var commonIncludes = item.CommonIncludes(existingItem).ToList(); + var commonIncludes = item.IntersectIncludes(existingItem).ToList(); item.RemoveIncludes(commonIncludes); existingItem.RemoveIncludes(commonIncludes); var mergedItem = _projectElementGenerator.AddItem(item.ItemType, string.Join(";", commonIncludes)); - mergedItem.AddExcludes(existingItem.Excludes()); - mergedItem.AddExcludes(item.Excludes()); + mergedItem.UnionExcludes(existingItem.Excludes()); + mergedItem.UnionExcludes(item.Excludes()); mergedItem.AddMetadata(existingItem.Metadata); mergedItem.AddMetadata(item.Metadata); @@ -157,7 +157,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration { return project.ItemsWithoutConditions() .Where(i => string.Equals(i.ItemType, item.ItemType, StringComparison.Ordinal)) - .Where(i => i.CommonIncludes(item).Any()); + .Where(i => i.IntersectIncludes(item).Any()); } private class MergeResult diff --git a/src/dotnet/Properties/AssemblyInfo.cs b/src/dotnet/Properties/AssemblyInfo.cs index c6553d456..0dba7c570 100644 --- a/src/dotnet/Properties/AssemblyInfo.cs +++ b/src/dotnet/Properties/AssemblyInfo.cs @@ -2,5 +2,4 @@ using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyMetadataAttribute("Serviceable", "True")] -[assembly: InternalsVisibleTo("dotnet.Tests")] -[assembly: InternalsVisibleTo("Microsoft.DotNet.ProjectJsonMigration.Tests")] \ No newline at end of file +[assembly: InternalsVisibleTo("dotnet.Tests")] \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs b/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs index 430e486c1..3b67f26bb 100644 --- a/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs +++ b/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs @@ -6,17 +6,18 @@ using System.IO; using Microsoft.Build.Construction; using Microsoft.DotNet.Cli; using Microsoft.DotNet.ProjectJsonMigration; +using Microsoft.DotNet.ProjectModel; namespace Microsoft.DotNet.Tools.Migrate { public partial class MigrateCommand { - private string _templateFile; - private string _outputDirectory; - private string _projectJson; - private string _sdkVersion; + private readonly string _templateFile; + private readonly string _outputDirectory; + private readonly string _projectJson; + private readonly string _sdkVersion; - private TemporaryDotnetNewTemplateProject _temporaryDotnetNewProject; + private readonly TemporaryDotnetNewTemplateProject _temporaryDotnetNewProject; public MigrateCommand(string templateFile, string outputDirectory, string projectJson, string sdkVersion) { @@ -28,23 +29,24 @@ namespace Microsoft.DotNet.Tools.Migrate _temporaryDotnetNewProject = new TemporaryDotnetNewTemplateProject(); } - public int Start() + public int Execute() { - var project = GetProjectJsonPath(_projectJson) ?? _temporaryDotnetNewProject.ProjectJsonPath; + var project = GetProjectJsonPath(_projectJson) ?? GetProjectJsonPath(Directory.GetCurrentDirectory()); EnsureNotNull(project, "Unable to find project.json"); var projectDirectory = Path.GetDirectoryName(project); - var templateFile = _templateFile ?? _temporaryDotnetNewProject.MSBuildProjectPath; - EnsureNotNull(templateFile, "Unable to find default msbuild template"); + var msBuildTemplate = _templateFile != null ? + ProjectRootElement.TryOpen(_templateFile) : _temporaryDotnetNewProject.MSBuildProject; - var outputDirectory = _outputDirectory ?? Path.GetDirectoryName(project); + var outputDirectory = _outputDirectory ?? projectDirectory; EnsureNotNull(outputDirectory, "Null output directory"); var sdkVersion = _sdkVersion ?? new ProjectJsonParser(_temporaryDotnetNewProject.ProjectJson).SdkPackageVersion; EnsureNotNull(sdkVersion, "Null Sdk Version"); - var migrationSettings = new MigrationSettings(projectDirectory, outputDirectory, sdkVersion, templateFile); + var migrationSettings = new MigrationSettings(projectDirectory, outputDirectory, sdkVersion, msBuildTemplate); new ProjectMigrator().Migrate(migrationSettings); + return 0; } @@ -63,21 +65,13 @@ namespace Microsoft.DotNet.Tools.Migrate return null; } + projectJson = ProjectPathHelper.NormalizeProjectFilePath(projectJson); + if (File.Exists(projectJson)) { return projectJson; } - if (Directory.Exists(projectJson)) - { - var projectCandidate = Path.Combine(projectJson, "project.json"); - - if (File.Exists(projectCandidate)) - { - return projectCandidate; - } - } - throw new Exception($"Unable to find project file at {projectJson}"); } } diff --git a/src/dotnet/commands/dotnet-migrate/Program.cs b/src/dotnet/commands/dotnet-migrate/Program.cs index 8c2c5708e..4626ed2d5 100644 --- a/src/dotnet/commands/dotnet-migrate/Program.cs +++ b/src/dotnet/commands/dotnet-migrate/Program.cs @@ -13,12 +13,11 @@ namespace Microsoft.DotNet.Tools.Migrate { DebugHelper.HandleDebugSwitch(ref args); - CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false); + CommandLineApplication app = new CommandLineApplication(); app.Name = "dotnet migrate"; app.FullName = ".NET Migrate Command"; app.Description = "Command used to migrate project.json projects to msbuild"; app.HandleResponseFiles = true; - app.AllowArgumentSeparator = true; app.HelpOption("-h|--help"); CommandOption template = app.Option("-t|--template-file", "Base MSBuild template to use for migrated app. The default is the project included in dotnet new -t msbuild", CommandOptionType.SingleValue); @@ -34,7 +33,7 @@ namespace Microsoft.DotNet.Tools.Migrate project.Value(), sdkVersion.Value()); - return migrateCommand.Start(); + return migrateCommand.Execute(); }); try diff --git a/src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs b/src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs index 4856a64aa..71f599ba2 100644 --- a/src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs +++ b/src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs @@ -4,8 +4,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using Microsoft.DotNet.ProjectJsonMigration; -namespace Microsoft.DotNet.Cli +namespace Microsoft.DotNet.Tools.Migrate { /// /// Parses select data from a project.json without relying on ProjectModel. @@ -13,18 +14,16 @@ namespace Microsoft.DotNet.Cli /// internal class ProjectJsonParser { - public static string SdkPackageName => "Microsoft.DotNet.Core.Sdk"; - public string SdkPackageVersion { get; } public ProjectJsonParser(JObject projectJson) { - SdkPackageVersion = GetSdkPackageVersion(projectJson); + SdkPackageVersion = GetPackageVersion(projectJson, ConstantPackageNames.CSdkPackageName); } - private string GetSdkPackageVersion(JObject projectJson) + private string GetPackageVersion(JObject projectJson, string packageName) { - var sdkPackageNode = SelectJsonNodes(projectJson, property => property.Name == SdkPackageName).First(); + var sdkPackageNode = SelectJsonNodes(projectJson, property => property.Name == packageName).First(); if (sdkPackageNode.Value.Type == JTokenType.String) { @@ -34,10 +33,10 @@ namespace Microsoft.DotNet.Cli { var sdkPackageNodeValue = (JObject)sdkPackageNode.Value; - JToken sdkVersionNode; - if (sdkPackageNodeValue.TryGetValue("version", out sdkVersionNode)) + JToken versionNode; + if (sdkPackageNodeValue.TryGetValue("version", out versionNode)) { - return sdkVersionNode.Value(); + return versionNode.Value(); } else { diff --git a/src/dotnet/commands/dotnet-migrate/TemporaryDotnetNewTemplateProject.cs b/src/dotnet/commands/dotnet-migrate/TemporaryDotnetNewTemplateProject.cs index 86a944c4b..33cdeb796 100644 --- a/src/dotnet/commands/dotnet-migrate/TemporaryDotnetNewTemplateProject.cs +++ b/src/dotnet/commands/dotnet-migrate/TemporaryDotnetNewTemplateProject.cs @@ -6,40 +6,40 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using Microsoft.DotNet.ProjectJsonMigration; -namespace Microsoft.DotNet.Cli +namespace Microsoft.DotNet.Tools.Migrate { internal class TemporaryDotnetNewTemplateProject { - private static string s_temporaryDotnetNewMSBuildProjectName = "p"; + private const string c_temporaryDotnetNewMSBuildProjectName = "p"; - public TemporaryDotnetNewTemplateProject() - { - ProjectDirectory = CreateDotnetNewMSBuild(s_temporaryDotnetNewMSBuildProjectName); - MSBuildProject = GetMSBuildProject(ProjectDirectory); - ProjectJson = GetProjectJson(ProjectDirectory); - } + private readonly string _projectDirectory; public ProjectRootElement MSBuildProject { get; } public JObject ProjectJson { get; } - public string ProjectDirectory { get; } - public string ProjectJsonPath => Path.Combine(ProjectDirectory, "project.json"); - public string MSBuildProjectPath => Path.Combine(ProjectDirectory, s_temporaryDotnetNewMSBuildProjectName); + public TemporaryDotnetNewTemplateProject() + { + _projectDirectory = CreateDotnetNewMSBuild(c_temporaryDotnetNewMSBuildProjectName); + MSBuildProject = GetMSBuildProject(_projectDirectory); + ProjectJson = GetProjectJson(_projectDirectory); + + Clean(); + } public void Clean() { - Directory.Delete(ProjectDirectory, true); + Directory.Delete(Path.Combine(_projectDirectory, ".."), true); } private string CreateDotnetNewMSBuild(string projectName) { - var guid = Guid.NewGuid().ToString(); var tempDir = Path.Combine( Path.GetTempPath(), this.GetType().Namespace, - guid, - s_temporaryDotnetNewMSBuildProjectName); + Path.GetRandomFileName(), + c_temporaryDotnetNewMSBuildProjectName); if (Directory.Exists(tempDir)) { @@ -55,7 +55,7 @@ namespace Microsoft.DotNet.Cli private ProjectRootElement GetMSBuildProject(string temporaryDotnetNewMSBuildDirectory) { var templateProjPath = Path.Combine(temporaryDotnetNewMSBuildDirectory, - s_temporaryDotnetNewMSBuildProjectName + ".csproj"); + c_temporaryDotnetNewMSBuildProjectName + ".csproj"); return ProjectRootElement.Open(templateProjPath); } @@ -78,6 +78,9 @@ namespace Microsoft.DotNet.Cli if (commandResult.ExitCode != 0) { + MigrationTrace.Instance.WriteLine(commandResult.StdOut); + MigrationTrace.Instance.WriteLine(commandResult.StdErr); + throw new Exception($"Failed to run {commandToExecute} in directory: {workingDirectory}"); } } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs new file mode 100644 index 000000000..8b42c70bd --- /dev/null +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using FluentAssertions; +using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectJsonMigration.Rules; +using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.Tools.Common; +using Microsoft.DotNet.Tools.Test.Utilities; +using NuGet.Frameworks; +using Xunit; + +namespace Microsoft.DotNet.ProjectJsonMigration.Tests +{ + public class GivenAProjectMigrator : TestBase + { + [Fact] + public void It_copies_ProjectDirectory_contents_to_OutputDirectory_when_the_directories_are_different() + { + var testProjectDirectory = TestAssetsManager.CreateTestInstance("TestAppSimple", callingMethod: "z") + .WithLockFiles().Path; + var outputDirectory = Temp.CreateDirectory().Path; + + var projectDirectoryRelativeFilePaths = EnumerateFilesWithRelativePath(testProjectDirectory); + + var mockProj = ProjectRootElement.Create(); + var testSettings = new MigrationSettings(testProjectDirectory, outputDirectory, "1.0.0", mockProj); + + var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); + projectMigrator.Migrate(testSettings); + + foreach (var projectDirectoryRelativeFilePath in projectDirectoryRelativeFilePaths) + { + File.Exists(Path.Combine(outputDirectory, projectDirectoryRelativeFilePath)).Should().BeTrue(); + } + } + + [Fact] + public void It_throws_when_migrating_a_deprecated_projectJson() + { + var testProjectDirectory = + TestAssetsManager.CreateTestInstance("TestLibraryWithDeprecatedProjectFile", callingMethod: "z") + .WithLockFiles().Path; + + var mockProj = ProjectRootElement.Create(); + var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, "1.0.0", mockProj); + + var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); + Action migrateAction = () => projectMigrator.Migrate(testSettings); + + migrateAction.ShouldThrow().Where( + e => e.Message.Contains("MIGRATE1011::Deprecated Project:") + && e.Message.Contains("The 'packInclude' option is deprecated. Use 'files' in 'packOptions' instead.") + && e.Message.Contains("The 'compilationOptions' option is deprecated. Use 'buildOptions' instead.")); + } + + [Fact] + public void It_throws_when_migrating_a_non_csharp_app() + { + var testProjectDirectory = + TestAssetsManager.CreateTestInstance("FSharpTestProjects/TestApp", callingMethod: "z") + .WithLockFiles().Path; + + var mockProj = ProjectRootElement.Create(); + var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, "1.0.0", mockProj); + + var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); + Action migrateAction = () => projectMigrator.Migrate(testSettings); + + migrateAction.ShouldThrow().Where( + e => e.Message.Contains("MIGRATE20013::Non-Csharp App: Cannot migrate project")); + } + + private IEnumerable EnumerateFilesWithRelativePath(string testProjectDirectory) + { + return + Directory.EnumerateFiles(testProjectDirectory, "*", SearchOption.AllDirectories) + .Select(file => PathUtility.GetRelativePath(testProjectDirectory, file)); + } + + private class FakeEmptyMigrationRule : IMigrationRule + { + public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) + { + return; + } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenMSBuildExtensions.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenMSBuildExtensions.cs index bf2923a10..b93ff6778 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenMSBuildExtensions.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenMSBuildExtensions.cs @@ -15,6 +15,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests item.Include = "include1;include2;aaa"; var includes = item.Includes().ToArray(); + + includes.Should().HaveCount(3); includes[0].Should().Be("include1"); includes[1].Should().Be("include2"); includes[2].Should().Be("aaa"); @@ -28,6 +30,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests item.Exclude = "include1;include2;aaa"; var excludes = item.Excludes().ToArray(); + + excludes.Should().HaveCount(3); excludes[0].Should().Be("include1"); excludes[1].Should().Be("include2"); excludes[2].Should().Be("aaa"); @@ -74,7 +78,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests { var project = ProjectRootElement.Create(); var item1 = project.AddItem("test", "include1;include2"); - item1.AddIncludes(new string[] {"include2", "include3"}); + item1.UnionIncludes(new string[] {"include2", "include3"}); item1.Include.Should().Be("include1;include2;include3"); } @@ -85,7 +89,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var project = ProjectRootElement.Create(); var item1 = project.AddItem("test", "include1"); item1.Exclude = "exclude1;exclude2"; - item1.AddExcludes(new string[] {"exclude2", "exclude3"}); + item1.UnionExcludes(new string[] {"exclude2", "exclude3"}); item1.Exclude.Should().Be("exclude1;exclude2;exclude3"); } @@ -98,7 +102,24 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests item1.AddMetadata("name", "value"); item1.HasMetadata.Should().BeTrue(); - var item2 = project.AddItem("test1", "hey"); + var item2 = project.AddItem("test1", "include1"); + item2.AddMetadata(item1.Metadata); + + item2.HasMetadata.Should().BeTrue(); + item2.Metadata.First().Name.Should().Be("name"); + item2.Metadata.First().Value.Should().Be("value"); + } + + [Fact] + public void AddMetadata_adds_metadata_from_an_item_generated_from_another_project() + { + var project = ProjectRootElement.Create(); + var item1 = project.AddItem("test", "include1"); + item1.AddMetadata("name", "value"); + item1.HasMetadata.Should().BeTrue(); + + var project2 = ProjectRootElement.Create(); + var item2 = project2.AddItem("test1", "include1"); item2.AddMetadata(item1.Metadata); item2.HasMetadata.Should().BeTrue(); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe index e69de29bb..2b4d0f999 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe @@ -0,0 +1 @@ +https://github.com/Microsoft/msbuild/issues/927 \ No newline at end of file diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe.config b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe.config index 2b31011cf..2b4d0f999 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe.config +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/MSBuild.exe.config @@ -1 +1 @@ -hey \ No newline at end of file +https://github.com/Microsoft/msbuild/issues/927 \ No newline at end of file diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.xproj b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.xproj index 04e81394b..c4813d88e 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.xproj +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.xproj @@ -1,4 +1,4 @@ - + 14.0.25123 @@ -8,8 +8,8 @@ 1F2EF070-AC5F-4078-AFB0-65745AC691B9 Microsoft.DotNet.ProjectJsonMigration.Tests - .\obj - .\bin\ + ..\artifacts\bin\ 2.0 diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/ProjectJsonBuilder.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/ProjectJsonBuilder.cs index 204aa2afc..bbf9237df 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/ProjectJsonBuilder.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/ProjectJsonBuilder.cs @@ -13,9 +13,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests /// public class ProjectJsonBuilder { - private static readonly string s_defaultProjectJsonTestAsset = "TestAppWithRuntimeOptions"; - - private TestAssetsManager _testAssetsManager; + private readonly TestAssetsManager _testAssetsManager; private JObject _projectJson; private bool _baseDefined = false; @@ -41,11 +39,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests return _projectJson; } - public ProjectJsonBuilder FromDefaultBase() - { - return FromTestAssetBase(s_defaultProjectJsonTestAsset); - } - public ProjectJsonBuilder FromTestAssetBase(string testAssetName) { var testProjectDirectory = _testAssetsManager.CreateTestInstance(testAssetName).Path; diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs index 4408d9a8b..899a78204 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using Xunit; using FluentAssertions; +using Microsoft.DotNet.ProjectJsonMigration.Rules; using Microsoft.DotNet.ProjectModel.Files; namespace Microsoft.DotNet.ProjectJsonMigration.Tests @@ -68,7 +69,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests } [Fact] - public void Migrating_EmitEntryPoint_true_populates_OutputType_and_TargetExt_fields() + public void Migrating_EmitEntryPoint_true_populates_OutputType_field() { var mockProj = RunBuildOptionsRuleOnPj(@" { @@ -78,10 +79,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests }"); mockProj.Properties.Count(p => p.Name == "OutputType").Should().Be(1); - mockProj.Properties.Count(p => p.Name == "TargetExt").Should().Be(1); - mockProj.Properties.First(p => p.Name == "OutputType").Value.Should().Be("Exe"); - mockProj.Properties.First(p => p.Name == "TargetExt").Value.Should().Be(".dll"); } [Fact] @@ -362,7 +360,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests [InlineData("compile", "Compile")] [InlineData("embed", "EmbeddedResource")] [InlineData("copyToOutput", "Content")] - private void Migrating_compile_include_exclude_Populates_compile_item( + private void Migrating_group_include_exclude_Populates_appropriate_ProjectItemElement( string group, string itemName) { @@ -404,6 +402,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests foreach (var item in mockProj.Items.Where(i => i.ItemType.Equals(itemName, StringComparison.Ordinal))) { + if (item.ItemType == "Content") + { + item.Metadata.Count(m => m.Name == "CopyToOutputDirectory").Should().Be(1); + } + if (item.Include.Contains(@"src\file1.cs")) { item.Include.Should().Be(@"src\file1.cs;src\file2.cs"); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs index bdf0a54d3..fbd179b5e 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateConfigurations.cs @@ -10,6 +10,7 @@ using Microsoft.DotNet.Tools.Test.Utilities; using NuGet.Frameworks; using Xunit; using FluentAssertions; +using Microsoft.DotNet.ProjectJsonMigration.Rules; using Microsoft.DotNet.ProjectJsonMigration.Tests; namespace Microsoft.DotNet.ProjectJsonMigrationMigration.Tests @@ -32,7 +33,7 @@ namespace Microsoft.DotNet.ProjectJsonMigrationMigration.Tests }"); mockProj.Properties.Count( - prop => prop.Name == "OutputType" || prop.Name == "TargetExt" || prop.Name == "DebugType").Should().Be(3); + prop => prop.Name == "OutputType" || prop.Name == "DebugType").Should().Be(2); mockProj.Properties.First(p => p.Name == "OutputType") .Parent.Condition.Should() @@ -59,11 +60,11 @@ namespace Microsoft.DotNet.ProjectJsonMigrationMigration.Tests }"); mockProj.Properties.Count(property => - property.Name == "OutputType" || property.Name == "TargetExt" || property.Name == "DebugType") - .Should().Be(3); + property.Name == "OutputType" || property.Name == "DebugType") + .Should().Be(2); foreach (var property in mockProj.Properties.Where(property => - property.Name == "OutputType" || property.Name == "TargetExt" || property.Name == "DebugType")) + property.Name == "OutputType" || property.Name == "DebugType")) { property.Parent.Condition.Should().Be(string.Empty); } @@ -141,7 +142,7 @@ namespace Microsoft.DotNet.ProjectJsonMigrationMigration.Tests action.ShouldThrow() .WithMessage( - "Unable to migrate projects with excluded files in configurations."); + "MIGRATE20012::Configuration Exclude: Unable to migrate projects with excluded files in configurations."); } private ProjectRootElement RunConfigurationsRuleOnPj(string s, string testDirectory = null) { diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs index 532a934f9..5cd730a76 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading.Tasks; using Xunit; using FluentAssertions; +using Microsoft.DotNet.ProjectJsonMigration.Rules; namespace Microsoft.DotNet.Migration.Tests { @@ -60,7 +61,7 @@ namespace Microsoft.DotNet.Migration.Tests var projectReferences = mockProj.Items.Where(item => item.ItemType.Equals("ProjectReference", StringComparison.Ordinal)); projectReferences.Count().Should().Be(1); - projectReferences.First().Include.Should().Be("../TestLibrary/TestLibrary.csproj"); + projectReferences.First().Include.Should().Be(Path.Combine("..", "TestLibrary", "TestLibrary.csproj")); } [Fact] @@ -79,7 +80,7 @@ namespace Microsoft.DotNet.Migration.Tests Action action = () => new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); action.ShouldThrow() - .WithMessage("Cannot migrate unresolved project dependency, please ensure restore has been run."); + .Where(e => e.Message.Contains("MIGRATE1014::Unresolved Dependency: Unresolved project dependency (TestLibrary)")); } } } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePublishOptions.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePublishOptions.cs index d9fe2544b..5d7e1d3a0 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePublishOptions.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePublishOptions.cs @@ -10,6 +10,7 @@ using Microsoft.DotNet.Tools.Test.Utilities; using NuGet.Frameworks; using Xunit; using FluentAssertions; +using Microsoft.DotNet.ProjectJsonMigration.Rules; namespace Microsoft.DotNet.ProjectJsonMigration.Tests { @@ -34,12 +35,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests mockProj.Items.Count(i => i.ItemType.Equals("Content", StringComparison.Ordinal)).Should().Be(2); - // From ProjectReader #L725 (Both are empty) - var defaultIncludePatterns = Enumerable.Empty(); - var defaultExcludePatterns = ProjectFilesCollection.DefaultPublishExcludePatterns; - foreach (var item in mockProj.Items.Where(i => i.ItemType.Equals("Content", StringComparison.Ordinal))) { + item.Metadata.Count(m => m.Name == "CopyToPublishDirectory").Should().Be(1); + if (item.Include.Contains(@"src\file1.cs")) { item.Include.Should().Be(@"src\file1.cs;src\file2.cs"); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs index 8089fef95..744e259ea 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs @@ -14,6 +14,7 @@ using NuGet.Frameworks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Collections.Generic; +using Microsoft.DotNet.ProjectJsonMigration.Rules; namespace Microsoft.DotNet.ProjectJsonMigration.Tests { diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateScripts.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateScripts.cs index ceea3d2df..fd108769f 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateScripts.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateScripts.cs @@ -9,23 +9,25 @@ using Microsoft.DotNet.ProjectJsonMigration; using System; using System.IO; using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectJsonMigration.Rules; namespace Microsoft.DotNet.ProjectJsonMigration.Tests { public class GivenThatIWantToMigrateScripts : TestBase { [Theory] - [InlineData("compile:FullTargetFramework", "$(TargetFrameworkIdentifier)=$(TargetFrameworkVersion)")] + [InlineData("compile:FullTargetFramework", "$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion)")] [InlineData("compile:Configuration", "$(Configuration)")] [InlineData("compile:OutputFile", "$(TargetPath)")] [InlineData("compile:OutputDir", "$(TargetDir)")] [InlineData("publish:ProjectPath", "$(MSBuildThisFileDirectory)")] [InlineData("publish:Configuration", "$(Configuration)")] [InlineData("publish:OutputPath", "$(TargetDir)")] - [InlineData("publish:FullTargetFramework", "$(TargetFrameworkIdentifier)=$(TargetFrameworkVersion)")] + [InlineData("publish:FullTargetFramework", "$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion)")] [InlineData("project:Version", "$(Version)")] - [InlineData("project:Name", "$(MSBuildThisFileName)")] + [InlineData("project:Name", "$(AssemblyName)")] [InlineData("project:Directory", "$(MSBuildProjectDirectory)")] + [InlineData("publish:Runtime", "$(RuntimeIdentifier)")] public void Formatting_script_commands_replaces_variables_with_the_right_msbuild_properties( string variable, string msbuildReplacement) @@ -41,7 +43,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests [InlineData("compile:RuntimeOutputDir")] [InlineData("compile:RuntimeIdentifier")] [InlineData("publish:TargetFramework")] - [InlineData("publish:Runtime")] public void Formatting_script_commands_throws_when_variable_is_unsupported(string unsupportedVariable) { var scriptMigrationRule = new MigrateScriptsRule(); @@ -158,7 +159,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests { count += 1; var scriptExtensionProperties = - propertyGroup.Properties.Where(p => p.Name.Contains($"MigratedScriptExtension_{count}")).ToArray(); + propertyGroup.Properties.Where(p => p.Name.Contains($"MigratedScriptExtension_{scriptName}_{count}")).ToArray(); scriptExtensionProperties.All(p => p.Value == ".sh" || p.Value == ".cmd").Should().BeTrue(); scriptExtensionProperties.Count().Should().Be(2); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs index 2018aec96..237f7c4b3 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Threading.Tasks; using Xunit; using FluentAssertions; +using Microsoft.DotNet.ProjectJsonMigration.Rules; namespace Microsoft.DotNet.ProjectJsonMigration.Tests { @@ -19,7 +20,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests { var testDirectory = Temp.CreateDirectory().Path; var testPJ = new ProjectJsonBuilder(TestAssetsManager) - .FromDefaultBase() + .FromTestAssetBase("TestAppWithRuntimeOptions") .WithCustomProperty("buildOptions", new Dictionary { { "emitEntryPoint", "false" } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs index a89257594..7400ffc99 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectJsonMigration.Rules; using Microsoft.DotNet.ProjectModel; using NuGet.Frameworks; diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAConditionalTransform.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAConditionalTransform.cs index a36c23817..c74fb6b04 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAConditionalTransform.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAConditionalTransform.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Xunit; using FluentAssertions; using Microsoft.Build.Construction; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; namespace Microsoft.DotNet.ProjectJsonMigration.Tests { diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenATransformApplicator.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenATransformApplicator.cs index cc348a2ad..b68024f75 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenATransformApplicator.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenATransformApplicator.cs @@ -4,6 +4,8 @@ using Xunit; using Xunit.Runner.DotNet; using FluentAssertions; using System.Linq; +using Microsoft.DotNet.ProjectJsonMigration.Models; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; namespace Microsoft.DotNet.ProjectJsonMigration.Tests.Transforms { @@ -23,15 +25,13 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests.Transforms var transform1 = new AddItemTransform("item", fullItemTransformSetIncludeValue, "exclude1", - t => true, - mergeExisting: true) + t => true) .WithMetadata(metadata[0]); var transform2 = new AddItemTransform("item", fullItemTransformSetIncludeValue, "exclude2", - t => true, - mergeExisting: true) + t => true) .WithMetadata(metadata[1]); var mockProj = ProjectRootElement.Create(); @@ -64,26 +64,5 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests.Transforms foundMetadata.All(kv => kv.Value).Should().BeTrue(); } - -// [Fact] -// public void It_adds_duplicate_properties_to_the_project_with_specified_value_when_the_property_exists() -// { -// var mockProj = ProjectRootElement.Create(); -// var propertyGroup = mockProj.AddPropertyGroup(); -// var propertyName = "Property1"; -// var propertyValue = "Value1"; -// -// var propertyTransform = new AddPropertyTransform(propertyName, propertyValue, t => true); -// propertyTransform.Transform("_"); -// propertyTransform.Transform("_", mockProj, propertyGroup); -// -// propertyGroup.Properties.Count.Should().Be(2); -// -// foreach (var property in propertyGroup.Properties) -// { -// property.Name.Should().Be(propertyName); -// property.Value.Should().Be(propertyValue); -// } -// } } } \ No newline at end of file diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddBoolPropertyTransform.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddBoolPropertyTransform.cs deleted file mode 100644 index 9d30d4284..000000000 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddBoolPropertyTransform.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectJsonMigration; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Xunit; -using FluentAssertions; - -namespace Microsoft.DotNet.Migration.Tests -{ - public class GivenAnAddBoolPropertyTransform - { - [Theory] - [InlineData(true)] - [InlineData(false)] - public void It_returns_a_property_to_the_project_with_boolean_value(bool propertyValue) - { - var propertyName = "Property1"; - - var propertyTransform = new AddBoolPropertyTransform(propertyName, t => true); - var property = propertyTransform.Transform(propertyValue); - - property.Name.Should().Be(propertyName); - property.Value.Should().Be(propertyValue.ToString()); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void It_returns_null_when_condition_is_false(bool propertyValue) - { - var propertyName = "Property1"; - - var propertyTransform = new AddBoolPropertyTransform(propertyName, t => false); - propertyTransform.Transform(propertyValue).Should().BeNull(); - } - } -} diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddItemTransform.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddItemTransform.cs index 0ea9c4cef..86113f10d 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddItemTransform.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddItemTransform.cs @@ -6,6 +6,8 @@ using System.Linq; using System.Threading.Tasks; using Xunit; using FluentAssertions; +using Microsoft.DotNet.ProjectJsonMigration.Models; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; namespace Microsoft.DotNet.Migration.Tests { diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddPropertyTransform.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddPropertyTransform.cs index 6d497a522..ac6be55f9 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddPropertyTransform.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddPropertyTransform.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading.Tasks; using Xunit; using FluentAssertions; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; namespace Microsoft.DotNet.Migration.Tests { diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddStringPropertyTransform.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddStringPropertyTransform.cs deleted file mode 100644 index 17784f1c8..000000000 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnAddStringPropertyTransform.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Microsoft.Build.Construction; -using Microsoft.DotNet.ProjectJsonMigration; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Xunit; -using FluentAssertions; - -namespace Microsoft.DotNet.Migration.Tests -{ - public class GivenAnAddStringPropertyTransform - { - [Fact] - public void It_adds_a_property_to_the_project_with_string_value() - { - var propertyName = "Property1"; - var propertyValue = "TestValue1"; - - var propertyTransform = new AddStringPropertyTransform(propertyName, t => true); - var property = propertyTransform.Transform(propertyValue); - property.Name.Should().Be(propertyName); - property.Value.Should().Be(propertyValue); - } - - [Fact] - public void It_returns_null_when_propertyValue_is_null_and_condition_is_passed() - { - var propertyName = "Property1"; - string propertyValue = null; - - var propertyTransform = new AddStringPropertyTransform(propertyName, t => true); - propertyTransform.Transform(propertyValue).Should().BeNull(); - } - [Fact] - public void It_returns_null_when_propertyValue_is_null_and_condition_is_not_passed() - { - var mockProj = ProjectRootElement.Create(); - var propertyName = "Property1"; - string propertyValue = null; - - var propertyTransform = new AddStringPropertyTransform(propertyName); - propertyTransform.Transform(propertyValue).Should().BeNull(); - } - - - [Fact] - public void It_returns_null_when_condition_is_false() - { - var propertyName = "Property1"; - var propertyValue = "TestValue1"; - - var propertyTransform = new AddStringPropertyTransform(propertyName, t => false); - propertyTransform.Transform(propertyValue).Should().BeNull(); - } - } -} diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnIncludeContextTransformation.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnIncludeContextTransformation.cs index f15b0036c..454650208 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnIncludeContextTransformation.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Transforms/GivenAnIncludeContextTransformation.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.DotNet.ProjectJsonMigration.Transforms; namespace Microsoft.DotNet.Migration.Tests { diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/NewCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/NewCommand.cs index 35bb30ccd..951982dde 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/NewCommand.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/NewCommand.cs @@ -18,5 +18,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities args = $"new {args}"; return base.Execute(args); } + + public override CommandResult ExecuteWithCapturedOutput(string args = "") + { + args = $"new {args}"; + return base.ExecuteWithCapturedOutput(args); + } } } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Scenarios/GivenThatIWantToMigrateTestApps.cs b/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs similarity index 52% rename from test/Microsoft.DotNet.ProjectJsonMigration.Tests/Scenarios/GivenThatIWantToMigrateTestApps.cs rename to test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs index dbb2b7017..b541bb8dc 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Scenarios/GivenThatIWantToMigrateTestApps.cs +++ b/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs @@ -10,61 +10,65 @@ using System.Threading.Tasks; using Xunit; using FluentAssertions; using System.IO; +using System.Runtime.InteropServices; using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Cli; -using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Tools.Migrate; using Build3Command = Microsoft.DotNet.Tools.Test.Utilities.Build3Command; -using TemporaryDotnetNewTemplateProject = Microsoft.DotNet.Cli.TemporaryDotnetNewTemplateProject; namespace Microsoft.DotNet.Migration.Tests { public class GivenThatIWantToMigrateTestApps : TestBase { - private class Failure - { - public string Phase {get; set;} - public string Message {get; set;} - public string ProjectJson {get; set;} - } - [Theory] // TODO: Standalone apps [InlineData("TestAppSimple", false)] // https://github.com/dotnet/sdk/issues/73 [InlineData("TestAppWithLibrary/TestApp", false)] - [InlineData("TestAppWithRuntimeOptions", false)] - public void It_migrates_a_project(string projectName, bool isLibrary) + [InlineData("TestAppWithRuntimeOptions")] + public void It_migrates_apps(string projectName) { var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, callingMethod: "i").WithLockFiles().Path; + var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory); - BuildProjectJson(projectDirectory); - var projectJsonBuildOutputs = new HashSet(CollectBuildOutputs(projectDirectory)); - CleanBinObj(projectDirectory); - - MigrateProject(projectDirectory); - Restore(projectDirectory); - BuildMSBuild(projectDirectory); - - var msbuildBuildOutputs = new HashSet(CollectBuildOutputs(projectDirectory)); - - var outputsIdentical = projectJsonBuildOutputs.SetEquals(msbuildBuildOutputs); - - // diagnostics + var outputsIdentical = + outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs); if (!outputsIdentical) { - Console.WriteLine("Project.json Outputs:"); - Console.WriteLine(string.Join("\n", projectJsonBuildOutputs)); - - Console.WriteLine(""); - - Console.WriteLine("MSBuild Outputs:"); - Console.WriteLine(string.Join("\n", msbuildBuildOutputs)); + OutputDiagnostics(outputComparisonData); } - outputsIdentical.Should().BeTrue(); + VerifyAllMSBuildOutputsRunnable(projectDirectory); + } - if (!isLibrary) + [Fact] + public void It_migrates_dotnet_new_console_with_identical_outputs() + { + var projectDirectory = Temp.CreateDirectory().Path; + var outputComparisonData = GetDotnetNewComparisonData(projectDirectory, "console"); + + var outputsIdentical = + outputComparisonData.ProjectJsonBuildOutputs.SetEquals(outputComparisonData.MSBuildBuildOutputs); + if (!outputsIdentical) { - VerifyMSBuildOutputRunnable(projectDirectory); + OutputDiagnostics(outputComparisonData); } + outputsIdentical.Should().BeTrue(); + VerifyAllMSBuildOutputsRunnable(projectDirectory); + } + + [Fact] + // Outputs Not Identical: https://github.com/dotnet/sdk/issues/97 + public void It_migrates_dotnet_new_web_with_outputs_containing_project_json_outputs() + { + var projectDirectory = Temp.CreateDirectory().Path; + var outputComparisonData = GetDotnetNewComparisonData(projectDirectory, "web"); + + var projectJsonOutputIsSubsetOfMSBuildOutput = + outputComparisonData.ProjectJsonBuildOutputs.IsProperSubsetOf(outputComparisonData.MSBuildBuildOutputs); + if (!projectJsonOutputIsSubsetOfMSBuildOutput) + { + OutputDiagnostics(outputComparisonData); + } + projectJsonOutputIsSubsetOfMSBuildOutput.Should().BeTrue(); } [Theory] @@ -75,29 +79,14 @@ namespace Microsoft.DotNet.Migration.Tests { var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, callingMethod: "i").WithLockFiles().Path; + var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory); - BuildProjectJson(projectDirectory); - var projectJsonBuildOutputs = new HashSet(CollectBuildOutputs(projectDirectory)); - CleanBinObj(projectDirectory); + var msBuildHasAdditionalOutputsButIncludesProjectJsonOutputs = + outputComparisonData.ProjectJsonBuildOutputs.IsProperSubsetOf(outputComparisonData.MSBuildBuildOutputs); - MigrateProject(projectDirectory); - Restore(projectDirectory); - BuildMSBuild(projectDirectory); - - var msbuildBuildOutputs = new HashSet(CollectBuildOutputs(projectDirectory)); - - var msBuildHasAdditionalOutputsButIncludesProjectJsonOutputs = projectJsonBuildOutputs.IsProperSubsetOf(msbuildBuildOutputs); - - // diagnostics if (!msBuildHasAdditionalOutputsButIncludesProjectJsonOutputs) { - Console.WriteLine("Project.json Outputs:"); - Console.WriteLine(string.Join("\n", projectJsonBuildOutputs)); - - Console.WriteLine(""); - - Console.WriteLine("MSBuild Outputs:"); - Console.WriteLine(string.Join("\n", msbuildBuildOutputs)); + OutputDiagnostics(outputComparisonData); } msBuildHasAdditionalOutputsButIncludesProjectJsonOutputs.Should().BeTrue(); @@ -107,7 +96,7 @@ namespace Microsoft.DotNet.Migration.Tests public void It_migrates_an_app_with_scripts_and_the_scripts_run() { var projectDirectory = - TestAssetsManager.CreateTestInstance("TestAppWithMigrateAbleScripts", callingMethod: "i").WithLockFiles().Path; + TestAssetsManager.CreateTestInstance("TestAppWithMigrateableScripts", callingMethod: "i").WithLockFiles().Path; BuildProjectJson(projectDirectory); var projectJsonBuildOutputs = new HashSet(CollectBuildOutputs(projectDirectory)); @@ -121,26 +110,25 @@ namespace Microsoft.DotNet.Migration.Tests var outputsIdentical = projectJsonBuildOutputs.SetEquals(msbuildBuildOutputs); outputsIdentical.Should().BeTrue(); - VerifyMSBuildOutputRunnable(projectDirectory); + VerifyAllMSBuildOutputsRunnable(projectDirectory); var outputDir = PathUtility.EnsureTrailingSlash(Path.Combine(projectDirectory, "bin", "Debug", "netcoreapp1.0")); - msBuildStdOut.Should().Contain($"precompile_output ?Debug? ?{outputDir}? ?.NETCoreApp=v1.0?"); - msBuildStdOut.Should().Contain($"postcompile_output ?Debug? ?{outputDir}? ?.NETCoreApp=v1.0?"); + msBuildStdOut.Should().Contain($"precompile_output ?Debug? ?{outputDir}? ?.NETCoreApp,Version=v1.0?"); + msBuildStdOut.Should().Contain($"postcompile_output ?Debug? ?{outputDir}? ?.NETCoreApp,Version=v1.0?"); } - private string RunNetcoreappMSBuildOutput(string projectDirectory) + private MigratedBuildComparisonData GetDotnetNewComparisonData(string projectDirectory, string dotnetNewType) { - var dllFileName = Path.GetFileName(projectDirectory) + ".dll"; + DotnetNew(projectDirectory, dotnetNewType); + Restore(projectDirectory); - var runnableDll = Path.Combine(projectDirectory, "bin","Debug", "netcoreapp1.0", dllFileName); - var result = new TestCommand("dotnet").ExecuteWithCapturedOutput(runnableDll); - result.Should().Pass(); - return result.StdOut; + var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory); + return outputComparisonData; } - private void VerifyMSBuildOutputRunnable(string projectDirectory) + private void VerifyAllMSBuildOutputsRunnable(string projectDirectory) { var dllFileName = Path.GetFileName(projectDirectory) + ".dll"; @@ -153,6 +141,21 @@ namespace Microsoft.DotNet.Migration.Tests } } + private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(string projectDirectory) + { + BuildProjectJson(projectDirectory); + var projectJsonBuildOutputs = new HashSet(CollectBuildOutputs(projectDirectory)); + CleanBinObj(projectDirectory); + + MigrateProject(projectDirectory); + Restore(projectDirectory); + BuildMSBuild(projectDirectory); + + var msbuildBuildOutputs = new HashSet(CollectBuildOutputs(projectDirectory)); + + return new MigratedBuildComparisonData(projectJsonBuildOutputs, msbuildBuildOutputs); + } + private IEnumerable CollectBuildOutputs(string projectDirectory) { var fullBinPath = Path.GetFullPath(Path.Combine(projectDirectory, "bin")); @@ -182,10 +185,18 @@ namespace Microsoft.DotNet.Migration.Tests private void MigrateProject(string projectDirectory) { - var dotnetNew = new TemporaryDotnetNewTemplateProject(); - var sdkVersion = new ProjectJsonParser(dotnetNew.ProjectJson).SdkPackageVersion; - var migrationSettings = new MigrationSettings(projectDirectory, projectDirectory, sdkVersion, dotnetNew.MSBuildProject); - new ProjectMigrator().Migrate(migrationSettings); + var result = + MigrateCommand.Run(new [] { "-p", projectDirectory }); + + result.Should().Be(0); + } + + private void DotnetNew(string projectDirectory, string dotnetNewType) + { + new NewCommand().WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput($"-t {dotnetNewType}") + .Should() + .Pass(); } private void Restore(string projectDirectory) @@ -197,16 +208,46 @@ namespace Microsoft.DotNet.Migration.Tests .Pass(); } - private string BuildMSBuild(string projectDirectory) + private string BuildMSBuild(string projectDirectory, string configuration="Debug") { var result = new Build3Command() .WithWorkingDirectory(projectDirectory) - .ExecuteWithCapturedOutput(); + .ExecuteWithCapturedOutput($"/p:Configuration={configuration}"); + result .Should() .Pass(); return result.StdOut; } + + private void OutputDiagnostics(MigratedBuildComparisonData comparisonData) + { + OutputDiagnostics(comparisonData.MSBuildBuildOutputs, comparisonData.ProjectJsonBuildOutputs); + } + + private void OutputDiagnostics(HashSet msbuildBuildOutputs, HashSet projectJsonBuildOutputs) + { + Console.WriteLine("Project.json Outputs:"); + Console.WriteLine(string.Join("\n", projectJsonBuildOutputs)); + + Console.WriteLine(""); + + Console.WriteLine("MSBuild Outputs:"); + Console.WriteLine(string.Join("\n", msbuildBuildOutputs)); + } + + private class MigratedBuildComparisonData + { + public HashSet ProjectJsonBuildOutputs { get; } + public HashSet MSBuildBuildOutputs { get; } + + public MigratedBuildComparisonData(HashSet projectJsonBuildOutputs, + HashSet msBuildBuildOutputs) + { + ProjectJsonBuildOutputs = projectJsonBuildOutputs; + MSBuildBuildOutputs = msBuildBuildOutputs; + } + } } } diff --git a/test/dotnet-migrate.Tests/MSBuild.exe b/test/dotnet-migrate.Tests/MSBuild.exe new file mode 100644 index 000000000..2b4d0f999 --- /dev/null +++ b/test/dotnet-migrate.Tests/MSBuild.exe @@ -0,0 +1 @@ +https://github.com/Microsoft/msbuild/issues/927 \ No newline at end of file diff --git a/test/dotnet-migrate.Tests/MSBuild.exe.config b/test/dotnet-migrate.Tests/MSBuild.exe.config new file mode 100644 index 000000000..2b4d0f999 --- /dev/null +++ b/test/dotnet-migrate.Tests/MSBuild.exe.config @@ -0,0 +1 @@ +https://github.com/Microsoft/msbuild/issues/927 \ No newline at end of file diff --git a/test/dotnet-migrate.Tests/dotnet-migrate.Tests.xproj b/test/dotnet-migrate.Tests/dotnet-migrate.Tests.xproj new file mode 100644 index 000000000..04e81394b --- /dev/null +++ b/test/dotnet-migrate.Tests/dotnet-migrate.Tests.xproj @@ -0,0 +1,21 @@ + + + + 14.0.25123 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 1F2EF070-AC5F-4078-AFB0-65745AC691B9 + Microsoft.DotNet.ProjectJsonMigration.Tests + .\obj + .\bin\ + + + 2.0 + + + + + + \ No newline at end of file diff --git a/test/dotnet-migrate.Tests/project.json b/test/dotnet-migrate.Tests/project.json new file mode 100644 index 000000000..a7b61f903 --- /dev/null +++ b/test/dotnet-migrate.Tests/project.json @@ -0,0 +1,39 @@ +{ + "version": "1.0.0-*", + "buildOptions": { + "copyToOutput": ["MSBuild.exe", "MSBuild.exe.config"] + }, + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0" + }, + "Microsoft.DotNet.ProjectJsonMigration": { + "target": "project" + }, + "xunit": "2.2.0-beta3-build3330", + "dotnet-test-xunit": "1.0.0-rc2-318883-21", + "FluentAssertions": "4.0.0", + "moq.netcore": "4.4.0-beta8", + "Microsoft.DotNet.Tools.Tests.Utilities": { + "target": "project" + }, + "Microsoft.DotNet.Cli.Utils": { + "target": "project" + }, + "dotnet": { + "target":"project" + } + }, + + "frameworks": { + "netcoreapp1.0": { + "imports": [ + "netstandardapp1.5", + "dotnet5.4", + "portable-net451+win8" + ] + } + }, + "testRunner": "xunit" +}