Auto add referenced assemblies for desktop migration
* https://github.com/dotnet/cli/issues/4351 Auto add referenced assemblies for desktop migration. Adds the same ones that the build for project.json does. * Address PR comments * Address CR comments * Address CR comment Use .ToList() instead of new List * Fix a build break Needed .noautobuild file in my test asset project * Change the migrate test for desktop framework to windows only * Reducing to 120 characters per line
This commit is contained in:
parent
a6d37d25f5
commit
71666cc9b5
6 changed files with 131 additions and 11 deletions
|
@ -0,0 +1,21 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.CSharp.RuntimeBinder;
|
||||
|
||||
namespace AutoAddDesktopReferencesDuringMigrate
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var mscorlibRef = new List<int>(new int[] { 4, 5, 6 });
|
||||
var systemCoreRef = mscorlibRef.ToArray().Average();
|
||||
Debug.Assert(systemCoreRef == 5, "Test System assembly reference");
|
||||
if (systemCoreRef != 5)
|
||||
{
|
||||
throw new RuntimeBinderException("Test Microsoft.CSharp assembly reference");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"debugType": "portable",
|
||||
"emitEntryPoint": true
|
||||
},
|
||||
"dependencies": {},
|
||||
"frameworks": {
|
||||
"net451": {}
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
|||
migrationRuleInputs.OutputMSBuildProject,
|
||||
targetFramework.FrameworkName,
|
||||
targetFramework.Dependencies,
|
||||
migrationRuleInputs.ProjectXproj);
|
||||
migrationRuleInputs.ProjectXproj);
|
||||
}
|
||||
|
||||
MigrateTools(project, migrationRuleInputs.OutputMSBuildProject);
|
||||
|
@ -125,13 +125,15 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
|||
ProjectRootElement xproj)
|
||||
{
|
||||
var projectDependencies = new HashSet<string>(GetAllProjectReferenceNames(project, framework, xproj));
|
||||
var packageDependencies = dependencies.Where(d => !projectDependencies.Contains(d.Name));
|
||||
var packageDependencies = dependencies.Where(d => !projectDependencies.Contains(d.Name)).ToList();
|
||||
|
||||
string condition = framework?.GetMSBuildCondition() ?? "";
|
||||
var itemGroup = output.ItemGroups.FirstOrDefault(i => i.Condition == condition)
|
||||
?? output.AddItemGroup();
|
||||
itemGroup.Condition = condition;
|
||||
|
||||
AutoInjectImplicitProjectJsonAssemblyReferences(framework, packageDependencies);
|
||||
|
||||
foreach (var packageDependency in packageDependencies)
|
||||
{
|
||||
MigrationTrace.Instance.WriteLine(packageDependency.Name);
|
||||
|
@ -165,6 +167,31 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
|||
}
|
||||
}
|
||||
|
||||
private void AutoInjectImplicitProjectJsonAssemblyReferences(NuGetFramework framework,
|
||||
IList<ProjectLibraryDependency> packageDependencies)
|
||||
{
|
||||
if (framework?.IsDesktop() ?? false)
|
||||
{
|
||||
InjectAssemblyReferenceIfNotPresent("System", packageDependencies);
|
||||
if (framework.Version >= new Version(4, 0))
|
||||
{
|
||||
InjectAssemblyReferenceIfNotPresent("Microsoft.CSharp", packageDependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InjectAssemblyReferenceIfNotPresent(string dependencyName,
|
||||
IList<ProjectLibraryDependency> packageDependencies)
|
||||
{
|
||||
if (!packageDependencies.Any(dep => string.Equals(dep.Name, dependencyName, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
packageDependencies.Add(new ProjectLibraryDependency
|
||||
{
|
||||
LibraryRange = new LibraryRange(dependencyName, LibraryDependencyTarget.Reference)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadLibraryIncludeFlags(LibraryIncludeFlags includeFlags)
|
||||
{
|
||||
if ((includeFlags ^ LibraryIncludeFlags.All) == 0)
|
||||
|
|
|
@ -200,6 +200,39 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
|||
net451Import.Value.Split(';').Should().BeEquivalentTo($"$({importPropertyName})", "netstandard1.3");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void It_auto_add_desktop_references_during_migrate()
|
||||
{
|
||||
var mockProj = RunPackageDependenciesRuleOnPj(@"
|
||||
{
|
||||
""frameworks"": {
|
||||
""net35"" : {},
|
||||
""net4"" : {},
|
||||
""net451"" : {}
|
||||
}
|
||||
}");
|
||||
|
||||
var itemGroup = mockProj.ItemGroups.Where(i => i.Condition == " '$(TargetFramework)' == 'net451' ");
|
||||
itemGroup.Should().HaveCount(1);
|
||||
itemGroup.First().Items.Should().HaveCount(2);
|
||||
var items = itemGroup.First().Items.ToArray();
|
||||
items[0].Include.Should().Be("System");
|
||||
items[1].Include.Should().Be("Microsoft.CSharp");
|
||||
|
||||
itemGroup = mockProj.ItemGroups.Where(i => i.Condition == " '$(TargetFramework)' == 'net40' ");
|
||||
itemGroup.Should().HaveCount(1);
|
||||
itemGroup.First().Items.Should().HaveCount(2);
|
||||
items = itemGroup.First().Items.ToArray();
|
||||
items[0].Include.Should().Be("System");
|
||||
items[1].Include.Should().Be("Microsoft.CSharp");
|
||||
|
||||
itemGroup = mockProj.ItemGroups.Where(i => i.Condition == " '$(TargetFramework)' == 'net35' ");
|
||||
itemGroup.Should().HaveCount(1);
|
||||
itemGroup.First().Items.Should().HaveCount(1);
|
||||
items = itemGroup.First().Items.ToArray();
|
||||
items[0].Include.Should().Be("System");
|
||||
}
|
||||
|
||||
private void EmitsPackageReferences(ProjectRootElement mockProj, params Tuple<string, string, string>[] packageSpecs)
|
||||
{
|
||||
foreach (var packageSpec in packageSpecs)
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
using Microsoft.Build.Construction;
|
||||
using Microsoft.DotNet.ProjectJsonMigration;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.TestFramework;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
using NuGet.Frameworks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using FluentAssertions;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Tools.Migrate;
|
||||
using Build3Command = Microsoft.DotNet.Tools.Test.Utilities.Build3Command;
|
||||
using BuildCommand = Microsoft.DotNet.Tools.Test.Utilities.BuildCommand;
|
||||
|
@ -295,7 +289,6 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
}
|
||||
|
||||
[Theory]
|
||||
// https://github.com/dotnet/cli/issues/4313
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void Migration_outputs_error_when_no_projects_found(bool useGlobalJson)
|
||||
|
@ -343,7 +336,42 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
result.StdErr.Should().Contain(errorMessage);
|
||||
result.StdErr.Should().Contain("Migration failed.");
|
||||
}
|
||||
|
||||
|
||||
[WindowsOnlyTheory]
|
||||
[InlineData("DesktopTestProjects", "AutoAddDesktopReferencesDuringMigrate", true)]
|
||||
[InlineData("TestProjects", "TestAppSimple", false)]
|
||||
public void It_auto_add_desktop_references_during_migrate(string testGroup, string projectName, bool isDesktopApp)
|
||||
{
|
||||
var testAssetManager = GetTestGroupTestAssetsManager(testGroup);
|
||||
var projectDirectory = testAssetManager.CreateTestInstance(projectName, callingMethod: "i").WithLockFiles().Path;
|
||||
|
||||
CleanBinObj(projectDirectory);
|
||||
MigrateProject(new string[] { projectDirectory });
|
||||
Restore3(projectDirectory);
|
||||
BuildMSBuild(projectDirectory, projectName);
|
||||
VerifyAutoInjectedDesktopReferences(projectDirectory, projectName, isDesktopApp);
|
||||
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
||||
}
|
||||
|
||||
private void VerifyAutoInjectedDesktopReferences(string projectDirectory, string projectName, bool shouldBePresent)
|
||||
{
|
||||
if (projectName != null)
|
||||
{
|
||||
projectName = projectName + ".csproj";
|
||||
}
|
||||
|
||||
var root = ProjectRootElement.Open(Path.Combine(projectDirectory, projectName));
|
||||
var autoInjectedReferences = root.Items.Where(i => i.ItemType == "Reference" && (i.Include == "System" || i.Include == "Microsoft.CSharp"));
|
||||
if (shouldBePresent)
|
||||
{
|
||||
autoInjectedReferences.Should().HaveCount(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
autoInjectedReferences.Should().BeEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private void VerifyMigration(IEnumerable<string> expectedProjects, string rootDir)
|
||||
{
|
||||
var migratedProjects = Directory.EnumerateFiles(rootDir, "project.json", SearchOption.AllDirectories)
|
||||
|
|
Loading…
Reference in a new issue