diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ConstantPackageNames.cs b/src/Microsoft.DotNet.ProjectJsonMigration/PackageConstants.cs similarity index 57% rename from src/Microsoft.DotNet.ProjectJsonMigration/ConstantPackageNames.cs rename to src/Microsoft.DotNet.ProjectJsonMigration/PackageConstants.cs index ada280bbf..8df052a58 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/ConstantPackageNames.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/PackageConstants.cs @@ -3,8 +3,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration { - internal class ConstantPackageNames + internal class PackageConstants { - public const string CSdkPackageName = "Microsoft.NET.Sdk"; + public const string SdkPackageName = "Microsoft.NET.Sdk"; + public const string WebSdkPackageName = "Microsoft.NET.Sdk.Web"; } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectExtensions.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectExtensions.cs new file mode 100644 index 000000000..d08310122 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectExtensions.cs @@ -0,0 +1,67 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license info + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using Microsoft.DotNet.Internal.ProjectModel; + +namespace Microsoft.DotNet.ProjectJsonMigration +{ + internal static class ProjectExtensions + { + public static ProjectType GetProjectType(this Project project) + { + var projectType = ProjectType.Console; + if (project.IsWebProject()) + { + projectType = ProjectType.Web; + } + + return projectType; + } + + private static bool IsWebProject(this Project project) + { + if(project.IsTestProject) + { + return false; + } + + var isExecutable = project.GetCompilerOptions(null, "Debug").EmitEntryPoint.GetValueOrDefault(); + if (isExecutable + && project.HasAnyPackageContainingName(".AspNetCore.")) + { + return true; + } + + return false; + } + + private static bool HasAnyPackageContainingName(this Project project, string nameSegment) + { + 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); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectType.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectType.cs new file mode 100644 index 000000000..97001ace2 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectType.cs @@ -0,0 +1,8 @@ +namespace Microsoft.DotNet.ProjectJsonMigration +{ + internal enum ProjectType + { + Console, + 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 3f1a5de38..1e1ec3351 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs @@ -44,10 +44,15 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules PackageDependencyInfoTransform.Transform( new PackageDependencyInfo { - Name = ConstantPackageNames.CSdkPackageName, + Name = PackageConstants.SdkPackageName, Version = migrationSettings.SdkPackageVersion, PrivateAssets = "All" }), noFrameworkPackageReferenceItemGroup, mergeExisting: false); + + AddProjectTypeSpecificDependencies( + migrationRuleInputs, + migrationSettings, + noFrameworkPackageReferenceItemGroup); // Migrate Direct Deps first MigrateDependencies( @@ -76,7 +81,32 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules MigrateTools(project, migrationRuleInputs.OutputMSBuildProject); } - private void MigrateImports(ProjectPropertyGroupElement commonPropertyGroup, TargetFrameworkInformation targetFramework) + private void AddProjectTypeSpecificDependencies( + MigrationRuleInputs migrationRuleInputs, + MigrationSettings migrationSettings, + ProjectItemGroupElement noFrameworkPackageReferenceItemGroup) + { + var type = migrationRuleInputs.DefaultProjectContext.ProjectFile.GetProjectType(); + switch (type) + { + case ProjectType.Web: + _transformApplicator.Execute( + PackageDependencyInfoTransform.Transform( + new PackageDependencyInfo + { + Name = PackageConstants.WebSdkPackageName, + Version = migrationSettings.SdkPackageVersion, + PrivateAssets = "All" + }), noFrameworkPackageReferenceItemGroup, mergeExisting: false); + break; + default: + break; + } + } + + private void MigrateImports( + ProjectPropertyGroupElement commonPropertyGroup, + TargetFrameworkInformation targetFramework) { var transform = ImportsTransformation.Transform(targetFramework); @@ -168,7 +198,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules } } - _transformApplicator.Execute(transform.Transform(packageDependency), itemGroup, mergeExisting: true); + _transformApplicator.Execute( + transform.Transform(packageDependency), + itemGroup, + mergeExisting: true); } } @@ -188,7 +221,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules private void InjectAssemblyReferenceIfNotPresent(string dependencyName, IList packageDependencies) { - if (!packageDependencies.Any(dep => string.Equals(dep.Name, dependencyName, StringComparison.OrdinalIgnoreCase))) + if (!packageDependencies.Any(dep => + string.Equals(dep.Name, dependencyName, StringComparison.OrdinalIgnoreCase))) { packageDependencies.Add(new ProjectLibraryDependency { @@ -238,12 +272,16 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules return flagString; } - private IEnumerable GetAllProjectReferenceNames(Project project, NuGetFramework framework, ProjectRootElement xproj) + private IEnumerable GetAllProjectReferenceNames( + Project project, + NuGetFramework framework, + ProjectRootElement xproj) { var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(xproj); var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes()); - var migratedXProjDependencyNames = new HashSet(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension( - PathUtility.GetPathWithDirectorySeparator(p)))); + var migratedXProjDependencyNames = + new HashSet(migratedXProjDependencyPaths.Select(p => + Path.GetFileNameWithoutExtension(PathUtility.GetPathWithDirectorySeparator(p)))); var projectDependencies = _projectDependencyFinder.ResolveDirectProjectDependenciesForFramework( project, framework, @@ -252,38 +290,43 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules return projectDependencies.Select(p => p.Name).Concat(migratedXProjDependencyNames); } - private AddItemTransform FrameworkDependencyTransform => new AddItemTransform( - "Reference", - dep => dep.Name, - dep => "", - dep => true); + private AddItemTransform FrameworkDependencyTransform => + new AddItemTransform( + "Reference", + dep => dep.Name, + dep => "", + dep => true); - private Func> PackageDependencyTransform => () => new AddItemTransform( - "PackageReference", - dep => dep.Name, - dep => "", - dep => true) - .WithMetadata("Version", r => r.LibraryRange.VersionRange.OriginalString); + private Func> PackageDependencyTransform => + () => new AddItemTransform( + "PackageReference", + dep => dep.Name, + dep => "", + dep => true) + .WithMetadata("Version", r => r.LibraryRange.VersionRange.OriginalString); - private AddItemTransform PackageDependencyInfoTransform => new AddItemTransform( - "PackageReference", - dep => dep.Name, - dep => "", - dep => true) - .WithMetadata("Version", r => r.Version) - .WithMetadata("PrivateAssets", r => r.PrivateAssets, r => !string.IsNullOrEmpty(r.PrivateAssets)); + private AddItemTransform PackageDependencyInfoTransform => + new AddItemTransform( + "PackageReference", + dep => dep.Name, + dep => "", + dep => true) + .WithMetadata("Version", r => r.Version) + .WithMetadata("PrivateAssets", r => r.PrivateAssets, r => !string.IsNullOrEmpty(r.PrivateAssets)); - private AddItemTransform ToolTransform => new AddItemTransform( - "DotNetCliToolReference", - dep => dep.Name, - dep => "", - dep => true) - .WithMetadata("Version", r => r.LibraryRange.VersionRange.OriginalString); + private AddItemTransform ToolTransform => + new AddItemTransform( + "DotNetCliToolReference", + dep => dep.Name, + dep => "", + dep => true) + .WithMetadata("Version", r => r.LibraryRange.VersionRange.OriginalString); - private AddPropertyTransform ImportsTransformation => new AddPropertyTransform( - "PackageTargetFallback", - t => $"$(PackageTargetFallback);{string.Join(";", t.Imports)}", - t => t.Imports.OrEmptyIfNull().Any()); + private AddPropertyTransform ImportsTransformation => + new AddPropertyTransform( + "PackageTargetFallback", + t => $"$(PackageTargetFallback);{string.Join(";", t.Imports)}", + t => t.Imports.OrEmptyIfNull().Any()); private class PackageDependencyInfo { diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs index c173d90f9..f150ccfff 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateTFMRule.cs @@ -72,7 +72,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules { var packageRefs = outputMSBuildProject .Items - .Where(i => i.ItemType == "PackageReference" && i.Include != ConstantPackageNames.CSdkPackageName) + .Where(i => i.ItemType == "PackageReference" && i.Include != PackageConstants.SdkPackageName) .ToList(); foreach (var packageRef in packageRefs) diff --git a/src/dotnet/commands/dotnet-migrate/ProjectRootElementExtensions.cs b/src/dotnet/commands/dotnet-migrate/ProjectRootElementExtensions.cs index 262670ad0..c733e0b8b 100644 --- a/src/dotnet/commands/dotnet-migrate/ProjectRootElementExtensions.cs +++ b/src/dotnet/commands/dotnet-migrate/ProjectRootElementExtensions.cs @@ -11,7 +11,7 @@ namespace Microsoft.DotNet.Tools.Migrate return projectRootElement .Items .Where(i => i.ItemType == "PackageReference") - .First(i => i.Include == ConstantPackageNames.CSdkPackageName) + .First(i => i.Include == PackageConstants.SdkPackageName) .GetMetadataWithName("version").Value; } } diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs index b7de22eb5..071b69dca 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigratePackageDependencies.cs @@ -49,6 +49,31 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests privateAssetsMetadata.Value.Should().Be("All"); } + [Fact] + public void It_migrates_web_projects_to_have_web_sdk_PrivateAssets() + { + var mockProj = RunPackageDependenciesRuleOnPj(@" + { + ""buildOptions"": { + ""emitEntryPoint"": true + }, + ""dependencies"": { + ""Microsoft.AspNetCore.Mvc"" : { + ""version"": ""1.0.0"" + } + }, + ""frameworks"": { + ""netcoreapp1.0"": {} + } + }"); + + var packageRef = mockProj.Items.FirstOrDefault(i => + i.Include == "Microsoft.NET.Sdk.Web" && i.ItemType == "PackageReference"); + + packageRef.Should().NotBeNull(); + packageRef.GetMetadataWithName("PrivateAssets").Value.Should().NotBeNull().And.Be("All"); + } + [Fact] public void It_migrates_suppress_parent_array_to_PrivateAssets() { diff --git a/test/dotnet-migrate.Tests/NuGet.tempaspnetpatch.config b/test/dotnet-migrate.Tests/NuGet.tempaspnetpatch.config index 9d03a414f..41ba66505 100644 --- a/test/dotnet-migrate.Tests/NuGet.tempaspnetpatch.config +++ b/test/dotnet-migrate.Tests/NuGet.tempaspnetpatch.config @@ -5,6 +5,7 @@ + \ No newline at end of file