Merge with rel/1.0.0

This commit is contained in:
Faizan Ahmad 2016-10-10 15:29:35 +05:30
commit 23af21d7bb
26 changed files with 367 additions and 180 deletions

View file

@ -17,7 +17,7 @@
<Version>1.0.1</Version> <Version>1.0.1</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NETCore.Sdk"> <PackageReference Include="Microsoft.NETCore.Sdk">
<Version>1.0.0-alpha-20160930-1</Version> <Version>1.0.0-alpha-20161007-1</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>

View file

@ -17,7 +17,7 @@
<Version>1.0.1</Version> <Version>1.0.1</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NETCore.Sdk"> <PackageReference Include="Microsoft.NETCore.Sdk">
<Version>1.0.0-alpha-20160930-1</Version> <Version>1.0.0-alpha-20161007-1</Version>
</PackageReference> </PackageReference>
<PackageReference Include="MSTest.TestFramework"> <PackageReference Include="MSTest.TestFramework">
<Version>1.0.4-preview</Version> <Version>1.0.4-preview</Version>
@ -26,12 +26,8 @@
<Version>1.1.3-preview</Version> <Version>1.1.3-preview</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.TestPlatform.TestHost"> <PackageReference Include="Microsoft.TestPlatform.TestHost">
<Version>15.0.0-preview-20160928-07</Version> <Version>15.0.0-preview-20161005-01</Version>
</PackageReference>
<PackageReference Include="Microsoft.TestPlatform.ObjectModel">
<Version>15.0.0-preview-20160928-07</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -10,7 +10,7 @@
<ItemGroup> <ItemGroup>
<PublishOutputExtensions Include="$(ExeExtension);.dll;.pdb;.deps.json;.runtimeconfig.json" /> <PublishOutputExtensions Include="$(ExeExtension);.dll;.pdb;.deps.json;.runtimeconfig.json" />
<FilesToMove Include="$(BinaryToCorehostifyRelDir)/csc.exe;$(BinaryToCorehostifyRelDir)/MSBuild.exe;" /> <FilesToMove Include="$(BinaryToCorehostifyRelDir)/csc.exe;" />
<BundledTools Include="csc;MSBuild;NuGet.CommandLine.XPlat;dotnet" /> <BundledTools Include="csc;MSBuild;NuGet.CommandLine.XPlat;dotnet" />
<MSBuildImportsContent Include="$(MSBuildImportsDir)/**/*" /> <MSBuildImportsContent Include="$(MSBuildImportsDir)/**/*" />
</ItemGroup> </ItemGroup>
@ -216,12 +216,6 @@
<Copy SourceFiles="@(MSBuildTargetsToCopy)" <Copy SourceFiles="@(MSBuildTargetsToCopy)"
DestinationFiles="@(MSBuildTargetsToCopy->'$(SdkOutputDirectory)/%(RecursiveDir)%(Filename)%(Extension)')" /> DestinationFiles="@(MSBuildTargetsToCopy->'$(SdkOutputDirectory)/%(RecursiveDir)%(Filename)%(Extension)')" />
<!--
MSBuild's nupkg puts Microsoft.Common.props in an "Extensions" folder. Take that folder out of the hierarchy, since
the CLI sets $(MSBuildExtensionsPath) to be the $(SdkOutputDirectory).
-->
<Move SourceFiles="$(SdkOutputDirectory)/Extensions/15.0/Microsoft.Common.props"
DestinationFolder="$(SdkOutputDirectory)/15.0" />
<RemoveDir Directories="$(SdkOutputDirectory)/Extensions" /> <RemoveDir Directories="$(SdkOutputDirectory)/Extensions" />
<ItemGroup> <ItemGroup>
@ -239,15 +233,5 @@
DestinationFiles="@(FilesToCopy->'$(StageSymbolsDirectory)\%(RecursiveDir)%(Filename)%(Extension)')" /> DestinationFiles="@(FilesToCopy->'$(StageSymbolsDirectory)\%(RecursiveDir)%(Filename)%(Extension)')" />
<Delete Files="@(PdbsToClean)" /> <Delete Files="@(PdbsToClean)" />
<!-- workaround for https://github.com/Microsoft/msbuild/issues/872 -->
<Copy SourceFiles="$(MSBuildTargetsDirectory)/MSBuild.exe"
DestinationFiles="$(SdkOutputDirectory)/MSBuild.exe" />
<Copy SourceFiles="$(RepoRoot)/resources/MSBuild.exe.config"
DestinationFiles="$(SdkOutputDirectory)/MSBuild.exe.config" />
<Copy SourceFiles="$(RepoRoot)/resources/MSBuild.exe.config"
DestinationFiles="$(MSBuildTargetsDirectory)/MSBuild.exe.config" />
</Target> </Target>
</Project> </Project>

View file

@ -20,7 +20,7 @@
"System.Runtime.Serialization.Primitives": "4.1.1", "System.Runtime.Serialization.Primitives": "4.1.1",
"System.Xml.XmlSerializer": "4.0.11", "System.Xml.XmlSerializer": "4.0.11",
"WindowsAzure.Storage": "6.2.2-preview", "WindowsAzure.Storage": "6.2.2-preview",
"NuGet.CommandLine.XPlat": "3.6.0-beta.1.msbuild.17", "NuGet.CommandLine.XPlat": "3.6.0-rc-1954",
"Microsoft.Build.Utilities.Core": "0.1.0-preview-00043-160929", "Microsoft.Build.Utilities.Core": "0.1.0-preview-00043-160929",
"Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933" "Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933"
}, },

View file

@ -9,10 +9,10 @@
"target": "project" "target": "project"
}, },
"Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933", "Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933",
"NuGet.Versioning": "3.6.0-beta.1.msbuild.17", "NuGet.Versioning": "3.6.0-rc-1954",
"NuGet.Packaging": "3.6.0-beta.1.msbuild.17", "NuGet.Packaging": "3.6.0-rc-1954",
"NuGet.Frameworks": "3.6.0-beta.1.msbuild.17", "NuGet.Frameworks": "3.6.0-rc-1954",
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17" "NuGet.ProjectModel": "3.6.0-rc-1954"
}, },
"frameworks": { "frameworks": {
"net451": { "net451": {

View file

@ -14,7 +14,7 @@
"Microsoft.DotNet.Files": { "Microsoft.DotNet.Files": {
"target": "project" "target": "project"
}, },
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17" "NuGet.ProjectModel": "3.6.0-rc-1954"
}, },
"frameworks": { "frameworks": {
"net451": { "net451": {

View file

@ -20,7 +20,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
public void Throw() public void Throw()
{ {
throw new MigrationException(GetFormattedErrorMessage()); throw new MigrationException(this, GetFormattedErrorMessage());
} }
public string GetFormattedErrorMessage() public string GetFormattedErrorMessage()

View file

@ -7,6 +7,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{ {
public class MigrationException : Exception public class MigrationException : Exception
{ {
public MigrationException(string message) : base(message) { } public MigrationError Error { get; }
public MigrationException(MigrationError error, string message) : base(message)
{
Error = error;
}
} }
} }

View file

@ -0,0 +1,21 @@
// 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.Collections.Generic;
using Microsoft.Build.Construction;
using System.Linq;
using Microsoft.DotNet.ProjectModel;
using System.IO;
namespace Microsoft.DotNet.ProjectJsonMigration
{
public static class ProjectContextExtensions
{
public static string GetProjectName(this ProjectContext projectContext)
{
// _ here is just an arbitrary configuration value so we can obtain the output name
return Path.GetFileNameWithoutExtension(projectContext.GetOutputPaths("_").CompilationFiles.Assembly);
}
}
}

View file

@ -26,40 +26,47 @@ namespace Microsoft.DotNet.ProjectJsonMigration
_ruleSet = ruleSet; _ruleSet = ruleSet;
} }
public void Migrate(MigrationSettings rootSettings, bool skipProjectReferences = false) public MigrationReport Migrate(MigrationSettings rootSettings, bool skipProjectReferences = false)
{ {
if (rootSettings == null) if (rootSettings == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Exception exc = null;
// Try to read the project dependencies, ignore an unresolved exception for now
MigrationRuleInputs rootInputs = ComputeMigrationRuleInputs(rootSettings);
IEnumerable<ProjectDependency> projectDependencies = null; IEnumerable<ProjectDependency> projectDependencies = null;
var tempMSBuildProjectTemplate = rootSettings.MSBuildProjectTemplate.DeepClone(); var tempMSBuildProjectTemplate = rootSettings.MSBuildProjectTemplate.DeepClone();
try try
{ {
// Verify up front so we can prefer these errors over an unresolved project dependency
VerifyInputs(rootInputs, rootSettings);
projectDependencies = ResolveTransitiveClosureProjectDependencies( projectDependencies = ResolveTransitiveClosureProjectDependencies(
rootSettings.ProjectDirectory, rootSettings.ProjectDirectory,
rootSettings.ProjectXProjFilePath); rootSettings.ProjectXProjFilePath);
} }
catch (Exception e) catch (MigrationException e)
{ {
exc = e; return new MigrationReport(
new List<ProjectMigrationReport>
{
new ProjectMigrationReport(
rootSettings.ProjectDirectory,
rootInputs?.DefaultProjectContext.GetProjectName(),
new List<MigrationError> {e.Error},
null)
});
} }
// Verify up front so we can prefer these errors over an unresolved project dependency var projectMigrationReports = new List<ProjectMigrationReport>();
VerifyInputs(ComputeMigrationRuleInputs(rootSettings), rootSettings); projectMigrationReports.Add(MigrateProject(rootSettings));
if (exc != null)
{
throw exc;
}
MigrateProject(rootSettings);
if (skipProjectReferences) if (skipProjectReferences)
{ {
return; return new MigrationReport(projectMigrationReports);
} }
foreach(var project in projectDependencies) foreach(var project in projectDependencies)
@ -70,7 +77,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration
rootSettings.SdkPackageVersion, rootSettings.SdkPackageVersion,
tempMSBuildProjectTemplate); tempMSBuildProjectTemplate);
MigrateProject(settings); MigrateProject(settings);
projectMigrationReports.Add(MigrateProject(settings));
} }
return new MigrationReport(projectMigrationReports);
} }
private void DeleteProjectJsons(MigrationSettings rootsettings, IEnumerable<ProjectDependency> projectDependencies) private void DeleteProjectJsons(MigrationSettings rootsettings, IEnumerable<ProjectDependency> projectDependencies)
@ -118,22 +128,37 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return projectsMap; return projectsMap;
} }
private void MigrateProject(MigrationSettings migrationSettings) private ProjectMigrationReport MigrateProject(MigrationSettings migrationSettings)
{ {
var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings); var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings);
var projectName = migrationRuleInputs.DefaultProjectContext.GetProjectName();
if (IsMigrated(migrationSettings, migrationRuleInputs)) try
{ {
// TODO : Adding user-visible logging if (IsMigrated(migrationSettings, migrationRuleInputs))
MigrationTrace.Instance.WriteLine($"{nameof(ProjectMigrator)}: Skip migrating {migrationSettings.ProjectDirectory}, it is already migrated."); {
return; MigrationTrace.Instance.WriteLine($"{nameof(ProjectMigrator)}: Skip migrating {migrationSettings.ProjectDirectory}, it is already migrated.");
return new ProjectMigrationReport(migrationSettings.ProjectDirectory, projectName, skipped: true);
}
VerifyInputs(migrationRuleInputs, migrationSettings);
SetupOutputDirectory(migrationSettings.ProjectDirectory, migrationSettings.OutputDirectory);
_ruleSet.Apply(migrationSettings, migrationRuleInputs);
} }
catch (MigrationException exc)
{
var error = new List<MigrationError>
{
exc.Error
};
VerifyInputs(migrationRuleInputs, migrationSettings); return new ProjectMigrationReport(migrationSettings.ProjectDirectory, projectName, error, null);
}
SetupOutputDirectory(migrationSettings.ProjectDirectory, migrationSettings.OutputDirectory);
var outputProject = Path.Combine(migrationSettings.OutputDirectory, projectName + ".csproj");
_ruleSet.Apply(migrationSettings, migrationRuleInputs); return new ProjectMigrationReport(migrationSettings.ProjectDirectory, projectName, outputProject, null);
} }
private MigrationRuleInputs ComputeMigrationRuleInputs(MigrationSettings migrationSettings) private MigrationRuleInputs ComputeMigrationRuleInputs(MigrationSettings migrationSettings)
@ -230,8 +255,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
public bool IsMigrated(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) public bool IsMigrated(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{ {
var outputName = Path.GetFileNameWithoutExtension( var outputName = migrationRuleInputs.DefaultProjectContext.GetProjectName();
migrationRuleInputs.DefaultProjectContext.GetOutputPaths("_").CompilationFiles.Assembly);
var outputProject = Path.Combine(migrationSettings.OutputDirectory, outputName + ".csproj"); var outputProject = Path.Combine(migrationSettings.OutputDirectory, outputName + ".csproj");
return File.Exists(outputProject); return File.Exists(outputProject);

View file

@ -0,0 +1,65 @@
// 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.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.ProjectJsonMigration
{
/// Any changes to this need to be reflected in roslyn-project-system
/// TODO add link
public class MigrationReport
{
public List<ProjectMigrationReport> ProjectMigrationReports { get; }
public int MigratedProjectsCount => ProjectMigrationReports.Count;
public int SucceededProjectsCount => ProjectMigrationReports.Count(p => p.Succeeded);
public int FailedProjectsCount => ProjectMigrationReports.Count(p => p.Failed);
public bool AllSucceeded => ! ProjectMigrationReports.Any(p => p.Failed);
public MigrationReport Merge(MigrationReport otherReport)
{
var allReports = ProjectMigrationReports.Concat(otherReport.ProjectMigrationReports).ToList();
var dedupedReports = DedupeSkippedReports(allReports);
return new MigrationReport(dedupedReports);
}
private List<ProjectMigrationReport> DedupeSkippedReports(List<ProjectMigrationReport> allReports)
{
var reportDict = new Dictionary<string, ProjectMigrationReport>();
foreach (var report in allReports)
{
ProjectMigrationReport existingReport;
if (reportDict.TryGetValue(report.ProjectDirectory, out existingReport))
{
if (existingReport.Skipped)
{
reportDict[report.ProjectDirectory] = report;
}
else if (!report.Skipped)
{
MigrationTrace.Instance.WriteLine("Detected double project migration: {report.ProjectDirectory}");
}
}
else
{
reportDict[report.ProjectDirectory] = report;
}
}
return reportDict.Values.ToList();
}
public MigrationReport(List<ProjectMigrationReport> projectMigrationReports)
{
ProjectMigrationReports = projectMigrationReports;
}
}
}

View file

@ -0,0 +1,45 @@
// 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.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.ProjectJsonMigration
{
public class ProjectMigrationReport
{
public string ProjectDirectory { get; }
public string ProjectName { get; }
public string OutputMSBuildProject { get; }
public List<MigrationError> Errors { get; }
public List<string> Warnings { get; }
public bool Skipped { get; }
public bool Failed => Errors.Any();
public bool Succeeded => !Errors.Any();
public ProjectMigrationReport(string projectDirectory, string projectName, bool skipped)
: this(projectDirectory, projectName, null, null, null, skipped: skipped) { }
public ProjectMigrationReport(string projectDirectory, string projectName, List<MigrationError> errors, List<string> warnings)
: this(projectDirectory, projectName, null, errors, warnings) { }
public ProjectMigrationReport(string projectDirectory, string projectName, string outputMSBuildProject, List<string> warnings)
: this(projectDirectory, projectName, outputMSBuildProject, null, warnings) { }
private ProjectMigrationReport(string projectDirectory, string projectName, string outputMSBuildProject, List<MigrationError> errors, List<string> warnings, bool skipped=false)
{
ProjectDirectory = projectDirectory;
ProjectName = projectName;
OutputMSBuildProject = outputMSBuildProject;
Errors = errors ?? new List<MigrationError>();
Warnings = warnings ?? new List<string>();
Skipped=skipped;
}
}
}

View file

@ -9,7 +9,6 @@ using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectJsonMigration.Transforms; using Microsoft.DotNet.ProjectJsonMigration.Transforms;
using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.Common;
using NuGet.Frameworks; using NuGet.Frameworks;
using NuGet.LibraryModel; using NuGet.LibraryModel;
@ -142,7 +141,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
transform = PackageDependencyTransform(); transform = PackageDependencyTransform();
if (packageDependency.Type == LibraryDependencyType.Build) if (packageDependency.Type == LibraryDependencyType.Build)
{ {
Console.WriteLine("Build type!!!");
transform = transform.WithMetadata("PrivateAssets", "all"); transform = transform.WithMetadata("PrivateAssets", "all");
} }
else if (packageDependency.SuppressParent != LibraryIncludeFlagUtils.DefaultSuppressParent) else if (packageDependency.SuppressParent != LibraryIncludeFlagUtils.DefaultSuppressParent)

View file

@ -10,8 +10,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{ {
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{ {
var outputName = Path.GetFileNameWithoutExtension( var outputName = migrationRuleInputs.DefaultProjectContext.GetProjectName();
migrationRuleInputs.DefaultProjectContext.GetOutputPaths("_").CompilationFiles.Assembly);
var outputProject = Path.Combine(migrationSettings.OutputDirectory, outputName + ".csproj"); var outputProject = Path.Combine(migrationSettings.OutputDirectory, outputName + ".csproj");

View file

@ -8,10 +8,10 @@
"Microsoft.Extensions.DependencyModel": "1.0.1-beta-000933", "Microsoft.Extensions.DependencyModel": "1.0.1-beta-000933",
"Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933", "Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933",
"Newtonsoft.Json": "9.0.1", "Newtonsoft.Json": "9.0.1",
"NuGet.Configuration": "3.6.0-beta.1.msbuild.17", "NuGet.Configuration": "3.6.0-rc-1954",
"NuGet.Packaging": "3.6.0-beta.1.msbuild.17", "NuGet.Packaging": "3.6.0-rc-1954",
"NuGet.RuntimeModel": "3.6.0-beta.1.msbuild.17", "NuGet.RuntimeModel": "3.6.0-rc-1954",
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17", "NuGet.ProjectModel": "3.6.0-rc-1954",
"System.Reflection.Metadata": "1.4.1-beta-24410-02" "System.Reflection.Metadata": "1.4.1-beta-24410-02"
}, },
"frameworks": { "frameworks": {

View file

@ -5,7 +5,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectJsonMigration; using Microsoft.DotNet.ProjectJsonMigration;
using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel;
@ -18,10 +20,19 @@ namespace Microsoft.DotNet.Tools.Migrate
private readonly string _sdkVersion; private readonly string _sdkVersion;
private readonly string _xprojFilePath; private readonly string _xprojFilePath;
private readonly bool _skipProjectReferences; private readonly bool _skipProjectReferences;
private readonly string _reportFile;
private readonly bool _reportFormatJson;
private readonly TemporaryDotnetNewTemplateProject _temporaryDotnetNewProject; private readonly TemporaryDotnetNewTemplateProject _temporaryDotnetNewProject;
public MigrateCommand(string templateFile, string projectArg, string sdkVersion, string xprojFilePath, bool skipProjectReferences) public MigrateCommand(
string templateFile,
string projectArg,
string sdkVersion,
string xprojFilePath,
string reportFile,
bool skipProjectReferences,
bool reportFormatJson)
{ {
_templateFile = templateFile; _templateFile = templateFile;
_projectArg = projectArg ?? Directory.GetCurrentDirectory(); _projectArg = projectArg ?? Directory.GetCurrentDirectory();
@ -29,6 +40,8 @@ namespace Microsoft.DotNet.Tools.Migrate
_xprojFilePath = xprojFilePath; _xprojFilePath = xprojFilePath;
_skipProjectReferences = skipProjectReferences; _skipProjectReferences = skipProjectReferences;
_temporaryDotnetNewProject = new TemporaryDotnetNewTemplateProject(); _temporaryDotnetNewProject = new TemporaryDotnetNewTemplateProject();
_reportFile = reportFile;
_reportFormatJson = reportFormatJson;
} }
public int Execute() public int Execute()
@ -42,16 +55,133 @@ namespace Microsoft.DotNet.Tools.Migrate
EnsureNotNull(sdkVersion, "Null Sdk Version"); EnsureNotNull(sdkVersion, "Null Sdk Version");
MigrationReport migrationReport = null;
foreach (var project in projectsToMigrate) foreach (var project in projectsToMigrate)
{ {
Console.WriteLine($"Migrating project {project}..");
var projectDirectory = Path.GetDirectoryName(project); var projectDirectory = Path.GetDirectoryName(project);
var outputDirectory = projectDirectory; var outputDirectory = projectDirectory;
var migrationSettings = new MigrationSettings(projectDirectory, outputDirectory, sdkVersion, msBuildTemplate, _xprojFilePath); var migrationSettings = new MigrationSettings(projectDirectory, outputDirectory, sdkVersion, msBuildTemplate, _xprojFilePath);
new ProjectMigrator().Migrate(migrationSettings, _skipProjectReferences); var projectMigrationReport = new ProjectMigrator().Migrate(migrationSettings, _skipProjectReferences);
if (migrationReport == null)
{
migrationReport = projectMigrationReport;
}
else
{
migrationReport = migrationReport.Merge(projectMigrationReport);
}
} }
return 0; WriteReport(migrationReport);
return migrationReport.FailedProjectsCount;
}
private void WriteReport(MigrationReport migrationReport)
{
if (!string.IsNullOrEmpty(_reportFile))
{
using (var outputTextWriter = GetReportFileOutputTextWriter())
{
outputTextWriter.Write(GetReportContent(migrationReport));
}
}
WriteReportToStdOut(migrationReport);
}
private void WriteReportToStdOut(MigrationReport migrationReport)
{
StringBuilder sb = new StringBuilder();
foreach (var projectMigrationReport in migrationReport.ProjectMigrationReports)
{
var errorContent = GetProjectReportErrorContent(projectMigrationReport, colored: true);
var successContent = GetProjectReportSuccessContent(projectMigrationReport, colored: true);
if (!string.IsNullOrEmpty(errorContent))
{
Reporter.Error.WriteLine(errorContent);
}
else
{
Reporter.Output.WriteLine(successContent);
}
}
Reporter.Output.WriteLine(GetReportSummary(migrationReport));
}
private string GetReportContent(MigrationReport migrationReport, bool colored = false)
{
if (_reportFormatJson)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(migrationReport);
}
StringBuilder sb = new StringBuilder();
foreach (var projectMigrationReport in migrationReport.ProjectMigrationReports)
{
var errorContent = GetProjectReportErrorContent(projectMigrationReport, colored: colored);
var successContent = GetProjectReportSuccessContent(projectMigrationReport, colored: colored);
if (!string.IsNullOrEmpty(errorContent))
{
sb.AppendLine(errorContent);
}
else
{
sb.AppendLine(successContent);
}
}
sb.AppendLine(GetReportSummary(migrationReport));
return sb.ToString();
}
private string GetReportSummary(MigrationReport migrationReport)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Summary");
sb.AppendLine($"Total Projects: {migrationReport.MigratedProjectsCount}");
sb.AppendLine($"Succeeded Projects: {migrationReport.SucceededProjectsCount}");
sb.AppendLine($"Failed Projects: {migrationReport.FailedProjectsCount}");
return sb.ToString();
}
private string GetProjectReportSuccessContent(ProjectMigrationReport projectMigrationReport, bool colored)
{
Func<string, string> GreenIfColored = (str) => colored ? str.Green() : str;
return GreenIfColored($"Project {projectMigrationReport.ProjectName} migration succeeded ({projectMigrationReport.ProjectDirectory})");
}
private string GetProjectReportErrorContent(ProjectMigrationReport projectMigrationReport, bool colored)
{
StringBuilder sb = new StringBuilder();
Func<string, string> RedIfColored = (str) => colored ? str.Red() : str;
if (projectMigrationReport.Errors.Any())
{
sb.AppendLine(RedIfColored($"Project {projectMigrationReport.ProjectName} migration failed ({projectMigrationReport.ProjectDirectory})"));
foreach (var error in projectMigrationReport.Errors.Select(e => e.GetFormattedErrorMessage()))
{
sb.AppendLine(RedIfColored(error));
}
}
return sb.ToString();
}
private TextWriter GetReportFileOutputTextWriter()
{
return File.CreateText(_reportFile);
} }
private IEnumerable<string> GetProjectsToMigrate(string projectArg) private IEnumerable<string> GetProjectsToMigrate(string projectArg)

View file

@ -40,6 +40,9 @@ namespace Microsoft.DotNet.Tools.Migrate
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 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 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); CommandOption skipProjectReferences = app.Option("-s|--skip-project-references", "Skip migrating project references. By default project references are migrated recursively", CommandOptionType.BoolValue);
CommandOption reportFile = app.Option("-r|--report-file", "Output migration report to a file in addition to the console.", CommandOptionType.SingleValue);
CommandOption structuredReportOutput = app.Option("--format-report-file-json", "Output migration report file as json rather than user messages", CommandOptionType.BoolValue);
app.OnExecute(() => app.OnExecute(() =>
{ {
@ -48,7 +51,9 @@ namespace Microsoft.DotNet.Tools.Migrate
projectArgument.Value, projectArgument.Value,
sdkVersion.Value(), sdkVersion.Value(),
xprojFile.Value(), xprojFile.Value(),
skipProjectReferences.BoolValue.HasValue ? skipProjectReferences.BoolValue.Value : false); reportFile.Value(),
skipProjectReferences.BoolValue.HasValue ? skipProjectReferences.BoolValue.Value : false,
structuredReportOutput.BoolValue.HasValue ? structuredReportOutput.BoolValue.Value : false);
return migrateCommand.Execute(); return migrateCommand.Execute();
}); });

View file

@ -1,80 +0,0 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.DotNet.ProjectJsonMigration;
namespace Microsoft.DotNet.Tools.Migrate
{
/// <summary>
/// Parses select data from a project.json without relying on ProjectModel.
/// Used to parse simple information.
/// </summary>
internal class ProjectJsonParser
{
public string SdkPackageVersion { get; }
public ProjectJsonParser(JObject projectJson)
{
SdkPackageVersion = GetPackageVersion(projectJson, ConstantPackageNames.CSdkPackageName);
}
private string GetPackageVersion(JObject projectJson, string packageName)
{
var sdkPackageNode = SelectJsonNodes(projectJson, property => property.Name == packageName).First();
if (sdkPackageNode.Value.Type == JTokenType.String)
{
return (string)sdkPackageNode.Value;
}
else if (sdkPackageNode.Type == JTokenType.Object)
{
var sdkPackageNodeValue = (JObject)sdkPackageNode.Value;
JToken versionNode;
if (sdkPackageNodeValue.TryGetValue("version", out versionNode))
{
return versionNode.Value<string>();
}
else
{
throw new Exception("Unable to determine sdk version, no version node in default template.");
}
}
else
{
throw new Exception("Unable to determine sdk version, no version information found");
}
}
private IEnumerable<JProperty> SelectJsonNodes(
JToken jsonNode,
Func<JProperty, bool> condition,
List<JProperty> nodeAccumulator = null)
{
nodeAccumulator = nodeAccumulator ?? new List<JProperty>();
if (jsonNode.Type == JTokenType.Object)
{
var eligibleNodes = jsonNode.Children<JProperty>().Where(j => condition(j));
nodeAccumulator.AddRange(eligibleNodes);
foreach (var child in jsonNode.Children<JProperty>())
{
SelectJsonNodes(child.Value, condition, nodeAccumulator: nodeAccumulator);
}
}
else if (jsonNode.Type == JTokenType.Array)
{
foreach (var child in jsonNode.Children())
{
SelectJsonNodes(child, condition, nodeAccumulator: nodeAccumulator);
}
}
return nodeAccumulator;
}
}
}

View file

@ -17,7 +17,7 @@
<Version>1.0.1</Version> <Version>1.0.1</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NETCore.Sdk"> <PackageReference Include="Microsoft.NETCore.Sdk">
<Version>1.0.0-alpha-20160930-1</Version> <Version>1.0.0-alpha-20161007-1</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>

View file

@ -69,7 +69,7 @@
"exclude": "compile" "exclude": "compile"
}, },
"Microsoft.Build": "0.1.0-preview-00043-160929", "Microsoft.Build": "15.1.298-preview5",
"Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933" "Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933"
}, },

View file

@ -19,15 +19,10 @@
"tool_nuget": "1.0.0-preview3-*", "tool_nuget": "1.0.0-preview3-*",
"tool_msbuild": "1.0.0-preview3-*", "tool_msbuild": "1.0.0-preview3-*",
"MSBuild": "0.1.0-preview-00043-160929", "Microsoft.Build.Runtime": "15.1.298-preview5",
"Microsoft.Build.Framework": "0.1.0-preview-00043-160929",
"Microsoft.Build.Tasks.Core": "0.1.0-preview-00043-160929",
"Microsoft.Build.Utilities.Core": "0.1.0-preview-00043-160929",
"Microsoft.Build.Targets": "0.1.0-preview-00043-160929",
"Microsoft.Build": "0.1.0-preview-00043-160929",
"Microsoft.CodeAnalysis.Build.Tasks": "2.0.0-beta6-60922-08", "Microsoft.CodeAnalysis.Build.Tasks": "2.0.0-beta6-60922-08",
"System.Runtime.Serialization.Xml": "4.1.1", "System.Runtime.Serialization.Xml": "4.1.1",
"NuGet.Build.Tasks": "3.6.0-beta.1.msbuild.17", "NuGet.Build.Tasks": "3.6.0-rc-1954",
"Microsoft.TestPlatform.CLI": "15.0.0-preview-20161005-01", "Microsoft.TestPlatform.CLI": "15.0.0-preview-20161005-01",
"Microsoft.TestPlatform.Build": "15.0.0-preview-20161005-01" "Microsoft.TestPlatform.Build": "15.0.0-preview-20161005-01"
}, },

View file

@ -8,12 +8,10 @@
"type": "platform", "type": "platform",
"version": "1.0.1" "version": "1.0.1"
}, },
"MSBuild": "0.1.0-preview-00043-160929", "Microsoft.Build.Runtime": "15.1.298-preview5",
"Microsoft.Build.Targets": "0.1.0-preview-00043-160929",
"Microsoft.Net.Compilers.netcore": "2.0.0-beta6-60922-08", "Microsoft.Net.Compilers.netcore": "2.0.0-beta6-60922-08",
"Microsoft.CodeAnalysis.Build.Tasks": "2.0.0-beta6-60922-08", "Microsoft.CodeAnalysis.Build.Tasks": "2.0.0-beta6-60922-08",
"Microsoft.Cci": "4.0.0-rc3-24128-00", "Microsoft.Cci": "4.0.0-rc3-24128-00",
"Microsoft.NuGet.Build.Tasks": "1.0.0-alpha-000004",
"Microsoft.Composition": "1.0.30" "Microsoft.Composition": "1.0.30"
}, },
"frameworks": { "frameworks": {

View file

@ -8,7 +8,7 @@
"type": "platform", "type": "platform",
"version": "1.0.1" "version": "1.0.1"
}, },
"NuGet.CommandLine.XPlat": "3.6.0-beta.1.msbuild.17" "NuGet.CommandLine.XPlat": "3.6.0-rc-1954"
}, },
"frameworks": { "frameworks": {
"netcoreapp1.0": { "netcoreapp1.0": {

View file

@ -20,10 +20,10 @@
}, },
"System.Diagnostics.TraceSource": "4.0.0", "System.Diagnostics.TraceSource": "4.0.0",
"System.Runtime.Serialization.Primitives": "4.1.1", "System.Runtime.Serialization.Primitives": "4.1.1",
"NuGet.Versioning": "3.6.0-beta.1.msbuild.17", "NuGet.Versioning": "3.6.0-rc-1954",
"NuGet.Packaging": "3.6.0-beta.1.msbuild.17", "NuGet.Packaging": "3.6.0-rc-1954",
"NuGet.Frameworks": "3.6.0-beta.1.msbuild.17", "NuGet.Frameworks": "3.6.0-rc-1954",
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17", "NuGet.ProjectModel": "3.6.0-rc-1954",
"Microsoft.DotNet.ProjectModel": { "Microsoft.DotNet.ProjectModel": {
"target": "project" "target": "project"
}, },

View file

@ -37,7 +37,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
} }
[Fact] [Fact]
public void It_throws_when_migrating_a_deprecated_projectJson() public void It_has_error_when_migrating_a_deprecated_projectJson()
{ {
var testProjectDirectory = var testProjectDirectory =
TestAssetsManager.CreateTestInstance("TestLibraryWithDeprecatedProjectFile", callingMethod: "z") TestAssetsManager.CreateTestInstance("TestLibraryWithDeprecatedProjectFile", callingMethod: "z")
@ -47,16 +47,18 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, "1.0.0", mockProj); var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, "1.0.0", mockProj);
var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule());
Action migrateAction = () => projectMigrator.Migrate(testSettings); var report = projectMigrator.Migrate(testSettings);
migrateAction.ShouldThrow<Exception>().Where( var projectReport = report.ProjectMigrationReports.First();
e => e.Message.Contains("MIGRATE1011::Deprecated Project:")
&& e.Message.Contains("The 'packInclude' option is deprecated. Use 'files' in 'packOptions' instead. (line: 6, file:") var errorMessage = projectReport.Errors.First().GetFormattedErrorMessage();
&& e.Message.Contains("The 'compilationOptions' option is deprecated. Use 'buildOptions' instead. (line: 3, file:")); errorMessage.Should().Contain("MIGRATE1011::Deprecated Project:");
errorMessage.Should().Contain("The 'packInclude' option is deprecated. Use 'files' in 'packOptions' instead. (line: 6, file:");
errorMessage.Should().Contain("The 'compilationOptions' option is deprecated. Use 'buildOptions' instead. (line: 3, file:");
} }
[Fact] [Fact]
public void It_throws_when_migrating_a_non_csharp_app() public void It_has_error_when_migrating_a_non_csharp_app()
{ {
var testProjectDirectory = var testProjectDirectory =
TestAssetsManager.CreateTestInstance("FSharpTestProjects/TestApp", callingMethod: "z") TestAssetsManager.CreateTestInstance("FSharpTestProjects/TestApp", callingMethod: "z")
@ -66,10 +68,11 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, "1.0.0", mockProj); var testSettings = new MigrationSettings(testProjectDirectory, testProjectDirectory, "1.0.0", mockProj);
var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); var projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule());
Action migrateAction = () => projectMigrator.Migrate(testSettings); var report = projectMigrator.Migrate(testSettings);
var projectReport = report.ProjectMigrationReports.First();
migrateAction.ShouldThrow<Exception>().Where( var errorMessage = projectReport.Errors.First().GetFormattedErrorMessage();
e => e.Message.Contains("MIGRATE20013::Non-Csharp App: Cannot migrate project")); errorMessage.Should().Contain("MIGRATE20013::Non-Csharp App: Cannot migrate project");
} }
private IEnumerable<string> EnumerateFilesWithRelativePath(string testProjectDirectory) private IEnumerable<string> EnumerateFilesWithRelativePath(string testProjectDirectory)

View file

@ -22,7 +22,7 @@
}, },
"xunit": "2.2.0-beta3-build3330", "xunit": "2.2.0-beta3-build3330",
"dotnet-test-xunit": "1.0.0-rc2-350904-49", "dotnet-test-xunit": "1.0.0-rc2-350904-49",
"NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17" "NuGet.ProjectModel": "3.6.0-rc-1954"
}, },
"frameworks": { "frameworks": {
"netcoreapp1.0": { "netcoreapp1.0": {