From e3bc102b0622cb18013f9d1a6b06c48f23355b23 Mon Sep 17 00:00:00 2001 From: Krzysztof Wicher Date: Mon, 31 Oct 2016 16:34:37 -0700 Subject: [PATCH] When Library add reference to NETStandardLib if not present --- .../LibraryWithNetStandardLibRef/.noautobuild | 1 + .../LibraryWithNetStandardLibRef/Program.cs | 5 ++ .../LibraryWithNetStandardLibRef/project.json | 10 +++ .../.noautobuild | 1 + .../Program.cs | 5 ++ .../project.json | 9 +++ .../PackageConstants.cs | 2 + .../ProjectExtensions.cs | 72 +++++++++---------- .../ProjectType.cs | 5 +- .../MigratePackageDependenciesAndToolsRule.cs | 15 ++++ .../GivenThatIWantToMigrateAspNetTools.cs | 5 +- ...enThatIWantToMigratePackageDependencies.cs | 30 ++++++++ .../GivenThatIWantToMigrateTestApps.cs | 13 ++++ 13 files changed, 134 insertions(+), 39 deletions(-) create mode 100644 TestAssets/TestProjects/LibraryWithNetStandardLibRef/.noautobuild create mode 100644 TestAssets/TestProjects/LibraryWithNetStandardLibRef/Program.cs create mode 100644 TestAssets/TestProjects/LibraryWithNetStandardLibRef/project.json create mode 100644 TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/.noautobuild create mode 100644 TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/Program.cs create mode 100644 TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/project.json diff --git a/TestAssets/TestProjects/LibraryWithNetStandardLibRef/.noautobuild b/TestAssets/TestProjects/LibraryWithNetStandardLibRef/.noautobuild new file mode 100644 index 000000000..8f7edc4ac --- /dev/null +++ b/TestAssets/TestProjects/LibraryWithNetStandardLibRef/.noautobuild @@ -0,0 +1 @@ +noautobuild \ No newline at end of file diff --git a/TestAssets/TestProjects/LibraryWithNetStandardLibRef/Program.cs b/TestAssets/TestProjects/LibraryWithNetStandardLibRef/Program.cs new file mode 100644 index 000000000..79ddf6c75 --- /dev/null +++ b/TestAssets/TestProjects/LibraryWithNetStandardLibRef/Program.cs @@ -0,0 +1,5 @@ +using System; + +class Program +{ +} diff --git a/TestAssets/TestProjects/LibraryWithNetStandardLibRef/project.json b/TestAssets/TestProjects/LibraryWithNetStandardLibRef/project.json new file mode 100644 index 000000000..519b9beee --- /dev/null +++ b/TestAssets/TestProjects/LibraryWithNetStandardLibRef/project.json @@ -0,0 +1,10 @@ +{ + "frameworks": { + "netstandard1.3": { + "dependencies": { + "System.AppContext": "4.1.0", + "NETStandard.Library": "1.5.0" + } + } + } +} diff --git a/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/.noautobuild b/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/.noautobuild new file mode 100644 index 000000000..8f7edc4ac --- /dev/null +++ b/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/.noautobuild @@ -0,0 +1 @@ +noautobuild \ No newline at end of file diff --git a/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/Program.cs b/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/Program.cs new file mode 100644 index 000000000..79ddf6c75 --- /dev/null +++ b/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/Program.cs @@ -0,0 +1,5 @@ +using System; + +class Program +{ +} diff --git a/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/project.json b/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/project.json new file mode 100644 index 000000000..2ef2a4a2c --- /dev/null +++ b/TestAssets/TestProjects/LibraryWithoutNetStandardLibRef/project.json @@ -0,0 +1,9 @@ +{ + "frameworks": { + "netstandard1.3": { + "dependencies": { + "System.AppContext": "4.1.0" + } + } + } +} diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/PackageConstants.cs b/src/Microsoft.DotNet.ProjectJsonMigration/PackageConstants.cs index f897d09be..6317b2a71 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/PackageConstants.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/PackageConstants.cs @@ -19,6 +19,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration public const string TestSdkPackageName = "Microsoft.NET.Test.Sdk"; public const string XUnitPackageName = "xunit"; public const string XUnitRunnerPackageName = "xunit.runner.visualstudio"; + public const string NetStandardPackageName = "NETStandard.Library"; + public const string NetStandardPackageVersion = "1.6.0"; public static readonly IDictionary ProjectDependencyPackages = new Dictionary { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectExtensions.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectExtensions.cs index a2e754d26..9bca917b0 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectExtensions.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectExtensions.cs @@ -13,59 +13,59 @@ namespace Microsoft.DotNet.ProjectJsonMigration { public static ProjectType GetProjectType(this Project project) { - var projectType = ProjectType.Console; - if (project.IsWebProject()) - { - projectType = ProjectType.Web; - } - else if (project.IsTestProject) + ProjectType projectType = ProjectType.Library; + if (project.IsTestProject) { projectType = ProjectType.Test; } + else if (project.HasEntryPoint()) + { + if (project.HasDependency(ContainingName(".AspNetCore."))) + { + projectType = ProjectType.Web; + } + else + { + projectType = ProjectType.Console; + } + } return projectType; } - private static bool IsWebProject(this Project project) + private static bool HasEntryPoint(this Project project) { - if(project.IsTestProject) - { - return false; - } + return project.GetCompilerOptions(null, "Debug").EmitEntryPoint.GetValueOrDefault(); + } - var isExecutable = project.GetCompilerOptions(null, "Debug").EmitEntryPoint.GetValueOrDefault(); - if (isExecutable - && project.HasAnyPackageContainingName(".AspNetCore.")) + private static Func ContainingName(string nameSegment) + { + return x => x.Name.IndexOf(nameSegment, StringComparison.OrdinalIgnoreCase) > -1; + } + + public static bool HasDependency(this Project project, Func pred) + { + if (HasAnyDependency(project.Dependencies, pred)) { return true; } + foreach (var tf in project.GetTargetFrameworks()) + { + if(HasAnyDependency(tf.Dependencies, pred)) + { + return true; + } + } + return false; } - private static bool HasAnyPackageContainingName(this Project project, string nameSegment) + private static bool HasAnyDependency( + IEnumerable dependencies, + Func pred) { - var containsPackageName = HasAnyPackageContainingName( - new ReadOnlyCollection(project.Dependencies), - nameSegment); - foreach (var tf in project.GetTargetFrameworks()) - { - if(containsPackageName) - { - break; - } - - containsPackageName = HasAnyPackageContainingName(tf.Dependencies, nameSegment); - } - - return containsPackageName; - } - - private static bool HasAnyPackageContainingName( - IReadOnlyList dependencies, - string nameSegment) - { - return dependencies.Any(x => x.Name.IndexOf(nameSegment, StringComparison.OrdinalIgnoreCase) > -1); + return dependencies.Any(pred); } } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectType.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectType.cs index 659ee6d5d..93349d576 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectType.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectType.cs @@ -3,7 +3,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration internal enum ProjectType { Console, - Web, - Test + Library, + Test, + Web } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs index a9f04e13c..c6a3ff2e2 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs @@ -136,6 +136,21 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules mergeExisting: false); } break; + case ProjectType.Library: + if (!project.HasDependency( + (dep) => dep.Name.Trim().ToLower() == PackageConstants.NetStandardPackageName.ToLower())) + { + _transformApplicator.Execute( + PackageDependencyInfoTransform().Transform( + new PackageDependencyInfo + { + Name = PackageConstants.NetStandardPackageName, + Version = PackageConstants.NetStandardPackageVersion + }), + noFrameworkPackageReferenceItemGroup, + mergeExisting: true); + } + break; default: break; } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAspNetTools.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAspNetTools.cs index 7702dcd71..f7fc798b8 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAspNetTools.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAspNetTools.cs @@ -44,7 +44,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests } }"); - var packageRef = mockProj.Items.Where(i => i.Include != "Microsoft.NET.Sdk" && i.ItemType == "PackageReference").Should().BeEmpty(); + var packageRef = mockProj.Items.Where(i => + i.Include != "Microsoft.NET.Sdk" && + i.Include != "NETStandard.Library" && + i.ItemType == "PackageReference").Should().BeEmpty(); } [Theory] diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs index 0fd10e329..4170568fe 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs @@ -347,6 +347,36 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests i.GetMetadataWithName("Version").Value == "2.2.0-beta4-build1188")); } + [Theory] + [InlineData(@" + { + ""frameworks"": { + ""netstandard1.3"": { + ""dependencies"": { + ""System.AppContext"": ""4.1.0"", + ""NETStandard.Library"": ""1.5.0"" + } + } + } + }")] + [InlineData(@" + { + ""frameworks"": { + ""netstandard1.3"": { + ""dependencies"": { + ""System.AppContext"": ""4.1.0"" + } + } + } + }")] + public void It_migrates_library_and_does_not_double_netstandard_ref(string pjContent) + { + var mockProj = RunPackageDependenciesRuleOnPj(pjContent); + + mockProj.Items.Should().ContainSingle( + i => (i.Include == "NETStandard.Library" && i.ItemType == "PackageReference")); + } + private void EmitsPackageReferences(ProjectRootElement mockProj, params Tuple[] packageSpecs) { foreach (var packageSpec in packageSpecs) diff --git a/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs b/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs index a411de556..c954d0206 100644 --- a/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs +++ b/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs @@ -423,6 +423,19 @@ namespace Microsoft.DotNet.Migration.Tests .Count().Should().Be(1); } + [Theory] + [InlineData("LibraryWithoutNetStandardLibRef")] + [InlineData("LibraryWithNetStandardLibRef")] + public void It_migrates_and_builds_library(string projectName) + { + var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, + callingMethod: $"{nameof(It_migrates_and_builds_library)}-projectName").Path; + + MigrateProject(projectDirectory); + Restore(projectDirectory, projectName); + BuildMSBuild(projectDirectory, projectName); + } + private void VerifyAutoInjectedDesktopReferences(string projectDirectory, string projectName, bool shouldBePresent) { if (projectName != null)