From 0831316321c0a461aa40239974de94828adfa35a Mon Sep 17 00:00:00 2001 From: Justin Goshi Date: Wed, 7 Dec 2016 11:49:15 -1000 Subject: [PATCH] Allow migration of sln files (#4949) * WIP Migrate sln files * WIP add reference to redist * Adding tests and fixing a few bugs * Fix some tests * Remove use of DeepClone * Fix test build errors * Fix more tests --- .../TestApp/.noautobuild | 0 .../TestApp/Program.cs | 17 ++++ .../TestApp/TestApp.sln | 23 ++++++ .../TestApp/TestApp.xproj | 18 ++++ .../TestApp/project.json | 30 +++++++ .../TestLibrary/.noautobuild | 0 .../TestLibrary/Helper.cs | 15 ++++ .../TestLibrary/TestLibrary.xproj | 18 ++++ .../TestLibrary/project.json | 16 ++++ ...crosoft.DotNet.ProjectJsonMigration.csproj | 3 +- .../MigrationSettings.cs | 72 ++++++++-------- .../ProjectDependencyFinder.cs | 39 +++++++-- .../ProjectMigrator.cs | 13 +-- .../MigratePackageDependenciesAndToolsRule.cs | 14 +++- .../Rules/MigrateProjectDependenciesRule.cs | 11 ++- .../dotnet-migrate/LocalizableStrings.cs | 4 +- .../commands/dotnet-migrate/MigrateCommand.cs | 82 ++++++++++++++++++- src/dotnet/dotnet.csproj | 3 +- src/redist/redist.csproj | 1 + .../GivenAProjectMigrator.cs | 6 +- ...t.DotNet.ProjectJsonMigration.Tests.csproj | 1 + .../GivenThatIWantToMigrateAssemblyInfo.cs | 2 +- .../GivenThatIWantToMigrateBuildOptions.cs | 2 +- ...enThatIWantToMigrateProjectDependencies.cs | 12 +-- .../GivenThatIWantToMigrateRuntimeOptions.cs | 4 +- .../Rules/GivenThatIWantToMigrateTFMs.cs | 8 +- .../TemporaryProjectFileRuleRunner.cs | 2 +- .../GivenThatIWantToMigrateTestApps.cs | 27 +++++- .../dotnet-migrate.Tests.csproj | 1 + .../dotnet-msbuild.Tests.csproj | 1 + test/dotnet-new.Tests/dotnet-new.Tests.csproj | 1 + .../dotnet-nuget.UnitTests.csproj | 1 + test/dotnet.Tests/dotnet.Tests.csproj | 1 + 33 files changed, 367 insertions(+), 81 deletions(-) create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/.noautobuild create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/Program.cs create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.sln create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.xproj create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/project.json create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/.noautobuild create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/Helper.cs create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/TestLibrary.xproj create mode 100644 TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/project.json diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/.noautobuild b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/Program.cs b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/Program.cs new file mode 100644 index 000000000..ac3163a58 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/Program.cs @@ -0,0 +1,17 @@ +// 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.Diagnostics; + +namespace TestApp +{ + public class Program + { + public static int Main(string[] args) + { + Console.WriteLine(TestLibrary.Helper.GetMessage()); + return 100; + } + } +} diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.sln b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.sln new file mode 100644 index 000000000..8be435fa9 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.sln @@ -0,0 +1,23 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestApp", "TestApp.xproj", "{0138CB8F-4AA9-4029-A21E-C07C30F425BA}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "..\TestLibrary\TestLibrary.xproj", "{DC0B35D0-8A36-4B52-8A11-B86739F055D2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.Build.0 = Release|Any CPU + {DC0B35D0-8A36-4B52-8A11-B86739F055D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC0B35D0-8A36-4B52-8A11-B86739F055D2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.xproj b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.xproj new file mode 100644 index 000000000..53f0c8b7a --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/TestApp.xproj @@ -0,0 +1,18 @@ + + + + 14.0.23107 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 0138cb8f-4aa9-4029-a21e-c07c30f425ba + TestAppWithContents + ..\..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\..\artifacts\ + + + 2.0 + + + \ No newline at end of file diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/project.json b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/project.json new file mode 100644 index 000000000..666d644b9 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestApp/project.json @@ -0,0 +1,30 @@ +{ + "version": "1.0.0-*", + "buildOptions": { + "emitEntryPoint": true, + "preserveCompilationContext": true + }, + "dependencies": { + "TestLibrary": { + "target": "project", + "version": "1.0.0-*" + }, + "Microsoft.NETCore.App": "1.0.1" + }, + "frameworks": { + "netcoreapp1.0": {} + }, + "runtimes": { + "win7-x64": {}, + "win7-x86": {}, + "osx.10.10-x64": {}, + "osx.10.11-x64": {}, + "ubuntu.14.04-x64": {}, + "ubuntu.16.04-x64": {}, + "centos.7-x64": {}, + "rhel.7.2-x64": {}, + "debian.8-x64": {}, + "fedora.23-x64": {}, + "opensuse.13.2-x64": {} + } +} diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/.noautobuild b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/Helper.cs b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/Helper.cs new file mode 100644 index 000000000..6c3bc0e53 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/Helper.cs @@ -0,0 +1,15 @@ +// 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 TestLibrary +{ + public static class Helper + { + public static string GetMessage() + { + return "This string came from the test library!"; + } + } +} diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/TestLibrary.xproj b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/TestLibrary.xproj new file mode 100644 index 000000000..197251f08 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/TestLibrary.xproj @@ -0,0 +1,18 @@ + + + + 14.0.23107 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + dc0b35d0-8a36-4b52-8a11-b86739f055d2 + TestAppWithContents + ..\..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\..\artifacts\ + + + 2.0 + + + \ No newline at end of file diff --git a/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/project.json b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/project.json new file mode 100644 index 000000000..bdf53dd6e --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndMultipleProjects/TestLibrary/project.json @@ -0,0 +1,16 @@ +{ + "version": "1.0.0-*", + "buildOptions": { + "nowarn": [ + "CS1591" + ], + "additionalArguments": [ + "-highentropyva+" + ] + },"dependencies": { + "NETStandard.Library": "1.6.0" + }, + "frameworks": { + "netstandard1.5": {} + } +} diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj index 6e3d1bd0f..4099b2daa 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj @@ -1,7 +1,7 @@  - + 1.0.0-preview5 netcoreapp1.0 @@ -15,6 +15,7 @@ + diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs index 77014b747..ec993cd87 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationSettings.cs @@ -3,41 +3,32 @@ using Microsoft.Build.Construction; using Microsoft.Build.Evaluation; +using Microsoft.DotNet.Cli.Sln.Internal; namespace Microsoft.DotNet.ProjectJsonMigration { internal class MigrationSettings { - private string _msBuildProjectTemplatePath; - public string ProjectXProjFilePath { get; } public string ProjectDirectory { get; } public string OutputDirectory { get; } public ProjectRootElement MSBuildProjectTemplate { get; } + public string MSBuildProjectTemplatePath { get; } public string SdkDefaultsFilePath { get; } - - public MigrationSettings( - string projectDirectory, - string outputDirectory, - ProjectRootElement msBuildProjectTemplate, - string projectXprojFilePath=null, - string sdkDefaultsFilePath=null) : this( - projectDirectory, outputDirectory, projectXprojFilePath, sdkDefaultsFilePath) - { - MSBuildProjectTemplate = msBuildProjectTemplate != null ? msBuildProjectTemplate.DeepClone() : null; - } + public SlnFile SolutionFile { get; } public MigrationSettings( string projectDirectory, string outputDirectory, string msBuildProjectTemplatePath, string projectXprojFilePath=null, - string sdkDefaultsFilePath=null) : this( - projectDirectory, outputDirectory, projectXprojFilePath, sdkDefaultsFilePath) + string sdkDefaultsFilePath=null, + SlnFile solutionFile=null) : this( + projectDirectory, outputDirectory, projectXprojFilePath, sdkDefaultsFilePath, solutionFile) { - _msBuildProjectTemplatePath = msBuildProjectTemplatePath; + MSBuildProjectTemplatePath = msBuildProjectTemplatePath; MSBuildProjectTemplate = ProjectRootElement.Open( - _msBuildProjectTemplatePath, + MSBuildProjectTemplatePath, new ProjectCollection(), preserveFormatting: true); } @@ -45,31 +36,44 @@ namespace Microsoft.DotNet.ProjectJsonMigration private MigrationSettings( string projectDirectory, string outputDirectory, - string projectXprojFilePath=null, - string sdkDefaultsFilePath=null) + ProjectRootElement msBuildProjectTemplate, + string projectXprojFilePath = null, + string sdkDefaultsFilePath = null) : this( + projectDirectory, outputDirectory, projectXprojFilePath, sdkDefaultsFilePath, null) + { + MSBuildProjectTemplate = msBuildProjectTemplate != null ? msBuildProjectTemplate.DeepClone() : null; + } + + private MigrationSettings( + string projectDirectory, + string outputDirectory, + string projectXprojFilePath, + string sdkDefaultsFilePath, + SlnFile solutionFile) { ProjectDirectory = projectDirectory; OutputDirectory = outputDirectory; ProjectXProjFilePath = projectXprojFilePath; SdkDefaultsFilePath = sdkDefaultsFilePath; + SolutionFile = solutionFile; } - public ProjectRootElement CloneMSBuildProjectTemplate() + public static MigrationSettings CreateMigrationSettingsTestHook( + string projectDirectory, + string outputDirectory, + ProjectRootElement msBuildProjectTemplate, + string projectXprojFilePath = null, + string sdkDefaultsFilePath = null) { - ProjectRootElement msBuildProjectTemplateClone = null; - if(!string.IsNullOrEmpty(_msBuildProjectTemplatePath)) - { - msBuildProjectTemplateClone = ProjectRootElement.Open( - _msBuildProjectTemplatePath, - new ProjectCollection(), - preserveFormatting: true); - } - else if(MSBuildProjectTemplate != null) - { - msBuildProjectTemplateClone = MSBuildProjectTemplate.DeepClone(); - } - - return msBuildProjectTemplateClone; + // Product code should not call this private constructor because we don't want to call DeepClone. + // Doing so means we lose formatting. + return new MigrationSettings( + projectDirectory, + outputDirectory, + msBuildProjectTemplate, + projectXprojFilePath, + sdkDefaultsFilePath); } + } } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectDependencyFinder.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectDependencyFinder.cs index 4b417d389..eef8acf4b 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectDependencyFinder.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectDependencyFinder.cs @@ -9,6 +9,7 @@ using Microsoft.DotNet.Internal.ProjectModel.Graph; using System.Linq; using System.IO; using Newtonsoft.Json.Linq; +using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Tools.Common; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -19,18 +20,21 @@ namespace Microsoft.DotNet.ProjectJsonMigration { public IEnumerable ResolveProjectDependencies( IEnumerable projectContexts, - IEnumerable preResolvedProjects = null) + IEnumerable preResolvedProjects = null, + SlnFile solutionFile=null) { foreach (var projectContext in projectContexts) { - foreach (var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects)) + foreach (var projectDependency in + ResolveProjectDependencies(projectContext, preResolvedProjects, solutionFile)) { yield return projectDependency; } } } - public IEnumerable ResolveProjectDependencies(string projectDir, string xprojFile = null) + public IEnumerable ResolveProjectDependencies(string projectDir, + string xprojFile = null, SlnFile solutionFile = null) { var projectContexts = ProjectContext.CreateContextForEachFramework(projectDir); xprojFile = xprojFile ?? FindXprojFile(projectDir); @@ -41,13 +45,17 @@ namespace Microsoft.DotNet.ProjectJsonMigration xproj = ProjectRootElement.Open(xprojFile); } - return ResolveProjectDependencies(projectContexts, ResolveXProjProjectDependencyNames(xproj)); + return ResolveProjectDependencies( + projectContexts, + ResolveXProjProjectDependencyNames(xproj), + solutionFile); } public IEnumerable ResolveAllProjectDependenciesForFramework( ProjectDependency projectToResolve, NuGetFramework framework, - IEnumerable preResolvedProjects=null) + IEnumerable preResolvedProjects=null, + SlnFile solutionFile=null) { var projects = new List { projectToResolve }; var allDependencies = new HashSet(); @@ -72,6 +80,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration projectContext.ProjectFile, framework, preResolvedProjects, + solutionFile, HoistDependenciesThatAreNotDirectDependencies(projectToResolve, project) ); projects.AddRange(dependencies); @@ -92,12 +101,13 @@ namespace Microsoft.DotNet.ProjectJsonMigration Project project, NuGetFramework framework, IEnumerable preResolvedProjects=null, + SlnFile solutionFile = null, bool hoistedDependencies = false) { preResolvedProjects = preResolvedProjects ?? new HashSet(); var possibleProjectDependencies = - FindPossibleProjectDependencies(project.ProjectFilePath, hoistedDependencies); + FindPossibleProjectDependencies(solutionFile, project.ProjectFilePath, hoistedDependencies); var projectDependencies = new List(); @@ -174,13 +184,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration private IEnumerable ResolveProjectDependencies( ProjectContext projectContext, - IEnumerable preResolvedProjects=null) + IEnumerable preResolvedProjects=null, + SlnFile slnFile=null) { preResolvedProjects = preResolvedProjects ?? new HashSet(); var projectExports = projectContext.CreateExporter("_").GetDependencies(); var possibleProjectDependencies = - FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath); + FindPossibleProjectDependencies(slnFile, projectContext.ProjectFile.ProjectFilePath); var projectDependencies = new List(); foreach (var projectExport in @@ -221,6 +232,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration } private Dictionary FindPossibleProjectDependencies( + SlnFile slnFile, string projectJsonFilePath, bool hoistedDependencies = false) { @@ -232,6 +244,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration var globalPaths = GetGlobalPaths(projectRootDirectory); projectSearchPaths = projectSearchPaths.Union(globalPaths).ToList(); + var solutionPaths = GetSolutionPaths(slnFile); + projectSearchPaths = projectSearchPaths.Union(solutionPaths).ToList(); + var projects = new Dictionary(StringComparer.Ordinal); foreach (var project in GetPotentialProjects(projectSearchPaths, hoistedDependencies)) @@ -352,6 +367,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration return paths; } + internal static List GetSolutionPaths(SlnFile solutionFile) + { + return (solutionFile == null) + ? new List() + : new List(solutionFile.Projects.Select(p => + Path.Combine(solutionFile.BaseDirectory.FullPath, Path.GetDirectoryName(p.FilePath)))); + } + private static string ResolveRootDirectory(string projectPath) { var di = new DirectoryInfo(projectPath); diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs index a3ab045f9..f6e4c46ad 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs @@ -9,6 +9,7 @@ using Microsoft.DotNet.Internal.ProjectModel.Graph; using Microsoft.DotNet.Cli; using System.Linq; using System.IO; +using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.ProjectJsonMigration.Rules; using Microsoft.DotNet.Tools.Common; @@ -37,8 +38,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration MigrationRuleInputs rootInputs = ComputeMigrationRuleInputs(rootSettings); IEnumerable projectDependencies = null; - var tempMSBuildProjectTemplate = rootSettings.CloneMSBuildProjectTemplate(); - try { // Verify up front so we can prefer these errors over an unresolved project dependency @@ -46,7 +45,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration projectDependencies = ResolveTransitiveClosureProjectDependencies( rootSettings.ProjectDirectory, - rootSettings.ProjectXProjFilePath); + rootSettings.ProjectXProjFilePath, + rootSettings.SolutionFile); } catch (MigrationException e) { @@ -74,7 +74,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration var projectDir = Path.GetDirectoryName(project.ProjectFilePath); var settings = new MigrationSettings(projectDir, projectDir, - tempMSBuildProjectTemplate); + rootSettings.MSBuildProjectTemplatePath); MigrateProject(settings); projectMigrationReports.Add(MigrateProject(settings)); } @@ -98,10 +98,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration } } - private IEnumerable ResolveTransitiveClosureProjectDependencies(string rootProject, string xprojFile) + private IEnumerable ResolveTransitiveClosureProjectDependencies( + string rootProject, string xprojFile, SlnFile solutionFile) { HashSet projectsMap = new HashSet(new ProjectDependencyComparer()); - var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile); + var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile, solutionFile); Queue projectsQueue = new Queue(projectDependencies); while (projectsQueue.Count() != 0) diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs index 5e655fba0..e6b9cdaab 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Build.Construction; +using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectJsonMigration.Transforms; using Microsoft.DotNet.Internal.ProjectModel; @@ -51,6 +52,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules null, project.Dependencies, migrationRuleInputs.ProjectXproj, + migrationSettings.SolutionFile, itemGroup: noFrameworkPackageReferenceItemGroup); MigrationTrace.Instance.WriteLine($"Migrating {targetFrameworks.Count()} target frameworks"); @@ -65,7 +67,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules migrationRuleInputs.OutputMSBuildProject, targetFramework.FrameworkName, targetFramework.Dependencies, - migrationRuleInputs.ProjectXproj); + migrationRuleInputs.ProjectXproj, + migrationSettings.SolutionFile); } MigrateTools(project, migrationRuleInputs.OutputMSBuildProject); @@ -213,9 +216,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules NuGetFramework framework, IEnumerable dependencies, ProjectRootElement xproj, + SlnFile solutionFile, ProjectItemGroupElement itemGroup=null) { - var projectDependencies = new HashSet(GetAllProjectReferenceNames(project, framework, xproj)); + var projectDependencies = new HashSet(GetAllProjectReferenceNames(project, framework, xproj, solutionFile)); var packageDependencies = dependencies.Where(d => !projectDependencies.Contains(d.Name)).ToList(); string condition = framework?.GetMSBuildCondition() ?? ""; @@ -360,7 +364,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules private IEnumerable GetAllProjectReferenceNames( Project project, NuGetFramework framework, - ProjectRootElement xproj) + ProjectRootElement xproj, + SlnFile solutionFile) { var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(xproj); var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes()); @@ -370,7 +375,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules var projectDependencies = _projectDependencyFinder.ResolveDirectProjectDependenciesForFramework( project, framework, - preResolvedProjects: migratedXProjDependencyNames); + preResolvedProjects: migratedXProjDependencyNames, + solutionFile: solutionFile); return projectDependencies.Select(p => p.Name).Concat(migratedXProjDependencyNames); } diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs index 1ac8aaa9e..bcda28e16 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigrateProjectDependenciesRule.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Build.Construction; +using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.ProjectJsonMigration.Transforms; using Microsoft.DotNet.Internal.ProjectModel; using Microsoft.DotNet.Tools.Common; @@ -36,7 +37,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules Path.GetFileNameWithoutExtension(PathUtility.GetPathWithDirectorySeparator(p)))); MigrateProjectJsonProjectDependencies( migrationRuleInputs.ProjectContexts, - migratedXProjDependencyNames, + migratedXProjDependencyNames, + migrationSettings.SolutionFile, migrationRuleInputs.OutputMSBuildProject); } @@ -79,6 +81,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules public void MigrateProjectJsonProjectDependencies( IEnumerable projectContexts, HashSet migratedXProjDependencyNames, + SlnFile solutionFile, ProjectRootElement outputMSBuildProject) { if(projectContexts.Any()) @@ -87,6 +90,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules projectContexts.First().ProjectFile, null, migratedXProjDependencyNames, + solutionFile, outputMSBuildProject); } @@ -96,6 +100,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules projectContext.ProjectFile, projectContext.TargetFramework, migratedXProjDependencyNames, + solutionFile, outputMSBuildProject); } } @@ -104,12 +109,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules Project project, NuGetFramework framework, HashSet migratedXProjDependencyNames, + SlnFile solutionFile, ProjectRootElement outputMSBuildProject) { var projectDependencies = _projectDependencyFinder.ResolveAllProjectDependenciesForFramework( new ProjectDependency(project.Name, project.ProjectFilePath, false), framework, - migratedXProjDependencyNames); + migratedXProjDependencyNames, + solutionFile); var projectDependencyTransformResults = projectDependencies.Select(p => diff --git a/src/dotnet/commands/dotnet-migrate/LocalizableStrings.cs b/src/dotnet/commands/dotnet-migrate/LocalizableStrings.cs index 64434c567..d614e4fbe 100644 --- a/src/dotnet/commands/dotnet-migrate/LocalizableStrings.cs +++ b/src/dotnet/commands/dotnet-migrate/LocalizableStrings.cs @@ -6,12 +6,14 @@ namespace Microsoft.DotNet.Tools.Migrate public const string AppDescription = "Command used to migrate project.json projects to msbuild"; - public const string CmdProjectArgument = "PROJECT_JSON/GLOBAL_JSON/PROJECT_DIR"; + public const string CmdProjectArgument = "PROJECT_JSON/GLOBAL_JSON/SOLUTION_FILE/PROJECT_DIR"; public const string CmdProjectArgumentDescription = @"The path to - a project.json file to migrate. or - a global.json file, it will migrate the folders specified in global.json. +or + - a solution.sln file, it will migrate the projects referenced in the solution. or - a directory to migrate, it will recursively search for project.json files to migrate. Defaults to current directory if nothing is specified."; diff --git a/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs b/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs index 31ede5a7f..6d75026cd 100644 --- a/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs +++ b/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using Microsoft.Build.Construction; using Microsoft.Build.Evaluation; +using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectJsonMigration; using Microsoft.DotNet.Internal.ProjectModel; @@ -18,6 +19,9 @@ namespace Microsoft.DotNet.Tools.Migrate { public partial class MigrateCommand { + private const string CSharpProjectTypeGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; + + private SlnFile _slnFile; private readonly DirectoryInfo _workspaceDirectory; private readonly DirectoryInfo _backupDirectory; private readonly string _templateFile; @@ -70,7 +74,9 @@ namespace Microsoft.DotNet.Tools.Migrate projectDirectory, outputDirectory, msBuildTemplatePath, - _xprojFilePath); + _xprojFilePath, + null, + _slnFile); var projectMigrationReport = new ProjectMigrator().Migrate(migrationSettings, _skipProjectReferences); if (migrationReport == null) @@ -87,11 +93,46 @@ namespace Microsoft.DotNet.Tools.Migrate temporaryDotnetNewProject.Clean(); + UpdateSolutionFile(migrationReport); + MoveProjectJsonArtifactsToBackup(migrationReport); return migrationReport.FailedProjectsCount; } + private void UpdateSolutionFile(MigrationReport migrationReport) + { + if (_slnFile == null) + { + return; + } + + if (migrationReport.FailedProjectsCount > 0) + { + return; + } + + foreach (var project in _slnFile.Projects) + { + var projectDirectory = Path.Combine( + _slnFile.BaseDirectory.FullPath, + Path.GetDirectoryName(project.FilePath)); + + var csprojFiles = new DirectoryInfo(projectDirectory) + .EnumerateFiles() + .Where(f => f.Extension == ".csproj"); + + if (csprojFiles.Count() == 1) + { + project.FilePath = Path.Combine(Path.GetDirectoryName(project.FilePath), csprojFiles.First().Name); + project.TypeGuid = CSharpProjectTypeGuid; + } + } + + _slnFile.Write(Path.Combine(_slnFile.BaseDirectory.FullPath, + Path.GetFileName(_slnFile.FileName))); + } + private void MoveProjectJsonArtifactsToBackup(MigrationReport migrationReport) { if (_skipBackup) @@ -269,13 +310,23 @@ namespace Microsoft.DotNet.Tools.Migrate } else if (projectArg.EndsWith(GlobalSettings.FileName, StringComparison.OrdinalIgnoreCase)) { - projects = GetProjectsFromGlobalJson(projectArg); + projects = GetProjectsFromGlobalJson(projectArg); if (!projects.Any()) { throw new Exception("Unable to find any projects in global.json"); } } + else if (File.Exists(projectArg) && + string.Equals(Path.GetExtension(projectArg), ".sln", StringComparison.OrdinalIgnoreCase)) + { + projects = GetProjectsFromSolution(projectArg); + + if (!projects.Any()) + { + throw new Exception($"Unable to find any projects in {projectArg}"); + } + } else if (Directory.Exists(projectArg)) { projects = Directory.EnumerateFiles(projectArg, Project.FileName, SearchOption.AllDirectories); @@ -287,7 +338,7 @@ namespace Microsoft.DotNet.Tools.Migrate } else { - throw new Exception($"Invalid project argument - '{projectArg}' is not a project.json or a global.json file and a directory named '{projectArg}' doesn't exist."); + throw new Exception($"Invalid project argument - '{projectArg}' is not a project.json, global.json, or solution.sln file and a directory named '{projectArg}' doesn't exist."); } foreach(var project in projects) @@ -336,7 +387,7 @@ namespace Microsoft.DotNet.Tools.Migrate foreach (var projectDirectory in directory.EnumerateDirectories()) { - var projectFilePath = Path.Combine(projectDirectory.FullName, "project.json"); + var projectFilePath = Path.Combine(projectDirectory.FullName, Project.FileName); if (File.Exists(projectFilePath)) { @@ -345,5 +396,28 @@ namespace Microsoft.DotNet.Tools.Migrate } } } + + private IEnumerable GetProjectsFromSolution(string slnPath) + { + if (!File.Exists(slnPath)) + { + throw new Exception($"Unable to find the solution file at {slnPath}"); + } + + _slnFile = new SlnFile(); + _slnFile.Read(slnPath); + + foreach (var project in _slnFile.Projects) + { + var projectFilePath = Path.Combine(_slnFile.BaseDirectory.FullPath, + Path.Combine(Path.GetDirectoryName(project.FilePath), Project.FileName)); + + if (File.Exists(projectFilePath)) + { + yield return projectFilePath; + } + } + } + } } diff --git a/src/dotnet/dotnet.csproj b/src/dotnet/dotnet.csproj index 791d0955e..11905cb8b 100755 --- a/src/dotnet/dotnet.csproj +++ b/src/dotnet/dotnet.csproj @@ -1,7 +1,7 @@  - + 1.0.0-preview5 netcoreapp1.0 @@ -26,6 +26,7 @@ + diff --git a/src/redist/redist.csproj b/src/redist/redist.csproj index 784c8deed..b3cee8981 100644 --- a/src/redist/redist.csproj +++ b/src/redist/redist.csproj @@ -41,6 +41,7 @@ + diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs index 75b06b538..b6d321f77 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs @@ -27,7 +27,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectDirectoryRelativeFilePaths = EnumerateFilesWithRelativePath(testProjectDirectory); var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(testProjectDirectory, outputDirectory, mockProj); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(testProjectDirectory, outputDirectory, mockProj); var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); projectMigrator.Migrate(testSettings); @@ -46,7 +46,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests .Path; var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, mockProj); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(testProjectDirectory, testProjectDirectory, mockProj); var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); var report = projectMigrator.Migrate(testSettings); @@ -67,7 +67,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests .Path; var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, mockProj); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(testProjectDirectory, testProjectDirectory, mockProj); var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); var report = projectMigrator.Migrate(testSettings); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj index 5b9766753..68d3c381d 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj @@ -22,6 +22,7 @@ + diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAssemblyInfo.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAssemblyInfo.cs index 3739a183f..891b23e42 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAssemblyInfo.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateAssemblyInfo.cs @@ -25,7 +25,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(projectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); _mockProject = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(projectDirectory, projectDirectory, _mockProject, null); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(projectDirectory, projectDirectory, _mockProject, null); var testInputs = new MigrationRuleInputs( new[] {projectContext}, _mockProject, diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs index 3d1feae9a..16249caa4 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateBuildOptions.cs @@ -40,7 +40,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var testProjectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithRuntimeOptions").Path; var projectContext = ProjectContext.Create(testProjectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); - var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, templateProj); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(testProjectDirectory, testProjectDirectory, templateProj); var testInputs = new MigrationRuleInputs(new[] {projectContext}, templateProj, templateProj.AddItemGroup(), templateProj.AddPropertyGroup()); new MigrateBuildOptionsRule().Apply(testSettings, testInputs); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs index b14dc4ce2..52900923a 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateProjectDependencies.cs @@ -27,7 +27,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(appDirectory, appDirectory, mockProj, null); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(appDirectory, appDirectory, mockProj, null); var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(), mockProj.AddPropertyGroup()); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); @@ -51,7 +51,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(appDirectory, appDirectory, mockProj, null); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(appDirectory, appDirectory, mockProj, null); var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(), mockProj.AddPropertyGroup()); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); @@ -71,7 +71,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(appDirectory, appDirectory, mockProj, null); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(appDirectory, appDirectory, mockProj, null); var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(), mockProj.AddPropertyGroup()); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); @@ -97,7 +97,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(appDirectory, appDirectory, mockProj); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(appDirectory, appDirectory, mockProj); var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(), mockProj.AddPropertyGroup()); Action action = () => new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); @@ -260,7 +260,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.Net451); var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(appDirectory, appDirectory, mockProj, null); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(appDirectory, appDirectory, mockProj, null); var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(), mockProj.AddPropertyGroup()); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); @@ -338,7 +338,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(appDirectory, targetFramework); var mockProj = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(appDirectory, appDirectory, mockProj, null); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(appDirectory, appDirectory, mockProj, null); var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(), mockProj.AddPropertyGroup()); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs index af6dd1f3f..7dfad829a 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateRuntimeOptions.cs @@ -34,7 +34,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(projectDir, FrameworkConstants.CommonFrameworks.NetCoreApp10); - var testSettings = new MigrationSettings(projectDir, projectDir, default(ProjectRootElement)); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(projectDir, projectDir, default(ProjectRootElement)); var testInputs = new MigrationRuleInputs(new[] { projectContext }, null, null, null); new MigrateRuntimeOptionsRule().Apply(testSettings, testInputs); @@ -54,7 +54,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(projectDir, FrameworkConstants.CommonFrameworks.NetCoreApp10); - var testSettings = new MigrationSettings(projectDir, projectDir, default(ProjectRootElement)); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(projectDir, projectDir, default(ProjectRootElement)); var testInputs = new MigrationRuleInputs(new[] { projectContext }, null, null, null); new MigrateRuntimeOptionsRule().Apply(testSettings, testInputs); diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs index df78b2521..8efd27482 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/Rules/GivenThatIWantToMigrateTFMs.cs @@ -30,7 +30,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContext = ProjectContext.Create(testDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var mockProj = ProjectRootElement.Create(); - var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); + var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj); var migrationInputs = new MigrationRuleInputs( new[] { projectContext }, mockProj, @@ -54,7 +54,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContexts = ProjectContext.CreateContextForEachFramework(testDirectory); var mockProj = ProjectRootElement.Create(); - var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); + var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj); var migrationInputs = new MigrationRuleInputs( projectContexts, mockProj, @@ -79,7 +79,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var projectContexts = ProjectContext.CreateContextForEachFramework(testDirectory); var mockProj = ProjectRootElement.Create(); - var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); + var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj); var migrationInputs = new MigrationRuleInputs( projectContexts, mockProj, @@ -109,7 +109,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests var mockProj = ProjectRootElement.Create(); // Run BuildOptionsRule - var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); + var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj); var migrationInputs = new MigrationRuleInputs( projectContexts, mockProj, diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs index 21380e997..f223ffe68 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/TemporaryProjectFileRuleRunner.cs @@ -28,7 +28,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests ProjectContext projectContext, string testDirectory, ProjectRootElement xproj) { var project = ProjectRootElement.Create(); - var testSettings = new MigrationSettings(testDirectory, testDirectory, project); + var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, project); var testInputs = new MigrationRuleInputs(new[] {projectContext}, project, project.AddItemGroup(), project.AddPropertyGroup(), diff --git a/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs b/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs index f12a9d5e4..b5a5c12a5 100644 --- a/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs +++ b/test/dotnet-migrate.Tests/GivenThatIWantToMigrateTestApps.cs @@ -449,6 +449,25 @@ namespace Microsoft.DotNet.Migration.Tests File.ReadAllText(migrationOutputFile).Should().Contain("MIGRATE1018"); } + [Fact] + public void It_migrates_sln() + { + var rootDirectory = TestAssetsManager.CreateTestInstance( + "TestAppWithSlnAndMultipleProjects", + callingMethod: "a").Path; + + var testAppProjectDirectory = Path.Combine(rootDirectory, "TestApp"); + var testLibProjectDirectory = Path.Combine(rootDirectory, "TestLibrary"); + string slnPath = Path.Combine(testAppProjectDirectory, "TestApp.sln"); + + CleanBinObj(testAppProjectDirectory); + CleanBinObj(testLibProjectDirectory); + + MigrateProject(slnPath); + Restore(testAppProjectDirectory, "TestApp.csproj"); + BuildMSBuild(testAppProjectDirectory, "TestApp.sln", "Release"); + } + private void VerifyAutoInjectedDesktopReferences(string projectDirectory, string projectName, bool shouldBePresent) { if (projectName != null) @@ -637,7 +656,11 @@ namespace Microsoft.DotNet.Migration.Tests if (projectName != null) { - command.Execute($"{projectName}.csproj /p:SkipInvalidConfigurations=true;_InvalidConfigurationWarning=false") + if (!Path.HasExtension(projectName)) + { + projectName += ".csproj"; + } + command.Execute($"{projectName} /p:SkipInvalidConfigurations=true;_InvalidConfigurationWarning=false") .Should().Pass(); } else @@ -653,7 +676,7 @@ namespace Microsoft.DotNet.Migration.Tests string configuration="Debug", string runtime=null) { - if (projectName != null) + if (projectName != null && !Path.HasExtension(projectName)) { projectName = projectName + ".csproj"; } diff --git a/test/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj b/test/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj index 6c1d0fab2..0337b3956 100644 --- a/test/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj +++ b/test/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj @@ -19,6 +19,7 @@ + diff --git a/test/dotnet-msbuild.Tests/dotnet-msbuild.Tests.csproj b/test/dotnet-msbuild.Tests/dotnet-msbuild.Tests.csproj index 97cac8e4c..1f11e9657 100644 --- a/test/dotnet-msbuild.Tests/dotnet-msbuild.Tests.csproj +++ b/test/dotnet-msbuild.Tests/dotnet-msbuild.Tests.csproj @@ -18,6 +18,7 @@ + true diff --git a/test/dotnet-new.Tests/dotnet-new.Tests.csproj b/test/dotnet-new.Tests/dotnet-new.Tests.csproj index fd1a60c05..84fe69b8a 100644 --- a/test/dotnet-new.Tests/dotnet-new.Tests.csproj +++ b/test/dotnet-new.Tests/dotnet-new.Tests.csproj @@ -18,6 +18,7 @@ + true diff --git a/test/dotnet-nuget.UnitTests/dotnet-nuget.UnitTests.csproj b/test/dotnet-nuget.UnitTests/dotnet-nuget.UnitTests.csproj index f4d60b799..7ee0d872c 100644 --- a/test/dotnet-nuget.UnitTests/dotnet-nuget.UnitTests.csproj +++ b/test/dotnet-nuget.UnitTests/dotnet-nuget.UnitTests.csproj @@ -17,6 +17,7 @@ + true diff --git a/test/dotnet.Tests/dotnet.Tests.csproj b/test/dotnet.Tests/dotnet.Tests.csproj index 795afccf1..4a559609a 100644 --- a/test/dotnet.Tests/dotnet.Tests.csproj +++ b/test/dotnet.Tests/dotnet.Tests.csproj @@ -31,6 +31,7 @@ + true