Handle "runtimes" section (#4503)
* Migrate "runtimes" section as a RuntimeIdentifiers property in the resulting csproj file. Also do not call restore3 from publish3 anymore. * Fix up the publish3 tests to call restore3 first and the csproj files to have RuntimeIdentifiers
This commit is contained in:
parent
4aa1c1bfb4
commit
68afda8e4d
10 changed files with 183 additions and 37 deletions
|
@ -4,6 +4,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp1.0</TargetFramework>
|
<TargetFramework>netcoreapp1.0</TargetFramework>
|
||||||
|
<RuntimeIdentifiers>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</RuntimeIdentifiers>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
new MigrateJsonPropertiesRule(),
|
new MigrateJsonPropertiesRule(),
|
||||||
new MigratePackOptionsRule(),
|
new MigratePackOptionsRule(),
|
||||||
new MigrateRuntimeOptionsRule(),
|
new MigrateRuntimeOptionsRule(),
|
||||||
|
new MigrateRuntimesRule(),
|
||||||
new MigratePublishOptionsRule(),
|
new MigratePublishOptionsRule(),
|
||||||
new MigrateProjectDependenciesRule(),
|
new MigrateProjectDependenciesRule(),
|
||||||
new MigratePackageDependenciesAndToolsRule(),
|
new MigratePackageDependenciesAndToolsRule(),
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
// 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.DotNet.ProjectJsonMigration.Transforms;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
|
{
|
||||||
|
public class MigrateRuntimesRule : IMigrationRule
|
||||||
|
{
|
||||||
|
AddPropertyTransform<IList<string>> RuntimeIdentifiersTransform =>
|
||||||
|
new AddPropertyTransform<IList<string>>(
|
||||||
|
"RuntimeIdentifiers",
|
||||||
|
l => String.Join(";", l),
|
||||||
|
l => l.Count > 0);
|
||||||
|
|
||||||
|
private readonly ITransformApplicator _transformApplicator;
|
||||||
|
|
||||||
|
public MigrateRuntimesRule(ITransformApplicator transformApplicator = null)
|
||||||
|
{
|
||||||
|
_transformApplicator = transformApplicator ?? new TransformApplicator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
|
||||||
|
{
|
||||||
|
var propertyGroup = migrationRuleInputs.CommonPropertyGroup;
|
||||||
|
|
||||||
|
_transformApplicator.Execute(
|
||||||
|
RuntimeIdentifiersTransform.Transform(migrationRuleInputs.DefaultProjectContext.ProjectFile.Runtimes),
|
||||||
|
propertyGroup,
|
||||||
|
mergeExisting: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -71,6 +71,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
public RuntimeOptions RuntimeOptions { get; set; }
|
public RuntimeOptions RuntimeOptions { get; set; }
|
||||||
|
|
||||||
|
public IList<string> Runtimes { get; set; }
|
||||||
|
|
||||||
public IDictionary<string, string> Commands { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
public IDictionary<string, string> Commands { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public IDictionary<string, IEnumerable<string>> Scripts { get; } = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase);
|
public IDictionary<string, IEnumerable<string>> Scripts { get; } = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
|
@ -159,6 +159,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
project.Dependencies = new List<ProjectLibraryDependency>();
|
project.Dependencies = new List<ProjectLibraryDependency>();
|
||||||
project.Tools = new List<ProjectLibraryDependency>();
|
project.Tools = new List<ProjectLibraryDependency>();
|
||||||
|
project.Runtimes = new List<string>();
|
||||||
|
|
||||||
// Project files
|
// Project files
|
||||||
project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath);
|
project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath);
|
||||||
|
@ -224,6 +225,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
"tools",
|
"tools",
|
||||||
isGacOrFrameworkReference: false);
|
isGacOrFrameworkReference: false);
|
||||||
|
|
||||||
|
PopulateRuntimes(project.Runtimes, rawProject);
|
||||||
|
|
||||||
JToken runtimeOptionsToken;
|
JToken runtimeOptionsToken;
|
||||||
if (rawProject.TryGetValue("runtimeOptions", out runtimeOptionsToken))
|
if (rawProject.TryGetValue("runtimeOptions", out runtimeOptionsToken))
|
||||||
{
|
{
|
||||||
|
@ -370,6 +373,21 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PopulateRuntimes(IList<string> results, JObject settings)
|
||||||
|
{
|
||||||
|
var runtimes = settings.Value<JToken>("runtimes") as JObject;
|
||||||
|
if (runtimes != null)
|
||||||
|
{
|
||||||
|
foreach (var runtime in runtimes)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(runtime.Key))
|
||||||
|
{
|
||||||
|
results.Add(runtime.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject)
|
private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject)
|
||||||
{
|
{
|
||||||
// Get the shared compilationOptions
|
// Get the shared compilationOptions
|
||||||
|
|
|
@ -25,12 +25,6 @@ namespace Microsoft.DotNet.Tools.Publish3
|
||||||
|
|
||||||
public int Execute()
|
public int Execute()
|
||||||
{
|
{
|
||||||
int restoreResult = EnsureRestored();
|
|
||||||
if (restoreResult != 0)
|
|
||||||
{
|
|
||||||
throw new GracefulException("Restore failed. Please fix the errors and try publishing again.");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> msbuildArgs = new List<string>();
|
List<string> msbuildArgs = new List<string>();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(ProjectPath))
|
if (!string.IsNullOrEmpty(ProjectPath))
|
||||||
|
@ -70,19 +64,5 @@ namespace Microsoft.DotNet.Tools.Publish3
|
||||||
return new MSBuildForwardingApp(msbuildArgs).Execute();
|
return new MSBuildForwardingApp(msbuildArgs).Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ensures that the project has been restored for the specified runtime.
|
|
||||||
/// </summary>
|
|
||||||
private int EnsureRestored()
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Runtime))
|
|
||||||
{
|
|
||||||
result = Restore3Command.Run(new[] { $"/p:RuntimeIdentifiers={Runtime}" });
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
using Microsoft.Build.Construction;
|
||||||
|
using Microsoft.DotNet.ProjectJsonMigration;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Microsoft.DotNet.ProjectJsonMigration.Rules;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
||||||
|
{
|
||||||
|
public class GivenThatIWantToMigrateRuntimes : TestBase
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void It_migrates_runtimes()
|
||||||
|
{
|
||||||
|
var projectJson = @"
|
||||||
|
{
|
||||||
|
""runtimes"": {
|
||||||
|
""win7-x64"": { },
|
||||||
|
""win7-x86"": { },
|
||||||
|
""osx.10.10-x64"": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
var testDirectory = Temp.CreateDirectory().Path;
|
||||||
|
var migratedProj = TemporaryProjectFileRuleRunner.RunRules(new IMigrationRule[]
|
||||||
|
{
|
||||||
|
new MigrateRuntimesRule()
|
||||||
|
}, projectJson, testDirectory);
|
||||||
|
|
||||||
|
migratedProj.Properties.Count(p => p.Name == "RuntimeIdentifiers").Should().Be(1);
|
||||||
|
migratedProj.Properties.First(p => p.Name == "RuntimeIdentifiers").Value
|
||||||
|
.Should().Be("win7-x64;win7-x86;osx.10.10-x64");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_has_an_empty_runtime_node_to_migrate()
|
||||||
|
{
|
||||||
|
var projectJson = @"
|
||||||
|
{
|
||||||
|
""runtimes"": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
var testDirectory = Temp.CreateDirectory().Path;
|
||||||
|
var migratedProj = TemporaryProjectFileRuleRunner.RunRules(new IMigrationRule[]
|
||||||
|
{
|
||||||
|
new MigrateRuntimesRule()
|
||||||
|
}, projectJson, testDirectory);
|
||||||
|
|
||||||
|
migratedProj.Properties.Count(p => p.Name == "RuntimeIdentifiers").Should().Be(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_has_no_runtimes_to_migrate()
|
||||||
|
{
|
||||||
|
var projectJson = @"
|
||||||
|
{
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
var testDirectory = Temp.CreateDirectory().Path;
|
||||||
|
var migratedProj = TemporaryProjectFileRuleRunner.RunRules(new IMigrationRule[]
|
||||||
|
{
|
||||||
|
new MigrateRuntimesRule()
|
||||||
|
}, projectJson, testDirectory);
|
||||||
|
|
||||||
|
migratedProj.Properties.Count(p => p.Name == "RuntimeIdentifiers").Should().Be(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,13 +29,13 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
||||||
|
|
||||||
public override CommandResult Execute(string args = "")
|
public override CommandResult Execute(string args = "")
|
||||||
{
|
{
|
||||||
args = $"publish3 {args} {BuildArgs()}";
|
args = $"publish3 {BuildArgs()} {args} ";
|
||||||
return base.Execute(args);
|
return base.Execute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override CommandResult ExecuteWithCapturedOutput(string args = "")
|
public override CommandResult ExecuteWithCapturedOutput(string args = "")
|
||||||
{
|
{
|
||||||
args = $"publish3 {args} {BuildArgs()}";
|
args = $"publish3 {BuildArgs()} {args}";
|
||||||
return base.ExecuteWithCapturedOutput(args);
|
return base.ExecuteWithCapturedOutput(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ using System.IO;
|
||||||
using Microsoft.DotNet.Tools.Migrate;
|
using Microsoft.DotNet.Tools.Migrate;
|
||||||
using Build3Command = Microsoft.DotNet.Tools.Test.Utilities.Build3Command;
|
using Build3Command = Microsoft.DotNet.Tools.Test.Utilities.Build3Command;
|
||||||
using BuildCommand = Microsoft.DotNet.Tools.Test.Utilities.BuildCommand;
|
using BuildCommand = Microsoft.DotNet.Tools.Test.Utilities.BuildCommand;
|
||||||
|
using Publish3Command = Microsoft.DotNet.Tools.Test.Utilities.Publish3Command;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Migration.Tests
|
namespace Microsoft.DotNet.Migration.Tests
|
||||||
|
@ -346,6 +346,19 @@ namespace Microsoft.DotNet.Migration.Tests
|
||||||
result.StdErr.Should().Contain("Migration failed.");
|
result.StdErr.Should().Contain("Migration failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_migrates_and_publishes_projects_with_runtimes()
|
||||||
|
{
|
||||||
|
var projectName = "TestAppSimple";
|
||||||
|
var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, callingMethod: "i")
|
||||||
|
.WithLockFiles()
|
||||||
|
.Path;
|
||||||
|
|
||||||
|
CleanBinObj(projectDirectory);
|
||||||
|
BuildProjectJsonMigrateBuildMSBuild(projectDirectory, projectName);
|
||||||
|
PublishMSBuild(projectDirectory, projectName, "win7-x64");
|
||||||
|
}
|
||||||
|
|
||||||
[WindowsOnlyTheory]
|
[WindowsOnlyTheory]
|
||||||
[InlineData("DesktopTestProjects", "AutoAddDesktopReferencesDuringMigrate", true)]
|
[InlineData("DesktopTestProjects", "AutoAddDesktopReferencesDuringMigrate", true)]
|
||||||
[InlineData("TestProjects", "TestAppSimple", false)]
|
[InlineData("TestProjects", "TestAppSimple", false)]
|
||||||
|
@ -558,6 +571,25 @@ namespace Microsoft.DotNet.Migration.Tests
|
||||||
return result.StdOut;
|
return result.StdOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string PublishMSBuild(string projectDirectory, string projectName, string runtime, string configuration = "Debug")
|
||||||
|
{
|
||||||
|
if (projectName != null)
|
||||||
|
{
|
||||||
|
projectName = projectName + ".csproj";
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteXproj(projectDirectory);
|
||||||
|
|
||||||
|
var result = new Publish3Command()
|
||||||
|
.WithRuntime(runtime)
|
||||||
|
.WithWorkingDirectory(projectDirectory)
|
||||||
|
.ExecuteWithCapturedOutput($"{projectName} /p:Configuration={configuration}");
|
||||||
|
|
||||||
|
result.Should().Pass();
|
||||||
|
|
||||||
|
return result.StdOut;
|
||||||
|
}
|
||||||
|
|
||||||
private void DeleteXproj(string projectDirectory)
|
private void DeleteXproj(string projectDirectory)
|
||||||
{
|
{
|
||||||
var xprojFiles = Directory.EnumerateFiles(projectDirectory, "*.xproj");
|
var xprojFiles = Directory.EnumerateFiles(projectDirectory, "*.xproj");
|
||||||
|
|
|
@ -25,24 +25,20 @@ namespace Microsoft.DotNet.Cli.Publish3.Tests
|
||||||
new Restore3Command()
|
new Restore3Command()
|
||||||
.WithWorkingDirectory(testProjectDirectory)
|
.WithWorkingDirectory(testProjectDirectory)
|
||||||
.Execute()
|
.Execute()
|
||||||
.Should()
|
.Should().Pass();
|
||||||
.Pass();
|
|
||||||
|
|
||||||
new Publish3Command()
|
new Publish3Command()
|
||||||
.WithWorkingDirectory(testProjectDirectory)
|
.WithWorkingDirectory(testProjectDirectory)
|
||||||
.Execute("--framework netcoreapp1.0")
|
.Execute("--framework netcoreapp1.0")
|
||||||
.Should()
|
.Should().Pass();
|
||||||
.Pass();
|
|
||||||
|
|
||||||
var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug";
|
var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug";
|
||||||
var outputDll = Path.Combine(testProjectDirectory, "bin", configuration, "netcoreapp1.0", "publish", $"{testAppName}.dll");
|
var outputDll = Path.Combine(testProjectDirectory, "bin", configuration, "netcoreapp1.0", "publish", $"{testAppName}.dll");
|
||||||
|
|
||||||
new TestCommand("dotnet")
|
new TestCommand("dotnet")
|
||||||
.ExecuteWithCapturedOutput(outputDll)
|
.ExecuteWithCapturedOutput(outputDll)
|
||||||
.Should()
|
.Should().Pass()
|
||||||
.Pass()
|
.And.HaveStdOutContaining("Hello World");
|
||||||
.And
|
|
||||||
.HaveStdOutContaining("Hello World");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -55,23 +51,25 @@ namespace Microsoft.DotNet.Cli.Publish3.Tests
|
||||||
var testProjectDirectory = testInstance.TestRoot;
|
var testProjectDirectory = testInstance.TestRoot;
|
||||||
var rid = DotnetLegacyRuntimeIdentifiers.InferLegacyRestoreRuntimeIdentifier();
|
var rid = DotnetLegacyRuntimeIdentifiers.InferLegacyRestoreRuntimeIdentifier();
|
||||||
|
|
||||||
|
new Restore3Command()
|
||||||
|
.WithWorkingDirectory(testProjectDirectory)
|
||||||
|
.Execute()
|
||||||
|
.Should().Pass();
|
||||||
|
|
||||||
new Publish3Command()
|
new Publish3Command()
|
||||||
.WithFramework("netcoreapp1.0")
|
.WithFramework("netcoreapp1.0")
|
||||||
.WithRuntime(rid)
|
.WithRuntime(rid)
|
||||||
.WithWorkingDirectory(testProjectDirectory)
|
.WithWorkingDirectory(testProjectDirectory)
|
||||||
.Execute()
|
.Execute()
|
||||||
.Should()
|
.Should().Pass();
|
||||||
.Pass();
|
|
||||||
|
|
||||||
var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug";
|
var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug";
|
||||||
var outputProgram = Path.Combine(testProjectDirectory, "bin", configuration, "netcoreapp1.0", rid, "publish", $"{testAppName}{Constants.ExeSuffix}");
|
var outputProgram = Path.Combine(testProjectDirectory, "bin", configuration, "netcoreapp1.0", rid, "publish", $"{testAppName}{Constants.ExeSuffix}");
|
||||||
|
|
||||||
new TestCommand(outputProgram)
|
new TestCommand(outputProgram)
|
||||||
.ExecuteWithCapturedOutput()
|
.ExecuteWithCapturedOutput()
|
||||||
.Should()
|
.Should().Pass()
|
||||||
.Pass()
|
.And.HaveStdOutContaining("Hello World");
|
||||||
.And
|
|
||||||
.HaveStdOutContaining("Hello World");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue