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
This commit is contained in:
Justin Goshi 2016-12-07 11:49:15 -10:00 committed by GitHub
parent 79e6126b2a
commit 0831316321
33 changed files with 367 additions and 81 deletions

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>0138cb8f-4aa9-4029-a21e-c07c30f425ba</ProjectGuid>
<RootNamespace>TestAppWithContents</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -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": {}
}
}

View file

@ -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!";
}
}
}

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.23107" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.23107</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>dc0b35d0-8a36-4b52-8a11-b86739f055d2</ProjectGuid>
<RootNamespace>TestAppWithContents</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,16 @@
{
"version": "1.0.0-*",
"buildOptions": {
"nowarn": [
"CS1591"
],
"additionalArguments": [
"-highentropyva+"
]
},"dependencies": {
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.5": {}
}
}

View file

@ -15,6 +15,7 @@
<EmbeddedResource Include="sdkdefaults.json" /> <EmbeddedResource Include="sdkdefaults.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -3,41 +3,32 @@
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation; using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli.Sln.Internal;
namespace Microsoft.DotNet.ProjectJsonMigration namespace Microsoft.DotNet.ProjectJsonMigration
{ {
internal class MigrationSettings internal class MigrationSettings
{ {
private string _msBuildProjectTemplatePath;
public string ProjectXProjFilePath { get; } public string ProjectXProjFilePath { get; }
public string ProjectDirectory { get; } public string ProjectDirectory { get; }
public string OutputDirectory { get; } public string OutputDirectory { get; }
public ProjectRootElement MSBuildProjectTemplate { get; } public ProjectRootElement MSBuildProjectTemplate { get; }
public string MSBuildProjectTemplatePath { get; }
public string SdkDefaultsFilePath { get; } public string SdkDefaultsFilePath { get; }
public SlnFile SolutionFile { 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 MigrationSettings( public MigrationSettings(
string projectDirectory, string projectDirectory,
string outputDirectory, string outputDirectory,
string msBuildProjectTemplatePath, string msBuildProjectTemplatePath,
string projectXprojFilePath=null, string projectXprojFilePath=null,
string sdkDefaultsFilePath=null) : this( string sdkDefaultsFilePath=null,
projectDirectory, outputDirectory, projectXprojFilePath, sdkDefaultsFilePath) SlnFile solutionFile=null) : this(
projectDirectory, outputDirectory, projectXprojFilePath, sdkDefaultsFilePath, solutionFile)
{ {
_msBuildProjectTemplatePath = msBuildProjectTemplatePath; MSBuildProjectTemplatePath = msBuildProjectTemplatePath;
MSBuildProjectTemplate = ProjectRootElement.Open( MSBuildProjectTemplate = ProjectRootElement.Open(
_msBuildProjectTemplatePath, MSBuildProjectTemplatePath,
new ProjectCollection(), new ProjectCollection(),
preserveFormatting: true); preserveFormatting: true);
} }
@ -45,31 +36,44 @@ namespace Microsoft.DotNet.ProjectJsonMigration
private MigrationSettings( private MigrationSettings(
string projectDirectory, string projectDirectory,
string outputDirectory, string outputDirectory,
ProjectRootElement msBuildProjectTemplate,
string projectXprojFilePath = null, string projectXprojFilePath = null,
string sdkDefaultsFilePath=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; ProjectDirectory = projectDirectory;
OutputDirectory = outputDirectory; OutputDirectory = outputDirectory;
ProjectXProjFilePath = projectXprojFilePath; ProjectXProjFilePath = projectXprojFilePath;
SdkDefaultsFilePath = sdkDefaultsFilePath; 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; // Product code should not call this private constructor because we don't want to call DeepClone.
if(!string.IsNullOrEmpty(_msBuildProjectTemplatePath)) // Doing so means we lose formatting.
{ return new MigrationSettings(
msBuildProjectTemplateClone = ProjectRootElement.Open( projectDirectory,
_msBuildProjectTemplatePath, outputDirectory,
new ProjectCollection(), msBuildProjectTemplate,
preserveFormatting: true); projectXprojFilePath,
} sdkDefaultsFilePath);
else if(MSBuildProjectTemplate != null)
{
msBuildProjectTemplateClone = MSBuildProjectTemplate.DeepClone();
} }
return msBuildProjectTemplateClone;
}
} }
} }

View file

@ -9,6 +9,7 @@ using Microsoft.DotNet.Internal.ProjectModel.Graph;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.Common;
using NuGet.Frameworks; using NuGet.Frameworks;
using NuGet.LibraryModel; using NuGet.LibraryModel;
@ -19,18 +20,21 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{ {
public IEnumerable<ProjectDependency> ResolveProjectDependencies( public IEnumerable<ProjectDependency> ResolveProjectDependencies(
IEnumerable<ProjectContext> projectContexts, IEnumerable<ProjectContext> projectContexts,
IEnumerable<string> preResolvedProjects = null) IEnumerable<string> preResolvedProjects = null,
SlnFile solutionFile=null)
{ {
foreach (var projectContext in projectContexts) foreach (var projectContext in projectContexts)
{ {
foreach (var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects)) foreach (var projectDependency in
ResolveProjectDependencies(projectContext, preResolvedProjects, solutionFile))
{ {
yield return projectDependency; yield return projectDependency;
} }
} }
} }
public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null) public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir,
string xprojFile = null, SlnFile solutionFile = null)
{ {
var projectContexts = ProjectContext.CreateContextForEachFramework(projectDir); var projectContexts = ProjectContext.CreateContextForEachFramework(projectDir);
xprojFile = xprojFile ?? FindXprojFile(projectDir); xprojFile = xprojFile ?? FindXprojFile(projectDir);
@ -41,13 +45,17 @@ namespace Microsoft.DotNet.ProjectJsonMigration
xproj = ProjectRootElement.Open(xprojFile); xproj = ProjectRootElement.Open(xprojFile);
} }
return ResolveProjectDependencies(projectContexts, ResolveXProjProjectDependencyNames(xproj)); return ResolveProjectDependencies(
projectContexts,
ResolveXProjProjectDependencyNames(xproj),
solutionFile);
} }
public IEnumerable<ProjectDependency> ResolveAllProjectDependenciesForFramework( public IEnumerable<ProjectDependency> ResolveAllProjectDependenciesForFramework(
ProjectDependency projectToResolve, ProjectDependency projectToResolve,
NuGetFramework framework, NuGetFramework framework,
IEnumerable<string> preResolvedProjects=null) IEnumerable<string> preResolvedProjects=null,
SlnFile solutionFile=null)
{ {
var projects = new List<ProjectDependency> { projectToResolve }; var projects = new List<ProjectDependency> { projectToResolve };
var allDependencies = new HashSet<ProjectDependency>(); var allDependencies = new HashSet<ProjectDependency>();
@ -72,6 +80,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
projectContext.ProjectFile, projectContext.ProjectFile,
framework, framework,
preResolvedProjects, preResolvedProjects,
solutionFile,
HoistDependenciesThatAreNotDirectDependencies(projectToResolve, project) HoistDependenciesThatAreNotDirectDependencies(projectToResolve, project)
); );
projects.AddRange(dependencies); projects.AddRange(dependencies);
@ -92,12 +101,13 @@ namespace Microsoft.DotNet.ProjectJsonMigration
Project project, Project project,
NuGetFramework framework, NuGetFramework framework,
IEnumerable<string> preResolvedProjects=null, IEnumerable<string> preResolvedProjects=null,
SlnFile solutionFile = null,
bool hoistedDependencies = false) bool hoistedDependencies = false)
{ {
preResolvedProjects = preResolvedProjects ?? new HashSet<string>(); preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
var possibleProjectDependencies = var possibleProjectDependencies =
FindPossibleProjectDependencies(project.ProjectFilePath, hoistedDependencies); FindPossibleProjectDependencies(solutionFile, project.ProjectFilePath, hoistedDependencies);
var projectDependencies = new List<ProjectDependency>(); var projectDependencies = new List<ProjectDependency>();
@ -174,13 +184,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
private IEnumerable<ProjectDependency> ResolveProjectDependencies( private IEnumerable<ProjectDependency> ResolveProjectDependencies(
ProjectContext projectContext, ProjectContext projectContext,
IEnumerable<string> preResolvedProjects=null) IEnumerable<string> preResolvedProjects=null,
SlnFile slnFile=null)
{ {
preResolvedProjects = preResolvedProjects ?? new HashSet<string>(); preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
var projectExports = projectContext.CreateExporter("_").GetDependencies(); var projectExports = projectContext.CreateExporter("_").GetDependencies();
var possibleProjectDependencies = var possibleProjectDependencies =
FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath); FindPossibleProjectDependencies(slnFile, projectContext.ProjectFile.ProjectFilePath);
var projectDependencies = new List<ProjectDependency>(); var projectDependencies = new List<ProjectDependency>();
foreach (var projectExport in foreach (var projectExport in
@ -221,6 +232,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
} }
private Dictionary<string, ProjectDependency> FindPossibleProjectDependencies( private Dictionary<string, ProjectDependency> FindPossibleProjectDependencies(
SlnFile slnFile,
string projectJsonFilePath, string projectJsonFilePath,
bool hoistedDependencies = false) bool hoistedDependencies = false)
{ {
@ -232,6 +244,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var globalPaths = GetGlobalPaths(projectRootDirectory); var globalPaths = GetGlobalPaths(projectRootDirectory);
projectSearchPaths = projectSearchPaths.Union(globalPaths).ToList(); projectSearchPaths = projectSearchPaths.Union(globalPaths).ToList();
var solutionPaths = GetSolutionPaths(slnFile);
projectSearchPaths = projectSearchPaths.Union(solutionPaths).ToList();
var projects = new Dictionary<string, ProjectDependency>(StringComparer.Ordinal); var projects = new Dictionary<string, ProjectDependency>(StringComparer.Ordinal);
foreach (var project in GetPotentialProjects(projectSearchPaths, hoistedDependencies)) foreach (var project in GetPotentialProjects(projectSearchPaths, hoistedDependencies))
@ -352,6 +367,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return paths; return paths;
} }
internal static List<string> GetSolutionPaths(SlnFile solutionFile)
{
return (solutionFile == null)
? new List<string>()
: new List<string>(solutionFile.Projects.Select(p =>
Path.Combine(solutionFile.BaseDirectory.FullPath, Path.GetDirectoryName(p.FilePath))));
}
private static string ResolveRootDirectory(string projectPath) private static string ResolveRootDirectory(string projectPath)
{ {
var di = new DirectoryInfo(projectPath); var di = new DirectoryInfo(projectPath);

View file

@ -9,6 +9,7 @@ using Microsoft.DotNet.Internal.ProjectModel.Graph;
using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.ProjectJsonMigration.Rules; using Microsoft.DotNet.ProjectJsonMigration.Rules;
using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.Common;
@ -37,8 +38,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration
MigrationRuleInputs rootInputs = ComputeMigrationRuleInputs(rootSettings); MigrationRuleInputs rootInputs = ComputeMigrationRuleInputs(rootSettings);
IEnumerable<ProjectDependency> projectDependencies = null; IEnumerable<ProjectDependency> projectDependencies = null;
var tempMSBuildProjectTemplate = rootSettings.CloneMSBuildProjectTemplate();
try try
{ {
// Verify up front so we can prefer these errors over an unresolved project dependency // Verify up front so we can prefer these errors over an unresolved project dependency
@ -46,7 +45,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration
projectDependencies = ResolveTransitiveClosureProjectDependencies( projectDependencies = ResolveTransitiveClosureProjectDependencies(
rootSettings.ProjectDirectory, rootSettings.ProjectDirectory,
rootSettings.ProjectXProjFilePath); rootSettings.ProjectXProjFilePath,
rootSettings.SolutionFile);
} }
catch (MigrationException e) catch (MigrationException e)
{ {
@ -74,7 +74,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var projectDir = Path.GetDirectoryName(project.ProjectFilePath); var projectDir = Path.GetDirectoryName(project.ProjectFilePath);
var settings = new MigrationSettings(projectDir, var settings = new MigrationSettings(projectDir,
projectDir, projectDir,
tempMSBuildProjectTemplate); rootSettings.MSBuildProjectTemplatePath);
MigrateProject(settings); MigrateProject(settings);
projectMigrationReports.Add(MigrateProject(settings)); projectMigrationReports.Add(MigrateProject(settings));
} }
@ -98,10 +98,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration
} }
} }
private IEnumerable<ProjectDependency> ResolveTransitiveClosureProjectDependencies(string rootProject, string xprojFile) private IEnumerable<ProjectDependency> ResolveTransitiveClosureProjectDependencies(
string rootProject, string xprojFile, SlnFile solutionFile)
{ {
HashSet<ProjectDependency> projectsMap = new HashSet<ProjectDependency>(new ProjectDependencyComparer()); HashSet<ProjectDependency> projectsMap = new HashSet<ProjectDependency>(new ProjectDependencyComparer());
var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile); var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile, solutionFile);
Queue<ProjectDependency> projectsQueue = new Queue<ProjectDependency>(projectDependencies); Queue<ProjectDependency> projectsQueue = new Queue<ProjectDependency>(projectDependencies);
while (projectsQueue.Count() != 0) while (projectsQueue.Count() != 0)

View file

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectJsonMigration.Transforms; using Microsoft.DotNet.ProjectJsonMigration.Transforms;
using Microsoft.DotNet.Internal.ProjectModel; using Microsoft.DotNet.Internal.ProjectModel;
@ -51,6 +52,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
null, null,
project.Dependencies, project.Dependencies,
migrationRuleInputs.ProjectXproj, migrationRuleInputs.ProjectXproj,
migrationSettings.SolutionFile,
itemGroup: noFrameworkPackageReferenceItemGroup); itemGroup: noFrameworkPackageReferenceItemGroup);
MigrationTrace.Instance.WriteLine($"Migrating {targetFrameworks.Count()} target frameworks"); MigrationTrace.Instance.WriteLine($"Migrating {targetFrameworks.Count()} target frameworks");
@ -65,7 +67,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
migrationRuleInputs.OutputMSBuildProject, migrationRuleInputs.OutputMSBuildProject,
targetFramework.FrameworkName, targetFramework.FrameworkName,
targetFramework.Dependencies, targetFramework.Dependencies,
migrationRuleInputs.ProjectXproj); migrationRuleInputs.ProjectXproj,
migrationSettings.SolutionFile);
} }
MigrateTools(project, migrationRuleInputs.OutputMSBuildProject); MigrateTools(project, migrationRuleInputs.OutputMSBuildProject);
@ -213,9 +216,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
NuGetFramework framework, NuGetFramework framework,
IEnumerable<ProjectLibraryDependency> dependencies, IEnumerable<ProjectLibraryDependency> dependencies,
ProjectRootElement xproj, ProjectRootElement xproj,
SlnFile solutionFile,
ProjectItemGroupElement itemGroup=null) ProjectItemGroupElement itemGroup=null)
{ {
var projectDependencies = new HashSet<string>(GetAllProjectReferenceNames(project, framework, xproj)); var projectDependencies = new HashSet<string>(GetAllProjectReferenceNames(project, framework, xproj, solutionFile));
var packageDependencies = dependencies.Where(d => !projectDependencies.Contains(d.Name)).ToList(); var packageDependencies = dependencies.Where(d => !projectDependencies.Contains(d.Name)).ToList();
string condition = framework?.GetMSBuildCondition() ?? ""; string condition = framework?.GetMSBuildCondition() ?? "";
@ -360,7 +364,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
private IEnumerable<string> GetAllProjectReferenceNames( private IEnumerable<string> GetAllProjectReferenceNames(
Project project, Project project,
NuGetFramework framework, NuGetFramework framework,
ProjectRootElement xproj) ProjectRootElement xproj,
SlnFile solutionFile)
{ {
var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(xproj); var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(xproj);
var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes()); var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes());
@ -370,7 +375,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
var projectDependencies = _projectDependencyFinder.ResolveDirectProjectDependenciesForFramework( var projectDependencies = _projectDependencyFinder.ResolveDirectProjectDependenciesForFramework(
project, project,
framework, framework,
preResolvedProjects: migratedXProjDependencyNames); preResolvedProjects: migratedXProjDependencyNames,
solutionFile: solutionFile);
return projectDependencies.Select(p => p.Name).Concat(migratedXProjDependencyNames); return projectDependencies.Select(p => p.Name).Concat(migratedXProjDependencyNames);
} }

View file

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.ProjectJsonMigration.Transforms; using Microsoft.DotNet.ProjectJsonMigration.Transforms;
using Microsoft.DotNet.Internal.ProjectModel; using Microsoft.DotNet.Internal.ProjectModel;
using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.Common;
@ -37,6 +38,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
MigrateProjectJsonProjectDependencies( MigrateProjectJsonProjectDependencies(
migrationRuleInputs.ProjectContexts, migrationRuleInputs.ProjectContexts,
migratedXProjDependencyNames, migratedXProjDependencyNames,
migrationSettings.SolutionFile,
migrationRuleInputs.OutputMSBuildProject); migrationRuleInputs.OutputMSBuildProject);
} }
@ -79,6 +81,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
public void MigrateProjectJsonProjectDependencies( public void MigrateProjectJsonProjectDependencies(
IEnumerable<ProjectContext> projectContexts, IEnumerable<ProjectContext> projectContexts,
HashSet<string> migratedXProjDependencyNames, HashSet<string> migratedXProjDependencyNames,
SlnFile solutionFile,
ProjectRootElement outputMSBuildProject) ProjectRootElement outputMSBuildProject)
{ {
if(projectContexts.Any()) if(projectContexts.Any())
@ -87,6 +90,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
projectContexts.First().ProjectFile, projectContexts.First().ProjectFile,
null, null,
migratedXProjDependencyNames, migratedXProjDependencyNames,
solutionFile,
outputMSBuildProject); outputMSBuildProject);
} }
@ -96,6 +100,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
projectContext.ProjectFile, projectContext.ProjectFile,
projectContext.TargetFramework, projectContext.TargetFramework,
migratedXProjDependencyNames, migratedXProjDependencyNames,
solutionFile,
outputMSBuildProject); outputMSBuildProject);
} }
} }
@ -104,12 +109,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
Project project, Project project,
NuGetFramework framework, NuGetFramework framework,
HashSet<string> migratedXProjDependencyNames, HashSet<string> migratedXProjDependencyNames,
SlnFile solutionFile,
ProjectRootElement outputMSBuildProject) ProjectRootElement outputMSBuildProject)
{ {
var projectDependencies = _projectDependencyFinder.ResolveAllProjectDependenciesForFramework( var projectDependencies = _projectDependencyFinder.ResolveAllProjectDependenciesForFramework(
new ProjectDependency(project.Name, project.ProjectFilePath, false), new ProjectDependency(project.Name, project.ProjectFilePath, false),
framework, framework,
migratedXProjDependencyNames); migratedXProjDependencyNames,
solutionFile);
var projectDependencyTransformResults = var projectDependencyTransformResults =
projectDependencies.Select(p => projectDependencies.Select(p =>

View file

@ -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 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 = public const string CmdProjectArgumentDescription =
@"The path to @"The path to
- a project.json file to migrate. - a project.json file to migrate.
or or
- a global.json file, it will migrate the folders specified in global.json. - 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 or
- a directory to migrate, it will recursively search for project.json files to migrate. - a directory to migrate, it will recursively search for project.json files to migrate.
Defaults to current directory if nothing is specified."; Defaults to current directory if nothing is specified.";

View file

@ -8,6 +8,7 @@ using System.Linq;
using System.Text; using System.Text;
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation; using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectJsonMigration; using Microsoft.DotNet.ProjectJsonMigration;
using Microsoft.DotNet.Internal.ProjectModel; using Microsoft.DotNet.Internal.ProjectModel;
@ -18,6 +19,9 @@ namespace Microsoft.DotNet.Tools.Migrate
{ {
public partial class MigrateCommand public partial class MigrateCommand
{ {
private const string CSharpProjectTypeGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}";
private SlnFile _slnFile;
private readonly DirectoryInfo _workspaceDirectory; private readonly DirectoryInfo _workspaceDirectory;
private readonly DirectoryInfo _backupDirectory; private readonly DirectoryInfo _backupDirectory;
private readonly string _templateFile; private readonly string _templateFile;
@ -70,7 +74,9 @@ namespace Microsoft.DotNet.Tools.Migrate
projectDirectory, projectDirectory,
outputDirectory, outputDirectory,
msBuildTemplatePath, msBuildTemplatePath,
_xprojFilePath); _xprojFilePath,
null,
_slnFile);
var projectMigrationReport = new ProjectMigrator().Migrate(migrationSettings, _skipProjectReferences); var projectMigrationReport = new ProjectMigrator().Migrate(migrationSettings, _skipProjectReferences);
if (migrationReport == null) if (migrationReport == null)
@ -87,11 +93,46 @@ namespace Microsoft.DotNet.Tools.Migrate
temporaryDotnetNewProject.Clean(); temporaryDotnetNewProject.Clean();
UpdateSolutionFile(migrationReport);
MoveProjectJsonArtifactsToBackup(migrationReport); MoveProjectJsonArtifactsToBackup(migrationReport);
return migrationReport.FailedProjectsCount; 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) private void MoveProjectJsonArtifactsToBackup(MigrationReport migrationReport)
{ {
if (_skipBackup) if (_skipBackup)
@ -276,6 +317,16 @@ namespace Microsoft.DotNet.Tools.Migrate
throw new Exception("Unable to find any projects in global.json"); 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)) else if (Directory.Exists(projectArg))
{ {
projects = Directory.EnumerateFiles(projectArg, Project.FileName, SearchOption.AllDirectories); projects = Directory.EnumerateFiles(projectArg, Project.FileName, SearchOption.AllDirectories);
@ -287,7 +338,7 @@ namespace Microsoft.DotNet.Tools.Migrate
} }
else 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) foreach(var project in projects)
@ -336,7 +387,7 @@ namespace Microsoft.DotNet.Tools.Migrate
foreach (var projectDirectory in directory.EnumerateDirectories()) 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)) if (File.Exists(projectFilePath))
{ {
@ -345,5 +396,28 @@ namespace Microsoft.DotNet.Tools.Migrate
} }
} }
} }
private IEnumerable<string> 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;
}
}
}
} }
} }

View file

@ -26,6 +26,7 @@
<ProjectReference Include="../Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj" /> <ProjectReference Include="../Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.csproj" />
<ProjectReference Include="../Microsoft.DotNet.Archive/Microsoft.DotNet.Archive.csproj" /> <ProjectReference Include="../Microsoft.DotNet.Archive/Microsoft.DotNet.Archive.csproj" />
<ProjectReference Include="../Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj" /> <ProjectReference Include="../Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj" />
<ProjectReference Include="../Microsoft.DotNet.Cli.Sln.Internal/Microsoft.DotNet.Cli.Sln.Internal.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -41,6 +41,7 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' "> <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">
<ProjectReference Include="..\dotnet\dotnet.csproj" /> <ProjectReference Include="..\dotnet\dotnet.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Archive\Microsoft.DotNet.Archive.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Archive\Microsoft.DotNet.Archive.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Configurer\Microsoft.DotNet.Configurer.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Configurer\Microsoft.DotNet.Configurer.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" />

View file

@ -27,7 +27,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectDirectoryRelativeFilePaths = EnumerateFilesWithRelativePath(testProjectDirectory); var projectDirectoryRelativeFilePaths = EnumerateFilesWithRelativePath(testProjectDirectory);
var mockProj = ProjectRootElement.Create(); var mockProj = ProjectRootElement.Create();
var testSettings = new MigrationSettings(testProjectDirectory, outputDirectory, mockProj); var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(testProjectDirectory, outputDirectory, mockProj);
var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule());
projectMigrator.Migrate(testSettings); projectMigrator.Migrate(testSettings);
@ -46,7 +46,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
.Path; .Path;
var mockProj = ProjectRootElement.Create(); 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 projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule());
var report = projectMigrator.Migrate(testSettings); var report = projectMigrator.Migrate(testSettings);
@ -67,7 +67,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
.Path; .Path;
var mockProj = ProjectRootElement.Create(); 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 projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule());
var report = projectMigrator.Migrate(testSettings); var report = projectMigrator.Migrate(testSettings);

View file

@ -22,6 +22,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.ProjectJsonMigration\Microsoft.DotNet.ProjectJsonMigration.csproj" /> <ProjectReference Include="..\..\src\Microsoft.DotNet.ProjectJsonMigration\Microsoft.DotNet.ProjectJsonMigration.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" /> <ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />

View file

@ -25,7 +25,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = var projectContext =
ProjectContext.Create(projectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); ProjectContext.Create(projectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
_mockProject = ProjectRootElement.Create(); _mockProject = ProjectRootElement.Create();
var testSettings = new MigrationSettings(projectDirectory, projectDirectory, _mockProject, null); var testSettings = MigrationSettings.CreateMigrationSettingsTestHook(projectDirectory, projectDirectory, _mockProject, null);
var testInputs = new MigrationRuleInputs( var testInputs = new MigrationRuleInputs(
new[] {projectContext}, new[] {projectContext},
_mockProject, _mockProject,

View file

@ -40,7 +40,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var testProjectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithRuntimeOptions").Path; var testProjectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithRuntimeOptions").Path;
var projectContext = ProjectContext.Create(testProjectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); 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(), var testInputs = new MigrationRuleInputs(new[] {projectContext}, templateProj, templateProj.AddItemGroup(),
templateProj.AddPropertyGroup()); templateProj.AddPropertyGroup());
new MigrateBuildOptionsRule().Apply(testSettings, testInputs); new MigrateBuildOptionsRule().Apply(testSettings, testInputs);

View file

@ -27,7 +27,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
var mockProj = ProjectRootElement.Create(); 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(), var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(),
mockProj.AddPropertyGroup()); mockProj.AddPropertyGroup());
new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs);
@ -51,7 +51,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
var mockProj = ProjectRootElement.Create(); 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(), var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(),
mockProj.AddPropertyGroup()); mockProj.AddPropertyGroup());
new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs);
@ -71,7 +71,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
var mockProj = ProjectRootElement.Create(); 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(), var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(),
mockProj.AddPropertyGroup()); mockProj.AddPropertyGroup());
new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs);
@ -97,7 +97,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
var mockProj = ProjectRootElement.Create(); 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()); var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(), mockProj.AddPropertyGroup());
Action action = () => new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); 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 projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.Net451);
var mockProj = ProjectRootElement.Create(); 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(), var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(),
mockProj.AddPropertyGroup()); mockProj.AddPropertyGroup());
new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs);
@ -338,7 +338,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(appDirectory, targetFramework); var projectContext = ProjectContext.Create(appDirectory, targetFramework);
var mockProj = ProjectRootElement.Create(); 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(), var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(),
mockProj.AddPropertyGroup()); mockProj.AddPropertyGroup());
new MigrateProjectDependenciesRule().Apply(testSettings, testInputs); new MigrateProjectDependenciesRule().Apply(testSettings, testInputs);

View file

@ -34,7 +34,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(projectDir, FrameworkConstants.CommonFrameworks.NetCoreApp10); 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); var testInputs = new MigrationRuleInputs(new[] { projectContext }, null, null, null);
new MigrateRuntimeOptionsRule().Apply(testSettings, testInputs); new MigrateRuntimeOptionsRule().Apply(testSettings, testInputs);
@ -54,7 +54,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(projectDir, FrameworkConstants.CommonFrameworks.NetCoreApp10); 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); var testInputs = new MigrationRuleInputs(new[] { projectContext }, null, null, null);
new MigrateRuntimeOptionsRule().Apply(testSettings, testInputs); new MigrateRuntimeOptionsRule().Apply(testSettings, testInputs);

View file

@ -30,7 +30,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContext = ProjectContext.Create(testDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10); var projectContext = ProjectContext.Create(testDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
var mockProj = ProjectRootElement.Create(); var mockProj = ProjectRootElement.Create();
var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj);
var migrationInputs = new MigrationRuleInputs( var migrationInputs = new MigrationRuleInputs(
new[] { projectContext }, new[] { projectContext },
mockProj, mockProj,
@ -54,7 +54,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContexts = ProjectContext.CreateContextForEachFramework(testDirectory); var projectContexts = ProjectContext.CreateContextForEachFramework(testDirectory);
var mockProj = ProjectRootElement.Create(); var mockProj = ProjectRootElement.Create();
var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj);
var migrationInputs = new MigrationRuleInputs( var migrationInputs = new MigrationRuleInputs(
projectContexts, projectContexts,
mockProj, mockProj,
@ -79,7 +79,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var projectContexts = ProjectContext.CreateContextForEachFramework(testDirectory); var projectContexts = ProjectContext.CreateContextForEachFramework(testDirectory);
var mockProj = ProjectRootElement.Create(); var mockProj = ProjectRootElement.Create();
var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj);
var migrationInputs = new MigrationRuleInputs( var migrationInputs = new MigrationRuleInputs(
projectContexts, projectContexts,
mockProj, mockProj,
@ -109,7 +109,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var mockProj = ProjectRootElement.Create(); var mockProj = ProjectRootElement.Create();
// Run BuildOptionsRule // Run BuildOptionsRule
var migrationSettings = new MigrationSettings(testDirectory, testDirectory, mockProj); var migrationSettings = MigrationSettings.CreateMigrationSettingsTestHook(testDirectory, testDirectory, mockProj);
var migrationInputs = new MigrationRuleInputs( var migrationInputs = new MigrationRuleInputs(
projectContexts, projectContexts,
mockProj, mockProj,

View file

@ -28,7 +28,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
ProjectContext projectContext, string testDirectory, ProjectRootElement xproj) ProjectContext projectContext, string testDirectory, ProjectRootElement xproj)
{ {
var project = ProjectRootElement.Create(); 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, var testInputs = new MigrationRuleInputs(new[] {projectContext}, project,
project.AddItemGroup(), project.AddItemGroup(),
project.AddPropertyGroup(), project.AddPropertyGroup(),

View file

@ -449,6 +449,25 @@ namespace Microsoft.DotNet.Migration.Tests
File.ReadAllText(migrationOutputFile).Should().Contain("MIGRATE1018"); 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) private void VerifyAutoInjectedDesktopReferences(string projectDirectory, string projectName, bool shouldBePresent)
{ {
if (projectName != null) if (projectName != null)
@ -637,7 +656,11 @@ namespace Microsoft.DotNet.Migration.Tests
if (projectName != null) 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(); .Should().Pass();
} }
else else
@ -653,7 +676,7 @@ namespace Microsoft.DotNet.Migration.Tests
string configuration="Debug", string configuration="Debug",
string runtime=null) string runtime=null)
{ {
if (projectName != null) if (projectName != null && !Path.HasExtension(projectName))
{ {
projectName = projectName + ".csproj"; projectName = projectName + ".csproj";
} }

View file

@ -19,6 +19,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.ProjectJsonMigration\Microsoft.DotNet.ProjectJsonMigration.csproj" /> <ProjectReference Include="..\..\src\Microsoft.DotNet.ProjectJsonMigration\Microsoft.DotNet.ProjectJsonMigration.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" /> <ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />

View file

@ -18,6 +18,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\dotnet\dotnet.csproj" /> <ProjectReference Include="..\..\src\dotnet\dotnet.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj"> <ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj">
<FromP2P>true</FromP2P> <FromP2P>true</FromP2P>
</ProjectReference> </ProjectReference>

View file

@ -18,6 +18,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\dotnet\dotnet.csproj" /> <ProjectReference Include="..\..\src\dotnet\dotnet.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj"> <ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj">
<FromP2P>true</FromP2P> <FromP2P>true</FromP2P>
</ProjectReference> </ProjectReference>

View file

@ -17,6 +17,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\dotnet\dotnet.csproj" /> <ProjectReference Include="..\..\src\dotnet\dotnet.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj"> <ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj">
<FromP2P>true</FromP2P> <FromP2P>true</FromP2P>

View file

@ -31,6 +31,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" /> <ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
<ProjectReference Include="..\..\src\dotnet\dotnet.csproj" /> <ProjectReference Include="..\..\src\dotnet\dotnet.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" /> <ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj"> <ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj">
<FromP2P>true</FromP2P> <FromP2P>true</FromP2P>