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,
|
migrationRuleInputs.OutputMSBuildProject,
|
||||||
targetFramework.FrameworkName,
|
targetFramework.FrameworkName,
|
||||||
targetFramework.Dependencies,
|
targetFramework.Dependencies,
|
||||||
migrationRuleInputs.ProjectXproj);
|
migrationRuleInputs.ProjectXproj);
|
||||||
}
|
}
|
||||||
|
|
||||||
MigrateTools(project, migrationRuleInputs.OutputMSBuildProject);
|
MigrateTools(project, migrationRuleInputs.OutputMSBuildProject);
|
||||||
|
@ -125,13 +125,15 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
ProjectRootElement xproj)
|
ProjectRootElement xproj)
|
||||||
{
|
{
|
||||||
var projectDependencies = new HashSet<string>(GetAllProjectReferenceNames(project, framework, 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() ?? "";
|
string condition = framework?.GetMSBuildCondition() ?? "";
|
||||||
var itemGroup = output.ItemGroups.FirstOrDefault(i => i.Condition == condition)
|
var itemGroup = output.ItemGroups.FirstOrDefault(i => i.Condition == condition)
|
||||||
?? output.AddItemGroup();
|
?? output.AddItemGroup();
|
||||||
itemGroup.Condition = condition;
|
itemGroup.Condition = condition;
|
||||||
|
|
||||||
|
AutoInjectImplicitProjectJsonAssemblyReferences(framework, packageDependencies);
|
||||||
|
|
||||||
foreach (var packageDependency in packageDependencies)
|
foreach (var packageDependency in packageDependencies)
|
||||||
{
|
{
|
||||||
MigrationTrace.Instance.WriteLine(packageDependency.Name);
|
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)
|
private string ReadLibraryIncludeFlags(LibraryIncludeFlags includeFlags)
|
||||||
{
|
{
|
||||||
if ((includeFlags ^ LibraryIncludeFlags.All) == 0)
|
if ((includeFlags ^ LibraryIncludeFlags.All) == 0)
|
||||||
|
|
|
@ -200,6 +200,39 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
||||||
net451Import.Value.Split(';').Should().BeEquivalentTo($"$({importPropertyName})", "netstandard1.3");
|
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)
|
private void EmitsPackageReferences(ProjectRootElement mockProj, params Tuple<string, string, string>[] packageSpecs)
|
||||||
{
|
{
|
||||||
foreach (var packageSpec in packageSpecs)
|
foreach (var packageSpec in packageSpecs)
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
using Microsoft.Build.Construction;
|
using Microsoft.Build.Construction;
|
||||||
using Microsoft.DotNet.ProjectJsonMigration;
|
using Microsoft.DotNet.TestFramework;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
|
||||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||||
using NuGet.Frameworks;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Microsoft.DotNet.Tools.Common;
|
|
||||||
using Microsoft.DotNet.Cli;
|
|
||||||
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;
|
||||||
|
@ -295,7 +289,6 @@ namespace Microsoft.DotNet.Migration.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
// https://github.com/dotnet/cli/issues/4313
|
|
||||||
[InlineData(true)]
|
[InlineData(true)]
|
||||||
[InlineData(false)]
|
[InlineData(false)]
|
||||||
public void Migration_outputs_error_when_no_projects_found(bool useGlobalJson)
|
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(errorMessage);
|
||||||
result.StdErr.Should().Contain("Migration failed.");
|
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)
|
private void VerifyMigration(IEnumerable<string> expectedProjects, string rootDir)
|
||||||
{
|
{
|
||||||
var migratedProjects = Directory.EnumerateFiles(rootDir, "project.json", SearchOption.AllDirectories)
|
var migratedProjects = Directory.EnumerateFiles(rootDir, "project.json", SearchOption.AllDirectories)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue