From 28bd507f40cf522353a3bb20d9193ecb321ee8dc Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Thu, 6 Oct 2016 09:35:58 -0700 Subject: [PATCH 1/5] update nuget and sdk to 3.6.0-rc-1954 and 1.0.0-alpha-20161006-3 (#4332) --- .../TestProjects/MSBuildTestApp/MSBuildTestApp.csproj | 2 +- .../TestProjects/VSTestDotNetCoreProject/project.json | 2 +- build_projects/dotnet-cli-build/project.json | 2 +- src/Microsoft.DotNet.Cli.Utils/project.json | 8 ++++---- src/Microsoft.DotNet.Compiler.Common/project.json | 2 +- src/Microsoft.DotNet.ProjectModel/project.json | 8 ++++---- .../dotnet-new/CSharp_MSBuild/$projectName$.csproj | 2 +- src/redist/project.json | 2 +- src/tool_nuget/project.json | 2 +- test/Microsoft.DotNet.Cli.Utils.Tests/project.json | 8 ++++---- test/Microsoft.DotNet.ProjectModel.Tests/project.json | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj b/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj index 6b0d11806..9103295f3 100644 --- a/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj +++ b/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj @@ -17,7 +17,7 @@ 1.0.1 - 1.0.0-alpha-20160930-1 + 1.0.0-alpha-20161006-3 diff --git a/TestAssets/TestProjects/VSTestDotNetCoreProject/project.json b/TestAssets/TestProjects/VSTestDotNetCoreProject/project.json index a576bf82a..ce2590081 100644 --- a/TestAssets/TestProjects/VSTestDotNetCoreProject/project.json +++ b/TestAssets/TestProjects/VSTestDotNetCoreProject/project.json @@ -6,7 +6,7 @@ "frameworks": { "netcoreapp1.0": { "dependencies": { - "Microsoft.NETCore.Sdk": "1.0.0-alpha-20160914-1", + "Microsoft.NETCore.Sdk": "1.0.0-alpha-20161006-3", "Microsoft.NETCore.App": { "version": "1.0.1", "type": "platform" diff --git a/build_projects/dotnet-cli-build/project.json b/build_projects/dotnet-cli-build/project.json index d1fa711bf..41c1c00f7 100644 --- a/build_projects/dotnet-cli-build/project.json +++ b/build_projects/dotnet-cli-build/project.json @@ -20,7 +20,7 @@ "System.Runtime.Serialization.Primitives": "4.1.1", "System.Xml.XmlSerializer": "4.0.11", "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.DotNet.PlatformAbstractions": "1.0.1-beta-000933" }, diff --git a/src/Microsoft.DotNet.Cli.Utils/project.json b/src/Microsoft.DotNet.Cli.Utils/project.json index a80d89dea..e7b773db5 100644 --- a/src/Microsoft.DotNet.Cli.Utils/project.json +++ b/src/Microsoft.DotNet.Cli.Utils/project.json @@ -9,10 +9,10 @@ "target": "project" }, "Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933", - "NuGet.Versioning": "3.6.0-beta.1.msbuild.17", - "NuGet.Packaging": "3.6.0-beta.1.msbuild.17", - "NuGet.Frameworks": "3.6.0-beta.1.msbuild.17", - "NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17" + "NuGet.Versioning": "3.6.0-rc-1954", + "NuGet.Packaging": "3.6.0-rc-1954", + "NuGet.Frameworks": "3.6.0-rc-1954", + "NuGet.ProjectModel": "3.6.0-rc-1954" }, "frameworks": { "net451": { diff --git a/src/Microsoft.DotNet.Compiler.Common/project.json b/src/Microsoft.DotNet.Compiler.Common/project.json index 0d217e27a..7549438b3 100644 --- a/src/Microsoft.DotNet.Compiler.Common/project.json +++ b/src/Microsoft.DotNet.Compiler.Common/project.json @@ -14,7 +14,7 @@ "Microsoft.DotNet.Files": { "target": "project" }, - "NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17" + "NuGet.ProjectModel": "3.6.0-rc-1954" }, "frameworks": { "net451": { diff --git a/src/Microsoft.DotNet.ProjectModel/project.json b/src/Microsoft.DotNet.ProjectModel/project.json index 6dfdc2028..19259e2d1 100644 --- a/src/Microsoft.DotNet.ProjectModel/project.json +++ b/src/Microsoft.DotNet.ProjectModel/project.json @@ -8,10 +8,10 @@ "Microsoft.Extensions.DependencyModel": "1.0.1-beta-000933", "Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933", "Newtonsoft.Json": "9.0.1", - "NuGet.Configuration": "3.6.0-beta.1.msbuild.17", - "NuGet.Packaging": "3.6.0-beta.1.msbuild.17", - "NuGet.RuntimeModel": "3.6.0-beta.1.msbuild.17", - "NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17", + "NuGet.Configuration": "3.6.0-rc-1954", + "NuGet.Packaging": "3.6.0-rc-1954", + "NuGet.RuntimeModel": "3.6.0-rc-1954", + "NuGet.ProjectModel": "3.6.0-rc-1954", "System.Reflection.Metadata": "1.4.1-beta-24410-02" }, "frameworks": { diff --git a/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj b/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj index a528f3029..41144d9bd 100644 --- a/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj +++ b/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj @@ -17,7 +17,7 @@ 1.0.1 - 1.0.0-alpha-20160930-1 + 1.0.0-alpha-20161006-3 diff --git a/src/redist/project.json b/src/redist/project.json index 0f0e6b4bb..3d3800bb7 100644 --- a/src/redist/project.json +++ b/src/redist/project.json @@ -27,7 +27,7 @@ "Microsoft.Build": "0.1.0-preview-00043-160929", "Microsoft.CodeAnalysis.Build.Tasks": "2.0.0-beta6-60922-08", "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-20160915-01" }, "frameworks": { diff --git a/src/tool_nuget/project.json b/src/tool_nuget/project.json index afb81db19..a077120aa 100644 --- a/src/tool_nuget/project.json +++ b/src/tool_nuget/project.json @@ -8,7 +8,7 @@ "type": "platform", "version": "1.0.1" }, - "NuGet.CommandLine.XPlat": "3.6.0-beta.1.msbuild.17" + "NuGet.CommandLine.XPlat": "3.6.0-rc-1954" }, "frameworks": { "netcoreapp1.0": { diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/project.json b/test/Microsoft.DotNet.Cli.Utils.Tests/project.json index 5d3016b5f..dcbb34626 100644 --- a/test/Microsoft.DotNet.Cli.Utils.Tests/project.json +++ b/test/Microsoft.DotNet.Cli.Utils.Tests/project.json @@ -20,10 +20,10 @@ }, "System.Diagnostics.TraceSource": "4.0.0", "System.Runtime.Serialization.Primitives": "4.1.1", - "NuGet.Versioning": "3.6.0-beta.1.msbuild.17", - "NuGet.Packaging": "3.6.0-beta.1.msbuild.17", - "NuGet.Frameworks": "3.6.0-beta.1.msbuild.17", - "NuGet.ProjectModel": "3.6.0-beta.1.msbuild.17", + "NuGet.Versioning": "3.6.0-rc-1954", + "NuGet.Packaging": "3.6.0-rc-1954", + "NuGet.Frameworks": "3.6.0-rc-1954", + "NuGet.ProjectModel": "3.6.0-rc-1954", "Microsoft.DotNet.ProjectModel": { "target": "project" }, diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/project.json b/test/Microsoft.DotNet.ProjectModel.Tests/project.json index b8492a1bf..47b002045 100644 --- a/test/Microsoft.DotNet.ProjectModel.Tests/project.json +++ b/test/Microsoft.DotNet.ProjectModel.Tests/project.json @@ -22,7 +22,7 @@ }, "xunit": "2.2.0-beta3-build3330", "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": { "netcoreapp1.0": { From fbaf9a679e566a2e969f40b78a702c977d1f0e94 Mon Sep 17 00:00:00 2001 From: Bryan Thornbury Date: Tue, 4 Oct 2016 14:59:04 -0700 Subject: [PATCH 2/5] Project Migration Report --- .../MigrationError.cs | 2 +- .../MigrationException.cs | 6 +- .../ProjectContextExtensions.cs | 21 +++ .../ProjectMigrator.cs | 78 ++++++---- .../Report/MigrationReport.cs | 65 +++++++++ .../Report/ProjectMigrationReport.cs | 45 ++++++ .../MigratePackageDependenciesAndToolsRule.cs | 2 - .../Rules/SaveOutputProjectRule.cs | 3 +- .../commands/dotnet-migrate/MigrateCommand.cs | 138 +++++++++++++++++- src/dotnet/commands/dotnet-migrate/Program.cs | 7 +- .../dotnet-migrate/ProjectJsonParser.cs | 80 ---------- .../GivenAProjectMigrator.cs | 23 +-- 12 files changed, 342 insertions(+), 128 deletions(-) create mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/ProjectContextExtensions.cs create mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/Report/MigrationReport.cs create mode 100644 src/Microsoft.DotNet.ProjectJsonMigration/Report/ProjectMigrationReport.cs delete mode 100644 src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs index 9eff1a9a5..c7d819415 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationError.cs @@ -20,7 +20,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration public void Throw() { - throw new MigrationException(GetFormattedErrorMessage()); + throw new MigrationException(this, GetFormattedErrorMessage()); } public string GetFormattedErrorMessage() diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationException.cs b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationException.cs index 1b78a536c..ecef3c3ac 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/MigrationException.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/MigrationException.cs @@ -7,6 +7,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration { public class MigrationException : Exception { - public MigrationException(string message) : base(message) { } + public MigrationError Error { get; } + public MigrationException(MigrationError error, string message) : base(message) + { + Error = error; + } } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectContextExtensions.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectContextExtensions.cs new file mode 100644 index 000000000..aa7d345ae --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectContextExtensions.cs @@ -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); + } + } +} diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs index c075ce1f4..9de79845e 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/ProjectMigrator.cs @@ -26,40 +26,47 @@ namespace Microsoft.DotNet.ProjectJsonMigration _ruleSet = ruleSet; } - public void Migrate(MigrationSettings rootSettings, bool skipProjectReferences = false) + public MigrationReport Migrate(MigrationSettings rootSettings, bool skipProjectReferences = false) { if (rootSettings == null) { throw new ArgumentNullException(); } - Exception exc = null; + + // Try to read the project dependencies, ignore an unresolved exception for now + MigrationRuleInputs rootInputs = ComputeMigrationRuleInputs(rootSettings); IEnumerable projectDependencies = null; var tempMSBuildProjectTemplate = rootSettings.MSBuildProjectTemplate.DeepClone(); try { + // Verify up front so we can prefer these errors over an unresolved project dependency + VerifyInputs(rootInputs, rootSettings); + projectDependencies = ResolveTransitiveClosureProjectDependencies( rootSettings.ProjectDirectory, rootSettings.ProjectXProjFilePath); } - catch (Exception e) + catch (MigrationException e) { - exc = e; + return new MigrationReport( + new List + { + new ProjectMigrationReport( + rootSettings.ProjectDirectory, + rootInputs?.DefaultProjectContext.GetProjectName(), + new List {e.Error}, + null) + }); } - // Verify up front so we can prefer these errors over an unresolved project dependency - VerifyInputs(ComputeMigrationRuleInputs(rootSettings), rootSettings); - if (exc != null) - { - throw exc; - } - - MigrateProject(rootSettings); - + var projectMigrationReports = new List(); + projectMigrationReports.Add(MigrateProject(rootSettings)); + if (skipProjectReferences) { - return; + return new MigrationReport(projectMigrationReports); } foreach(var project in projectDependencies) @@ -70,7 +77,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration rootSettings.SdkPackageVersion, tempMSBuildProjectTemplate); MigrateProject(settings); + projectMigrationReports.Add(MigrateProject(settings)); } + + return new MigrationReport(projectMigrationReports); } private void DeleteProjectJsons(MigrationSettings rootsettings, IEnumerable projectDependencies) @@ -118,22 +128,37 @@ namespace Microsoft.DotNet.ProjectJsonMigration return projectsMap; } - private void MigrateProject(MigrationSettings migrationSettings) + private ProjectMigrationReport MigrateProject(MigrationSettings migrationSettings) { var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings); + var projectName = migrationRuleInputs.DefaultProjectContext.GetProjectName(); - if (IsMigrated(migrationSettings, migrationRuleInputs)) - { - // TODO : Adding user-visible logging - MigrationTrace.Instance.WriteLine($"{nameof(ProjectMigrator)}: Skip migrating {migrationSettings.ProjectDirectory}, it is already migrated."); - return; + try + { + if (IsMigrated(migrationSettings, migrationRuleInputs)) + { + 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 + { + exc.Error + }; - VerifyInputs(migrationRuleInputs, migrationSettings); - - SetupOutputDirectory(migrationSettings.ProjectDirectory, migrationSettings.OutputDirectory); - - _ruleSet.Apply(migrationSettings, migrationRuleInputs); + return new ProjectMigrationReport(migrationSettings.ProjectDirectory, projectName, error, null); + } + + var outputProject = Path.Combine(migrationSettings.OutputDirectory, projectName + ".csproj"); + return new ProjectMigrationReport(migrationSettings.ProjectDirectory, projectName, outputProject, null); } private MigrationRuleInputs ComputeMigrationRuleInputs(MigrationSettings migrationSettings) @@ -230,8 +255,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration public bool IsMigrated(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) { - var outputName = Path.GetFileNameWithoutExtension( - migrationRuleInputs.DefaultProjectContext.GetOutputPaths("_").CompilationFiles.Assembly); + var outputName = migrationRuleInputs.DefaultProjectContext.GetProjectName(); var outputProject = Path.Combine(migrationSettings.OutputDirectory, outputName + ".csproj"); return File.Exists(outputProject); diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Report/MigrationReport.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Report/MigrationReport.cs new file mode 100644 index 000000000..d54d0faf7 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Report/MigrationReport.cs @@ -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 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 DedupeSkippedReports(List allReports) + { + var reportDict = new Dictionary(); + + 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 projectMigrationReports) + { + ProjectMigrationReports = projectMigrationReports; + } + } +} diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Report/ProjectMigrationReport.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Report/ProjectMigrationReport.cs new file mode 100644 index 000000000..b719b6ce7 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Report/ProjectMigrationReport.cs @@ -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 Errors { get; } + + public List 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 errors, List warnings) + : this(projectDirectory, projectName, null, errors, warnings) { } + + public ProjectMigrationReport(string projectDirectory, string projectName, string outputMSBuildProject, List warnings) + : this(projectDirectory, projectName, outputMSBuildProject, null, warnings) { } + + private ProjectMigrationReport(string projectDirectory, string projectName, string outputMSBuildProject, List errors, List warnings, bool skipped=false) + { + ProjectDirectory = projectDirectory; + ProjectName = projectName; + OutputMSBuildProject = outputMSBuildProject; + Errors = errors ?? new List(); + Warnings = warnings ?? new List(); + Skipped=skipped; + } + } +} diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs index 65dac4a93..7249b8696 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/MigratePackageDependenciesAndToolsRule.cs @@ -9,7 +9,6 @@ using Microsoft.Build.Construction; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectJsonMigration.Transforms; using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.Tools.Common; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -142,7 +141,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules transform = PackageDependencyTransform(); if (packageDependency.Type == LibraryDependencyType.Build) { - Console.WriteLine("Build type!!!"); transform = transform.WithMetadata("PrivateAssets", "all"); } else if (packageDependency.SuppressParent != LibraryIncludeFlagUtils.DefaultSuppressParent) diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs index 5781e8082..af471895c 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Rules/SaveOutputProjectRule.cs @@ -10,8 +10,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules { public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) { - var outputName = Path.GetFileNameWithoutExtension( - migrationRuleInputs.DefaultProjectContext.GetOutputPaths("_").CompilationFiles.Assembly); + var outputName = migrationRuleInputs.DefaultProjectContext.GetProjectName(); var outputProject = Path.Combine(migrationSettings.OutputDirectory, outputName + ".csproj"); diff --git a/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs b/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs index 7db6d751e..900cb6567 100644 --- a/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs +++ b/src/dotnet/commands/dotnet-migrate/MigrateCommand.cs @@ -5,7 +5,9 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using Microsoft.Build.Construction; +using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectJsonMigration; using Microsoft.DotNet.ProjectModel; @@ -18,10 +20,19 @@ namespace Microsoft.DotNet.Tools.Migrate private readonly string _sdkVersion; private readonly string _xprojFilePath; private readonly bool _skipProjectReferences; + private readonly string _reportFile; + private readonly bool _reportFormatJson; 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; _projectArg = projectArg ?? Directory.GetCurrentDirectory(); @@ -29,6 +40,8 @@ namespace Microsoft.DotNet.Tools.Migrate _xprojFilePath = xprojFilePath; _skipProjectReferences = skipProjectReferences; _temporaryDotnetNewProject = new TemporaryDotnetNewTemplateProject(); + _reportFile = reportFile; + _reportFormatJson = reportFormatJson; } public int Execute() @@ -42,16 +55,133 @@ namespace Microsoft.DotNet.Tools.Migrate EnsureNotNull(sdkVersion, "Null Sdk Version"); + MigrationReport migrationReport = null; + 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); + 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 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 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 GetProjectsToMigrate(string projectArg) diff --git a/src/dotnet/commands/dotnet-migrate/Program.cs b/src/dotnet/commands/dotnet-migrate/Program.cs index be3d656e6..a60660ab8 100644 --- a/src/dotnet/commands/dotnet-migrate/Program.cs +++ b/src/dotnet/commands/dotnet-migrate/Program.cs @@ -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 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 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(() => { @@ -48,7 +51,9 @@ namespace Microsoft.DotNet.Tools.Migrate projectArgument.Value, sdkVersion.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(); }); diff --git a/src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs b/src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs deleted file mode 100644 index 71f599ba2..000000000 --- a/src/dotnet/commands/dotnet-migrate/ProjectJsonParser.cs +++ /dev/null @@ -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 -{ - /// - /// Parses select data from a project.json without relying on ProjectModel. - /// Used to parse simple information. - /// - 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(); - } - 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 SelectJsonNodes( - JToken jsonNode, - Func condition, - List nodeAccumulator = null) - { - nodeAccumulator = nodeAccumulator ?? new List(); - - if (jsonNode.Type == JTokenType.Object) - { - var eligibleNodes = jsonNode.Children().Where(j => condition(j)); - nodeAccumulator.AddRange(eligibleNodes); - - foreach (var child in jsonNode.Children()) - { - 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; - } - } -} diff --git a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs index a651283aa..5bcbf8273 100644 --- a/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs +++ b/test/Microsoft.DotNet.ProjectJsonMigration.Tests/GivenAProjectMigrator.cs @@ -37,7 +37,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests } [Fact] - public void It_throws_when_migrating_a_deprecated_projectJson() + public void It_has_error_when_migrating_a_deprecated_projectJson() { var testProjectDirectory = 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 projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); - Action migrateAction = () => projectMigrator.Migrate(testSettings); + var report = projectMigrator.Migrate(testSettings); - migrateAction.ShouldThrow().Where( - e => e.Message.Contains("MIGRATE1011::Deprecated Project:") - && e.Message.Contains("The 'packInclude' option is deprecated. Use 'files' in 'packOptions' instead. (line: 6, file:") - && e.Message.Contains("The 'compilationOptions' option is deprecated. Use 'buildOptions' instead. (line: 3, file:")); + var projectReport = report.ProjectMigrationReports.First(); + + var errorMessage = projectReport.Errors.First().GetFormattedErrorMessage(); + 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] - public void It_throws_when_migrating_a_non_csharp_app() + public void It_has_error_when_migrating_a_non_csharp_app() { var testProjectDirectory = 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 projectMigrator = new ProjectMigrator(new FakeEmptyMigrationRule()); - Action migrateAction = () => projectMigrator.Migrate(testSettings); + var report = projectMigrator.Migrate(testSettings); + var projectReport = report.ProjectMigrationReports.First(); - migrateAction.ShouldThrow().Where( - e => e.Message.Contains("MIGRATE20013::Non-Csharp App: Cannot migrate project")); + var errorMessage = projectReport.Errors.First().GetFormattedErrorMessage(); + errorMessage.Should().Contain("MIGRATE20013::Non-Csharp App: Cannot migrate project"); } private IEnumerable EnumerateFilesWithRelativePath(string testProjectDirectory) From 6242db9b142c34fa256e24d8f643028f4374dfab Mon Sep 17 00:00:00 2001 From: Livar Cunha Date: Fri, 30 Sep 2016 20:26:07 -0700 Subject: [PATCH 3/5] Moving msbuild dependencies to msbuild 15. --- build/Microsoft.DotNet.Cli.Compile.targets | 18 +----------------- src/dotnet/project.json | 2 +- src/redist/project.json | 7 +------ src/tool_msbuild/project.json | 4 +--- 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/build/Microsoft.DotNet.Cli.Compile.targets b/build/Microsoft.DotNet.Cli.Compile.targets index 6433c2687..037253813 100644 --- a/build/Microsoft.DotNet.Cli.Compile.targets +++ b/build/Microsoft.DotNet.Cli.Compile.targets @@ -10,7 +10,7 @@ - + @@ -216,12 +216,6 @@ - - @@ -239,15 +233,5 @@ DestinationFiles="@(FilesToCopy->'$(StageSymbolsDirectory)\%(RecursiveDir)%(Filename)%(Extension)')" /> - - - - - - - \ No newline at end of file diff --git a/src/dotnet/project.json b/src/dotnet/project.json index 94106b469..e2064f277 100644 --- a/src/dotnet/project.json +++ b/src/dotnet/project.json @@ -69,7 +69,7 @@ "exclude": "compile" }, - "Microsoft.Build": "0.1.0-preview-00043-160929", + "Microsoft.Build": "15.1.298-preview5", "Microsoft.DotNet.PlatformAbstractions": "1.0.1-beta-000933" }, diff --git a/src/redist/project.json b/src/redist/project.json index 3d3800bb7..721eb5544 100644 --- a/src/redist/project.json +++ b/src/redist/project.json @@ -19,12 +19,7 @@ "tool_nuget": "1.0.0-preview3-*", "tool_msbuild": "1.0.0-preview3-*", - "MSBuild": "0.1.0-preview-00043-160929", - "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.Build.Runtime": "15.1.298-preview5", "Microsoft.CodeAnalysis.Build.Tasks": "2.0.0-beta6-60922-08", "System.Runtime.Serialization.Xml": "4.1.1", "NuGet.Build.Tasks": "3.6.0-rc-1954", diff --git a/src/tool_msbuild/project.json b/src/tool_msbuild/project.json index f59dbe70f..7d9b432db 100644 --- a/src/tool_msbuild/project.json +++ b/src/tool_msbuild/project.json @@ -8,12 +8,10 @@ "type": "platform", "version": "1.0.1" }, - "MSBuild": "0.1.0-preview-00043-160929", - "Microsoft.Build.Targets": "0.1.0-preview-00043-160929", + "Microsoft.Build.Runtime": "15.1.298-preview5", "Microsoft.Net.Compilers.netcore": "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.NuGet.Build.Tasks": "1.0.0-alpha-000004", "Microsoft.Composition": "1.0.30" }, "frameworks": { From 167470b1c99b1235aba11de0868166828615fc71 Mon Sep 17 00:00:00 2001 From: Livar Cunha Date: Thu, 6 Oct 2016 17:05:55 -0700 Subject: [PATCH 4/5] Updating the SDK version, which we need to pick up the NuGetTargetMoniker fix. --- .../MSBuildTestApp/MSBuildTestApp.csproj | 2 +- .../VSTestDotNetCoreProject.csproj | 20 +++++++++++++++--- .../VSTestDotNetCoreProject/project.json | 21 ------------------- .../CSharp_MSBuild/$projectName$.csproj | 2 +- test/dotnet-vstest.Tests/VSTestTests.cs | 6 ++++++ 5 files changed, 25 insertions(+), 26 deletions(-) delete mode 100644 TestAssets/TestProjects/VSTestDotNetCoreProject/project.json diff --git a/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj b/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj index 9103295f3..75d5c89f0 100644 --- a/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj +++ b/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj @@ -17,7 +17,7 @@ 1.0.1 - 1.0.0-alpha-20161006-3 + 1.0.0-alpha-20161007-1 diff --git a/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj b/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj index f4fa033eb..22c3f3a0e 100644 --- a/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj +++ b/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj @@ -4,9 +4,8 @@ Library - .NETCoreApp - v1.0 - bin\$(Configuration)\netcoreapp1.0 + netcoreapp1.0 + bin\$(Configuration) @@ -14,6 +13,21 @@ + + + 1.0.1 + + + 1.0.0-alpha-20161007-1 + + + 1.0.3-preview + + + 1.0.4-preview + + + diff --git a/TestAssets/TestProjects/VSTestDotNetCoreProject/project.json b/TestAssets/TestProjects/VSTestDotNetCoreProject/project.json deleted file mode 100644 index ce2590081..000000000 --- a/TestAssets/TestProjects/VSTestDotNetCoreProject/project.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "dependencies": { - "MSTest.TestAdapter": "1.0.3-preview", - "MSTest.TestFramework": "1.0.1-preview" - }, - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.Sdk": "1.0.0-alpha-20161006-3", - "Microsoft.NETCore.App": { - "version": "1.0.1", - "type": "platform" - } - }, - "imports": [ - "dnxcore50", - "portable-net45+win8" - ] - } - } -} diff --git a/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj b/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj index 41144d9bd..aadb3946a 100644 --- a/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj +++ b/src/dotnet/commands/dotnet-new/CSharp_MSBuild/$projectName$.csproj @@ -17,7 +17,7 @@ 1.0.1 - 1.0.0-alpha-20161006-3 + 1.0.0-alpha-20161007-1 diff --git a/test/dotnet-vstest.Tests/VSTestTests.cs b/test/dotnet-vstest.Tests/VSTestTests.cs index 4a3a9b61a..09fd80827 100644 --- a/test/dotnet-vstest.Tests/VSTestTests.cs +++ b/test/dotnet-vstest.Tests/VSTestTests.cs @@ -22,6 +22,12 @@ namespace Microsoft.DotNet.Cli.VSTest.Tests string testProjectDirectory = testInstance.TestRoot; + new Restore3Command() + .WithWorkingDirectory(testProjectDirectory) + .Execute() + .Should() + .Pass(); + // Build project DotNetCoreTestProject new Build3Command() .WithWorkingDirectory(testProjectDirectory) From 06aa54d16c093963395386b6e5a20ebafdc80045 Mon Sep 17 00:00:00 2001 From: Livar Cunha Date: Thu, 6 Oct 2016 19:29:20 -0700 Subject: [PATCH 5/5] Fixing a test. --- .../VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj b/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj index 22c3f3a0e..e3dba2cf4 100644 --- a/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj +++ b/TestAssets/TestProjects/VSTestDotNetCoreProject/VSTestDotNetCoreProject.csproj @@ -33,7 +33,7 @@ - - + + \ No newline at end of file