Merge pull request #4517 from livarcocc/promote_project_dependencies
Promote project dependencies
This commit is contained in:
commit
cbed94dbef
9 changed files with 144 additions and 47 deletions
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
|
<TargetFramework>netstandard1.5</TargetFramework>
|
||||||
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -13,5 +12,15 @@
|
||||||
<None Include="project.json" />
|
<None Include="project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Sdk">
|
||||||
|
<Version>1.0.0-alpha-20161026-2</Version>
|
||||||
|
<PrivateAssets>All</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NETStandard.Library">
|
||||||
|
<Version>1.6.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
|
<TargetFramework>netstandard1.5</TargetFramework>
|
||||||
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -13,5 +12,15 @@
|
||||||
<None Include="project.json" />
|
<None Include="project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Sdk">
|
||||||
|
<Version>1.0.0-alpha-20161026-2</Version>
|
||||||
|
<PrivateAssets>All</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NETStandard.Library">
|
||||||
|
<Version>1.6.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
|
<TargetFramework>netstandard1.5</TargetFramework>
|
||||||
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -13,5 +12,15 @@
|
||||||
<None Include="project.json" />
|
<None Include="project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Sdk">
|
||||||
|
<Version>1.0.0-alpha-20161026-2</Version>
|
||||||
|
<PrivateAssets>All</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="NETStandard.Library">
|
||||||
|
<Version>1.6.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using TestLibrary;
|
||||||
|
|
||||||
namespace TestApp
|
namespace TestApp
|
||||||
{
|
{
|
||||||
|
@ -11,6 +12,7 @@ namespace TestApp
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
Console.WriteLine("This string came from ProjectA");
|
Console.WriteLine("This string came from ProjectA");
|
||||||
|
Console.WriteLine($"{ProjectD.GetMessage()}");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,19 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
{
|
{
|
||||||
internal class ProjectDependencyFinder
|
internal class ProjectDependencyFinder
|
||||||
{
|
{
|
||||||
|
public IEnumerable<ProjectDependency> ResolveProjectDependencies(
|
||||||
|
IEnumerable<ProjectContext> projectContexts,
|
||||||
|
IEnumerable<string> preResolvedProjects = null)
|
||||||
|
{
|
||||||
|
foreach (var projectContext in projectContexts)
|
||||||
|
{
|
||||||
|
foreach (var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects))
|
||||||
|
{
|
||||||
|
yield return projectDependency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null)
|
public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null)
|
||||||
{
|
{
|
||||||
var projectContexts = ProjectContext.CreateContextForEachFramework(projectDir);
|
var projectContexts = ProjectContext.CreateContextForEachFramework(projectDir);
|
||||||
|
@ -31,20 +44,37 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
return ResolveProjectDependencies(projectContexts, ResolveXProjProjectDependencyNames(xproj));
|
return ResolveProjectDependencies(projectContexts, ResolveXProjProjectDependencyNames(xproj));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ProjectDependency> ResolveProjectDependencies(
|
public IEnumerable<ProjectDependency> ResolveAllProjectDependenciesForFramework(
|
||||||
IEnumerable<ProjectContext> projectContexts,
|
ProjectDependency projectToResolve,
|
||||||
IEnumerable<string> preResolvedProjects = null)
|
NuGetFramework framework,
|
||||||
|
IEnumerable<string> preResolvedProjects=null)
|
||||||
{
|
{
|
||||||
foreach (var projectContext in projectContexts)
|
var projects = new List<ProjectDependency> { projectToResolve };
|
||||||
|
var allDependencies = new List<ProjectDependency>();
|
||||||
|
while (projects.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects))
|
var project = projects.First();
|
||||||
|
projects.Remove(project);
|
||||||
|
var projectContext =
|
||||||
|
ProjectContext.CreateContextForEachFramework(project.ProjectFilePath).FirstOrDefault();
|
||||||
|
if(projectContext == null)
|
||||||
{
|
{
|
||||||
yield return projectDependency;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dependencies = ResolveDirectProjectDependenciesForFramework(
|
||||||
|
projectContext.ProjectFile,
|
||||||
|
framework,
|
||||||
|
preResolvedProjects
|
||||||
|
);
|
||||||
|
projects.AddRange(dependencies);
|
||||||
|
allDependencies.AddRange(dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return allDependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ProjectDependency> ResolveProjectDependenciesForFramework(
|
public IEnumerable<ProjectDependency> ResolveDirectProjectDependenciesForFramework(
|
||||||
Project project,
|
Project project,
|
||||||
NuGetFramework framework,
|
NuGetFramework framework,
|
||||||
IEnumerable<string> preResolvedProjects=null)
|
IEnumerable<string> preResolvedProjects=null)
|
||||||
|
@ -98,7 +128,37 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
return projectDependencies;
|
return projectDependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ProjectDependency> ResolveProjectDependencies(ProjectContext projectContext, IEnumerable<string> preResolvedProjects=null)
|
internal IEnumerable<ProjectItemElement> ResolveXProjProjectDependencies(ProjectRootElement xproj)
|
||||||
|
{
|
||||||
|
if (xproj == null)
|
||||||
|
{
|
||||||
|
MigrationTrace.Instance.WriteLine($"{nameof(ProjectDependencyFinder)}: No xproj file given.");
|
||||||
|
return Enumerable.Empty<ProjectItemElement>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return xproj.Items
|
||||||
|
.Where(i => i.ItemType == "ProjectReference")
|
||||||
|
.Where(p => p.Includes().Any(
|
||||||
|
include => string.Equals(Path.GetExtension(include), ".csproj", StringComparison.OrdinalIgnoreCase)));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string FindXprojFile(string projectDirectory)
|
||||||
|
{
|
||||||
|
var allXprojFiles = Directory.EnumerateFiles(projectDirectory, "*.xproj", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
if (allXprojFiles.Count() > 1)
|
||||||
|
{
|
||||||
|
MigrationErrorCodes
|
||||||
|
.MIGRATE1017($"Multiple xproj files found in {projectDirectory}, please specify which to use")
|
||||||
|
.Throw();
|
||||||
|
}
|
||||||
|
|
||||||
|
return allXprojFiles.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<ProjectDependency> ResolveProjectDependencies(
|
||||||
|
ProjectContext projectContext,
|
||||||
|
IEnumerable<string> preResolvedProjects=null)
|
||||||
{
|
{
|
||||||
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
|
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
|
||||||
|
|
||||||
|
@ -144,34 +204,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration
|
||||||
PathUtility.GetPathWithDirectorySeparator(p))));
|
PathUtility.GetPathWithDirectorySeparator(p))));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<ProjectItemElement> ResolveXProjProjectDependencies(ProjectRootElement xproj)
|
|
||||||
{
|
|
||||||
if (xproj == null)
|
|
||||||
{
|
|
||||||
MigrationTrace.Instance.WriteLine($"{nameof(ProjectDependencyFinder)}: No xproj file given.");
|
|
||||||
return Enumerable.Empty<ProjectItemElement>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return xproj.Items
|
|
||||||
.Where(i => i.ItemType == "ProjectReference")
|
|
||||||
.Where(p => p.Includes().Any(
|
|
||||||
include => string.Equals(Path.GetExtension(include), ".csproj", StringComparison.OrdinalIgnoreCase)));
|
|
||||||
}
|
|
||||||
|
|
||||||
internal string FindXprojFile(string projectDirectory)
|
|
||||||
{
|
|
||||||
var allXprojFiles = Directory.EnumerateFiles(projectDirectory, "*.xproj", SearchOption.TopDirectoryOnly);
|
|
||||||
|
|
||||||
if (allXprojFiles.Count() > 1)
|
|
||||||
{
|
|
||||||
MigrationErrorCodes
|
|
||||||
.MIGRATE1017($"Multiple xproj files found in {projectDirectory}, please specify which to use")
|
|
||||||
.Throw();
|
|
||||||
}
|
|
||||||
|
|
||||||
return allXprojFiles.FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, ProjectDependency> FindPossibleProjectDependencies(string projectJsonFilePath)
|
private Dictionary<string, ProjectDependency> FindPossibleProjectDependencies(string projectJsonFilePath)
|
||||||
{
|
{
|
||||||
var projectRootDirectory = GetRootFromProjectJson(projectJsonFilePath);
|
var projectRootDirectory = GetRootFromProjectJson(projectJsonFilePath);
|
||||||
|
|
|
@ -244,7 +244,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes());
|
var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes());
|
||||||
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
|
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
|
||||||
PathUtility.GetPathWithDirectorySeparator(p))));
|
PathUtility.GetPathWithDirectorySeparator(p))));
|
||||||
var projectDependencies = _projectDependencyFinder.ResolveProjectDependenciesForFramework(
|
var projectDependencies = _projectDependencyFinder.ResolveDirectProjectDependenciesForFramework(
|
||||||
project,
|
project,
|
||||||
framework,
|
framework,
|
||||||
preResolvedProjects: migratedXProjDependencyNames);
|
preResolvedProjects: migratedXProjDependencyNames);
|
||||||
|
|
|
@ -30,8 +30,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
_projectDirectory = migrationSettings.ProjectDirectory;
|
_projectDirectory = migrationSettings.ProjectDirectory;
|
||||||
|
|
||||||
var migratedXProjDependencyPaths = MigrateXProjProjectDependencies(migrationRuleInputs);
|
var migratedXProjDependencyPaths = MigrateXProjProjectDependencies(migrationRuleInputs);
|
||||||
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
|
var migratedXProjDependencyNames = new HashSet<string>(
|
||||||
PathUtility.GetPathWithDirectorySeparator(p))));
|
migratedXProjDependencyPaths.Select(p =>
|
||||||
|
Path.GetFileNameWithoutExtension(PathUtility.GetPathWithDirectorySeparator(p))));
|
||||||
MigrateProjectJsonProjectDependencies(
|
MigrateProjectJsonProjectDependencies(
|
||||||
migrationRuleInputs.ProjectContexts,
|
migrationRuleInputs.ProjectContexts,
|
||||||
migratedXProjDependencyNames,
|
migratedXProjDependencyNames,
|
||||||
|
@ -104,8 +105,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||||
HashSet<string> migratedXProjDependencyNames,
|
HashSet<string> migratedXProjDependencyNames,
|
||||||
ProjectRootElement outputMSBuildProject)
|
ProjectRootElement outputMSBuildProject)
|
||||||
{
|
{
|
||||||
var projectDependencies = _projectDependencyFinder.ResolveProjectDependenciesForFramework(
|
var projectDependencies = _projectDependencyFinder.ResolveAllProjectDependenciesForFramework(
|
||||||
project,
|
new ProjectDependency(project.Name, project.ProjectFilePath),
|
||||||
framework,
|
framework,
|
||||||
migratedXProjDependencyNames);
|
migratedXProjDependencyNames);
|
||||||
|
|
||||||
|
|
|
@ -238,5 +238,25 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
||||||
migratedProjectReferenceItem.Include.Should().Be(projectReference);
|
migratedProjectReferenceItem.Include.Should().Be(projectReference);
|
||||||
migratedProjectReferenceItem.Condition.Should().Be(" '$(Bar)' == 'foo' and '$(Foo)' == 'bar' ");
|
migratedProjectReferenceItem.Condition.Should().Be(" '$(Bar)' == 'foo' and '$(Foo)' == 'bar' ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_promotes_P2P_references_up_in_the_dependency_chain()
|
||||||
|
{
|
||||||
|
var solutionDirectory =
|
||||||
|
TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", callingMethod: "p").Path;
|
||||||
|
|
||||||
|
var appDirectory = Path.Combine(solutionDirectory, "ProjectA");
|
||||||
|
|
||||||
|
var projectContext = ProjectContext.Create(appDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
|
||||||
|
var mockProj = ProjectRootElement.Create();
|
||||||
|
var testSettings = new MigrationSettings(appDirectory, appDirectory, "1.0.0", mockProj, null);
|
||||||
|
var testInputs = new MigrationRuleInputs(new[] {projectContext}, mockProj, mockProj.AddItemGroup(),
|
||||||
|
mockProj.AddPropertyGroup());
|
||||||
|
new MigrateProjectDependenciesRule().Apply(testSettings, testInputs);
|
||||||
|
|
||||||
|
var projectReferences = mockProj.Items.Where(
|
||||||
|
item => item.ItemType.Equals("ProjectReference", StringComparison.Ordinal));
|
||||||
|
projectReferences.Count().Should().Be(7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,6 +375,21 @@ namespace Microsoft.DotNet.Migration.Tests
|
||||||
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_builds_a_migrated_app_with_a_indirect_dependency()
|
||||||
|
{
|
||||||
|
const string projectName = "ProjectA";
|
||||||
|
var solutionDirectory =
|
||||||
|
TestAssetsManager.CreateTestInstance("TestAppDependencyGraph", callingMethod: "p").Path;
|
||||||
|
var projectDirectory = Path.Combine(solutionDirectory, projectName);
|
||||||
|
|
||||||
|
MigrateProject(new string[] { projectDirectory });
|
||||||
|
Restore(projectDirectory);
|
||||||
|
BuildMSBuild(projectDirectory, projectName);
|
||||||
|
|
||||||
|
VerifyAllMSBuildOutputsRunnable(projectDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
private void VerifyAutoInjectedDesktopReferences(string projectDirectory, string projectName, bool shouldBePresent)
|
private void VerifyAutoInjectedDesktopReferences(string projectDirectory, string projectName, bool shouldBePresent)
|
||||||
{
|
{
|
||||||
if (projectName != null)
|
if (projectName != null)
|
||||||
|
|
Loading…
Reference in a new issue