Fix P2P migration
Fixes #4269 by deep cloning the MsbuildTemplateProject for each P2P reference. Add test which migrates and builds P2P references.
This commit is contained in:
parent
09e8877bd4
commit
a396630576
27 changed files with 201 additions and 54 deletions
|
@ -0,0 +1,17 @@
|
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
|
||||
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" Exclude="$(GlobalExclude)" />
|
||||
<EmbeddedResource Include="**\*.resx" Exclude="$(GlobalExclude)" />
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -5,11 +5,11 @@ using System;
|
|||
|
||||
namespace TestLibrary
|
||||
{
|
||||
public static class ProjectE
|
||||
public static class ProjectC
|
||||
{
|
||||
public static string GetMessage()
|
||||
{
|
||||
return "This string came from ProjectF";
|
||||
return "This string came from CsprojLibrary1";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"dependencies": {},
|
||||
"frameworks": {
|
||||
"netstandard1.5": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Sdk": "1.0.0-alpha-20160923-4",
|
||||
"NETStandard.Library": "1.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
|
||||
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" Exclude="$(GlobalExclude)" />
|
||||
<EmbeddedResource Include="**\*.resx" Exclude="$(GlobalExclude)" />
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,15 @@
|
|||
// 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;
|
||||
|
||||
namespace TestLibrary
|
||||
{
|
||||
public static class ProjectC
|
||||
{
|
||||
public static string GetMessage()
|
||||
{
|
||||
return "This string came from CsprojLibrary2";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"dependencies": {},
|
||||
"frameworks": {
|
||||
"netstandard1.5": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Sdk": "1.0.0-alpha-20160923-4",
|
||||
"NETStandard.Library": "1.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
|
||||
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" Exclude="$(GlobalExclude)" />
|
||||
<EmbeddedResource Include="**\*.resx" Exclude="$(GlobalExclude)" />
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,15 @@
|
|||
// 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;
|
||||
|
||||
namespace TestLibrary
|
||||
{
|
||||
public static class ProjectC
|
||||
{
|
||||
public static string GetMessage()
|
||||
{
|
||||
return "This string came from CsprojLibrary3";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"dependencies": {},
|
||||
"frameworks": {
|
||||
"netstandard1.5": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Sdk": "1.0.0-alpha-20160923-4",
|
||||
"NETStandard.Library": "1.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ namespace TestApp
|
|||
public static int Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("This string came from ProjectA");
|
||||
return 100;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ClassLibrary1\ClassLibrary1.csproj" />
|
||||
<ProjectReference Include="..\..\ClassLibrary2\ClassLibrary2.csproj" />
|
||||
<ProjectReference Include="..\CsprojLibrary1\CsprojLibrary1.csproj" />
|
||||
<ProjectReference Include="..\CsprojLibrary2\CsprojLibrary2.csproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -18,10 +18,10 @@
|
|||
"target": "project",
|
||||
"version": "1.0.0-*"
|
||||
},
|
||||
"ClassLibrary1": {
|
||||
"CsprojLibrary1": {
|
||||
"target": "project"
|
||||
},
|
||||
"ClassLibrary2": {
|
||||
"CsprojLibrary2": {
|
||||
"target": "project"
|
||||
},
|
||||
"NETStandard.Library": "1.6.0"
|
|
@ -16,8 +16,8 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ClassLibrary2\ClassLibrary2.csproj" />
|
||||
<ProjectReference Include="..\..\ClassLibrary3\ClassLibrary3.csproj" />
|
||||
<ProjectReference Include="..\CsprojLibrary2\CsprojLibrary2.csproj" />
|
||||
<ProjectReference Include="..\CsprojLibrary3\CsprojLibrary3.csproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -10,10 +10,10 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ClassLibrary2": {
|
||||
"CsprojLibrary2": {
|
||||
"target": "project"
|
||||
},
|
||||
"ClassLibrary3": {
|
||||
"CsprojLibrary3": {
|
||||
"target": "project"
|
||||
},
|
||||
"NETStandard.Library": "1.6.0"
|
|
@ -0,0 +1,19 @@
|
|||
// 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.Diagnostics;
|
||||
|
||||
namespace TestApp
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("This string came from ProjectF");
|
||||
string helperStr = TestLibrary.ProjectG.GetMessage();
|
||||
Console.WriteLine(helperStr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +1,20 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"nowarn": [
|
||||
"CS1591"
|
||||
],
|
||||
"xmlDoc": true,
|
||||
"additionalArguments": [
|
||||
"-highentropyva+"
|
||||
]
|
||||
"emitEntryPoint": true,
|
||||
"preserveCompilationContext": true
|
||||
},
|
||||
"dependencies": {
|
||||
"ProjectG": {
|
||||
"target": "project",
|
||||
"version": "1.0.0-*"
|
||||
},
|
||||
"NETStandard.Library": "1.6.0"
|
||||
"Microsoft.NETCore.App": {
|
||||
"type": "platform",
|
||||
"version": "1.0.1"
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.5": {}
|
||||
"netcoreapp1.0": {}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ using System;
|
|||
|
||||
namespace TestLibrary
|
||||
{
|
||||
public static class ProjectE
|
||||
public static class ProjectG
|
||||
{
|
||||
public static string GetMessage()
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ using NuGet.LibraryModel;
|
|||
|
||||
namespace Microsoft.DotNet.ProjectJsonMigration
|
||||
{
|
||||
internal class ProjectDependencyFinder
|
||||
public class ProjectDependencyFinder
|
||||
{
|
||||
public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null)
|
||||
{
|
||||
|
@ -33,16 +33,17 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
|
||||
public IEnumerable<ProjectDependency> ResolveProjectDependencies(
|
||||
IEnumerable<ProjectContext> projectContexts,
|
||||
IEnumerable<string> preResolvedProjects=null)
|
||||
IEnumerable<string> preResolvedProjects = null)
|
||||
{
|
||||
foreach(var projectContext in projectContexts)
|
||||
foreach (var projectContext in projectContexts)
|
||||
{
|
||||
foreach(var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects))
|
||||
foreach (var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects))
|
||||
{
|
||||
yield return projectDependency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ProjectDependency> ResolveProjectDependenciesForFramework(
|
||||
Project project,
|
||||
NuGetFramework framework,
|
||||
|
@ -95,7 +96,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
|
||||
|
||||
var projectExports = projectContext.CreateExporter("_").GetDependencies();
|
||||
var possibleProjectDependencies =
|
||||
var possibleProjectDependencies =
|
||||
FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath);
|
||||
|
||||
var projectDependencies = new List<ProjectDependency>();
|
||||
|
@ -104,10 +105,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
var projectExportName = projectExport.Library.Identity.Name;
|
||||
ProjectDependency projectDependency;
|
||||
|
||||
if (preResolvedProjects.Contains(projectExportName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!possibleProjectDependencies.TryGetValue(projectExportName, out projectDependency))
|
||||
{
|
||||
if (projectExport.Library.Identity.Type.Equals(LibraryType.Project)
|
||||
&& !preResolvedProjects.Contains(projectExportName))
|
||||
if (projectExport.Library.Identity.Type.Equals(LibraryType.Project))
|
||||
{
|
||||
MigrationErrorCodes
|
||||
.MIGRATE1014($"Unresolved project dependency ({projectExportName})").Throw();
|
||||
|
@ -347,7 +352,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
var projects = settings["projects"];
|
||||
var dependencies = settings["dependencies"] as JObject;
|
||||
|
||||
globalSettings.ProjectPaths = projects == null ? new string[] { } : projects.Select(a => a.Value<string>()).ToArray();;
|
||||
globalSettings.ProjectPaths = projects == null ? new string[] { } : projects.Select(a => a.Value<string>()).ToArray(); ;
|
||||
globalSettings.PackagesPath = settings.Value<string>("packages");
|
||||
globalSettings.FilePath = globalJsonPath;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
Exception exc = null;
|
||||
IEnumerable<ProjectDependency> projectDependencies = null;
|
||||
|
||||
var tempMSBuildProjectTemplate = rootSettings.MSBuildProjectTemplate.DeepClone();
|
||||
|
||||
try
|
||||
{
|
||||
projectDependencies = ResolveTransitiveClosureProjectDependencies(
|
||||
|
@ -54,7 +56,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
}
|
||||
|
||||
MigrateProject(rootSettings);
|
||||
|
||||
|
||||
if (skipProjectReferences)
|
||||
{
|
||||
return;
|
||||
|
@ -66,7 +68,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
var settings = new MigrationSettings(projectDir,
|
||||
projectDir,
|
||||
rootSettings.SdkPackageVersion,
|
||||
rootSettings.MSBuildProjectTemplate);
|
||||
tempMSBuildProjectTemplate.DeepClone());
|
||||
MigrateProject(settings);
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +95,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile);
|
||||
Queue<ProjectDependency> projectsQueue = new Queue<ProjectDependency>(projectDependencies);
|
||||
|
||||
while(projectsQueue.Count() != 0)
|
||||
while (projectsQueue.Count() != 0)
|
||||
{
|
||||
var projectDependency = projectsQueue.Dequeue();
|
||||
|
||||
|
@ -107,7 +109,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
var projectDir = Path.GetDirectoryName(projectDependency.ProjectFilePath);
|
||||
projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectDir);
|
||||
|
||||
foreach(var project in projectDependencies)
|
||||
foreach (var project in projectDependencies)
|
||||
{
|
||||
projectsQueue.Enqueue(project);
|
||||
}
|
||||
|
@ -138,7 +140,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
|||
{
|
||||
var projectContexts = ProjectContext.CreateContextForEachFramework(migrationSettings.ProjectDirectory);
|
||||
var xprojFile = migrationSettings.ProjectXProjFilePath ?? _projectDependencyFinder.FindXprojFile(migrationSettings.ProjectDirectory);
|
||||
|
||||
|
||||
ProjectRootElement xproj = null;
|
||||
if (xprojFile != null)
|
||||
{
|
||||
|
|
|
@ -153,8 +153,6 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
var projectDirectory =
|
||||
TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", callingMethod: $"{projectName}.RefsTest").Path;
|
||||
|
||||
FixUpProjectJsons(projectDirectory);
|
||||
|
||||
MigrateProject(Path.Combine(projectDirectory, projectName));
|
||||
|
||||
string[] migratedProjects = expectedProjects.Split(new char[] { ',' });
|
||||
|
@ -172,8 +170,6 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
var projectDirectory =
|
||||
TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", callingMethod: $"{projectName}.SkipRefsTest").Path;
|
||||
|
||||
FixUpProjectJsons(projectDirectory);
|
||||
|
||||
MigrateCommand.Run(new [] { Path.Combine(projectDirectory, projectName), "--skip-project-references" }).Should().Be(0);
|
||||
|
||||
VerifyMigration(Enumerable.Repeat(projectName, 1), projectDirectory);
|
||||
|
@ -186,8 +182,6 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", callingMethod: $"MigrateDirectory.SkipRefs.{skipRefs}").Path;
|
||||
|
||||
FixUpProjectJsons(projectDirectory);
|
||||
|
||||
if (skipRefs)
|
||||
{
|
||||
MigrateCommand.Run(new [] { projectDirectory, "--skip-project-references" }).Should().Be(0);
|
||||
|
@ -206,8 +200,6 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph").Path;
|
||||
|
||||
FixUpProjectJsons(projectDirectory);
|
||||
|
||||
var project = Path.Combine(projectDirectory, "ProjectA", "project.json");
|
||||
MigrateCommand.Run(new [] { project }).Should().Be(0);
|
||||
|
||||
|
@ -215,21 +207,31 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
VerifyMigration(migratedProjects, projectDirectory);
|
||||
}
|
||||
|
||||
private void FixUpProjectJsons(string projectDirectory)
|
||||
[Fact]
|
||||
// regression test for https://github.com/dotnet/cli/issues/4269
|
||||
public void It_migrates_and_builds_P2P_references()
|
||||
{
|
||||
var pjs = Directory.EnumerateFiles(projectDirectory, "project.json.1", SearchOption.AllDirectories);
|
||||
var assetsDir = TestAssetsManager.CreateTestInstance("TestAppDependencyGraph").WithLockFiles().Path;
|
||||
var projectDirectory = Path.Combine(assetsDir, "ProjectF");
|
||||
var depProjects = new List<string>() { Path.Combine(assetsDir, "ProjectG") };
|
||||
var outputComparisonData = BuildProjectJsonMigrateBuildMSBuild(projectDirectory, "ProjectF", depProjects);
|
||||
|
||||
foreach(var pj in pjs)
|
||||
{
|
||||
var newPj = pj.Replace("project.json.1", "project.json");
|
||||
File.Move(pj, newPj);
|
||||
}
|
||||
var outputsIdentical = outputComparisonData.ProjectJsonBuildOutputs
|
||||
.SetEquals(outputComparisonData.MSBuildBuildOutputs);
|
||||
|
||||
if (!outputsIdentical)
|
||||
{
|
||||
OutputDiagnostics(outputComparisonData);
|
||||
}
|
||||
|
||||
outputsIdentical.Should().BeTrue();
|
||||
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
||||
}
|
||||
|
||||
private void VerifyMigration(IEnumerable<string> expectedProjects, string rootDir)
|
||||
{
|
||||
var migratedProjects = Directory.EnumerateFiles(rootDir, "*.csproj", SearchOption.AllDirectories)
|
||||
.Select(s => Path.GetFileNameWithoutExtension(s));
|
||||
var migratedProjects = Directory.EnumerateFiles(rootDir, "project.migrated.json", SearchOption.AllDirectories)
|
||||
.Select(s => Path.GetFileName(Path.GetDirectoryName(s)));
|
||||
migratedProjects.Should().BeEquivalentTo(expectedProjects);
|
||||
}
|
||||
|
||||
|
@ -272,7 +274,7 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
}
|
||||
}
|
||||
|
||||
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(string projectDirectory, string projectName=null)
|
||||
private MigratedBuildComparisonData BuildProjectJsonMigrateBuildMSBuild(string projectDirectory, string projectName, List<string> additonalRestoreDirectories = null)
|
||||
{
|
||||
BuildProjectJson(projectDirectory);
|
||||
var projectJsonBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory));
|
||||
|
@ -285,6 +287,13 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
|
||||
DeleteXproj(projectDirectory);
|
||||
Restore3(projectDirectory, projectName);
|
||||
|
||||
additonalRestoreDirectories = additonalRestoreDirectories ?? new List<string>();
|
||||
foreach(var dir in additonalRestoreDirectories)
|
||||
{
|
||||
Restore3(dir);
|
||||
}
|
||||
|
||||
BuildMSBuild(projectDirectory, projectName);
|
||||
|
||||
var msbuildBuildOutputs = new HashSet<string>(CollectBuildOutputs(projectDirectory));
|
||||
|
@ -355,8 +364,8 @@ namespace Microsoft.DotNet.Migration.Tests
|
|||
if (projectName != null)
|
||||
{
|
||||
command.Execute($"{projectName}.csproj")
|
||||
.Should()
|
||||
.Pass();
|
||||
.Should()
|
||||
.Pass();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue