Merge pull request #4254 from dotnet/sridhar-ms/migrate-directory

Add support to migrate a directory.
This commit is contained in:
Sridhar Periyasamy 2016-09-29 10:13:55 -07:00 committed by GitHub
commit 98231a6628
9 changed files with 156 additions and 29 deletions

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 ProjectE
{
public static string GetMessage()
{
return "This string came from ProjectF";
}
}
}

View file

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

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 ProjectE
{
public static string GetMessage()
{
return "This string came from ProjectG";
}
}
}

View file

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

View file

@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli;
@ -13,17 +14,17 @@ namespace Microsoft.DotNet.Tools.Migrate
public partial class MigrateCommand
{
private readonly string _templateFile;
private readonly string _projectJson;
private readonly string _projectArg;
private readonly string _sdkVersion;
private readonly string _xprojFilePath;
private readonly bool _skipProjectReferences;
private readonly TemporaryDotnetNewTemplateProject _temporaryDotnetNewProject;
public MigrateCommand(string templateFile, string projectJson, string sdkVersion, string xprojFilePath, bool skipProjectReferences)
public MigrateCommand(string templateFile, string projectArg, string sdkVersion, string xprojFilePath, bool skipProjectReferences)
{
_templateFile = templateFile;
_projectJson = projectJson;
_projectArg = projectArg ?? Directory.GetCurrentDirectory();
_sdkVersion = sdkVersion;
_xprojFilePath = xprojFilePath;
_skipProjectReferences = skipProjectReferences;
@ -32,24 +33,47 @@ namespace Microsoft.DotNet.Tools.Migrate
public int Execute()
{
var project = GetProjectJsonPath(_projectJson) ?? GetProjectJsonPath(Directory.GetCurrentDirectory());
EnsureNotNull(project, "Unable to find project.json");
var projectDirectory = Path.GetDirectoryName(project);
var projectsToMigrate = GetProjectsToMigrate(_projectArg);
var msBuildTemplate = _templateFile != null ?
ProjectRootElement.TryOpen(_templateFile) : _temporaryDotnetNewProject.MSBuildProject;
var outputDirectory = projectDirectory;
var sdkVersion = _sdkVersion ?? new ProjectJsonParser(_temporaryDotnetNewProject.ProjectJson).SdkPackageVersion;
EnsureNotNull(sdkVersion, "Null Sdk Version");
var migrationSettings = new MigrationSettings(projectDirectory, outputDirectory, sdkVersion, msBuildTemplate, _xprojFilePath);
new ProjectMigrator().Migrate(migrationSettings, _skipProjectReferences);
foreach (var project in projectsToMigrate)
{
Console.WriteLine($"Migrating project {project}..");
var projectDirectory = Path.GetDirectoryName(project);
var outputDirectory = projectDirectory;
var migrationSettings = new MigrationSettings(projectDirectory, outputDirectory, sdkVersion, msBuildTemplate, _xprojFilePath);
new ProjectMigrator().Migrate(migrationSettings, _skipProjectReferences);
}
return 0;
}
private IEnumerable<string> GetProjectsToMigrate(string projectArg)
{
if (projectArg.EndsWith(Project.FileName))
{
yield return GetProjectJsonPath(projectArg);
}
else if (Directory.Exists(projectArg))
{
var projects = Directory.EnumerateFiles(projectArg, Project.FileName, SearchOption.AllDirectories);
foreach(var project in projects)
{
yield return GetProjectJsonPath(project);
}
}
else
{
throw new Exception($"Invalid project argument - '{projectArg}' is not a project.json file and a directory named '{projectArg}' doesn't exist.");
}
}
private void EnsureNotNull(string variable, string message)
{
if (variable == null)
@ -60,11 +84,6 @@ namespace Microsoft.DotNet.Tools.Migrate
private string GetProjectJsonPath(string projectJson)
{
if (projectJson == null)
{
return null;
}
projectJson = ProjectPathHelper.NormalizeProjectFilePath(projectJson);
if (File.Exists(projectJson))

View file

@ -20,8 +20,12 @@ namespace Microsoft.DotNet.Tools.Migrate
app.HandleResponseFiles = true;
app.HelpOption("-h|--help");
CommandArgument projectArgument = app.Argument("<PROJECT_JSON/PROJECT_DIR>",
"The path to project.json file or a directory to migrate." +
" If a directory is specified, then it will recursively search for project.json files to migrate." +
" Defaults to current directory if nothing is specified.");
CommandOption template = app.Option("-t|--template-file", "Base MSBuild template to use for migrated app. The default is the project included in dotnet new -t msbuild", CommandOptionType.SingleValue);
CommandOption project = app.Option("-p|--project", "The path to the project to run (defaults to the current directory). Can be a path to a project.json or a project directory", CommandOptionType.SingleValue);
CommandOption sdkVersion = app.Option("-v|--sdk-package-version", "The version of the sdk package that will be referenced in the migrated app. The default is the version of the sdk in dotnet new -t msbuild", CommandOptionType.SingleValue);
CommandOption xprojFile = app.Option("-x|--xproj-file", "The path to the xproj file to use. Required when there is more than one xproj in a project directory.", CommandOptionType.SingleValue);
CommandOption skipProjectReferences = app.Option("-s|--skip-project-references", "Skip migrating project references. By default project references are migrated recursively", CommandOptionType.BoolValue);
@ -30,7 +34,7 @@ namespace Microsoft.DotNet.Tools.Migrate
{
MigrateCommand migrateCommand = new MigrateCommand(
template.Value(),
project.Value(),
projectArgument.Value,
sdkVersion.Value(),
xprojFile.Value(),
skipProjectReferences.BoolValue.HasValue ? skipProjectReferences.BoolValue.Value : false);

View file

@ -129,12 +129,7 @@ namespace Microsoft.DotNet.Migration.Tests
MigrateProject(Path.Combine(projectDirectory, projectName));
string[] migratedProjects = expectedProjects.Split(new char[] { ',' });
foreach(var migratedProject in migratedProjects)
{
var dirInfo = new DirectoryInfo(Path.Combine(projectDirectory, migratedProject));
var csproj = $"{migratedProject}.csproj";
dirInfo.Should().HaveFile(csproj);
}
VerifyMigration(migratedProjects, projectDirectory);
}
[Theory]
@ -150,13 +145,45 @@ namespace Microsoft.DotNet.Migration.Tests
FixUpProjectJsons(projectDirectory);
MigrateCommand.Run(new [] { "-p", Path.Combine(projectDirectory, projectName), "--skip-project-references" }).Should().Be(0);
MigrateCommand.Run(new [] { Path.Combine(projectDirectory, projectName), "--skip-project-references" }).Should().Be(0);
var migratedProjects = Directory.EnumerateFiles(projectDirectory, "*.csproj", SearchOption.AllDirectories);
migratedProjects.Count().Should().Be(1, "Only the root project must be migrated");
VerifyMigration(Enumerable.Repeat(projectName, 1), projectDirectory);
}
var migratedProject = Path.GetFileName(migratedProjects.First());
migratedProject.Should().Be($"{projectName}.csproj");
[Theory]
[InlineData(true)]
[InlineData(false)]
public void It_migrates_all_projects_in_given_directory(bool skipRefs)
{
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", callingMethod: $"MigrateDirectory.SkipRefs.{skipRefs}").Path;
FixUpProjectJsons(projectDirectory);
if (skipRefs)
{
MigrateCommand.Run(new [] { projectDirectory, "--skip-project-references" }).Should().Be(0);
}
else
{
MigrateCommand.Run(new [] { projectDirectory }).Should().Be(0);
}
string[] migratedProjects = new string[] { "ProjectA", "ProjectB", "ProjectC", "ProjectD", "ProjectE", "ProjectF", "ProjectG" };
VerifyMigration(migratedProjects, projectDirectory);
}
[Fact]
public void It_migrates_given_project_json()
{
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph").Path;
FixUpProjectJsons(projectDirectory);
var project = Path.Combine(projectDirectory, "ProjectA", "project.json");
MigrateCommand.Run(new [] { project }).Should().Be(0);
string[] migratedProjects = new string[] { "ProjectA", "ProjectB", "ProjectC", "ProjectD", "ProjectE" };
VerifyMigration(migratedProjects, projectDirectory);
}
private void FixUpProjectJsons(string projectDirectory)
@ -170,6 +197,13 @@ namespace Microsoft.DotNet.Migration.Tests
}
}
private void VerifyMigration(IEnumerable<string> expectedProjects, string rootDir)
{
var migratedProjects = Directory.EnumerateFiles(rootDir, "*.csproj", SearchOption.AllDirectories)
.Select(s => Path.GetFileNameWithoutExtension(s));
migratedProjects.Should().BeEquivalentTo(expectedProjects);
}
private MigratedBuildComparisonData GetDotnetNewComparisonData(string projectDirectory, string dotnetNewType)
{
DotnetNew(projectDirectory, dotnetNewType);
@ -241,7 +275,7 @@ namespace Microsoft.DotNet.Migration.Tests
private void MigrateProject(string projectDirectory)
{
var result =
MigrateCommand.Run(new [] { "-p", projectDirectory });
MigrateCommand.Run(new [] { projectDirectory });
result.Should().Be(0);
}