Merge pull request #4517 from livarcocc/promote_project_dependencies

Promote project dependencies
This commit is contained in:
Livar 2016-10-28 15:17:47 -07:00 committed by GitHub
commit cbed94dbef
9 changed files with 144 additions and 47 deletions

View file

@ -3,8 +3,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
<TargetFramework>netstandard1.5</TargetFramework>
</PropertyGroup>
<ItemGroup>
@ -13,5 +12,15 @@
<None Include="project.json" />
</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" />
</Project>

View file

@ -3,8 +3,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
<TargetFramework>netstandard1.5</TargetFramework>
</PropertyGroup>
<ItemGroup>
@ -13,5 +12,15 @@
<None Include="project.json" />
</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" />
</Project>

View file

@ -3,8 +3,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
<TargetFramework>netstandard1.5</TargetFramework>
</PropertyGroup>
<ItemGroup>
@ -13,5 +12,15 @@
<None Include="project.json" />
</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" />
</Project>

View file

@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
using TestLibrary;
namespace TestApp
{
@ -11,6 +12,7 @@ namespace TestApp
public static int Main(string[] args)
{
Console.WriteLine("This string came from ProjectA");
Console.WriteLine($"{ProjectD.GetMessage()}");
return 0;
}
}

View file

@ -17,6 +17,19 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{
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)
{
var projectContexts = ProjectContext.CreateContextForEachFramework(projectDir);
@ -31,20 +44,37 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return ResolveProjectDependencies(projectContexts, ResolveXProjProjectDependencyNames(xproj));
}
public IEnumerable<ProjectDependency> ResolveProjectDependencies(
IEnumerable<ProjectContext> projectContexts,
IEnumerable<string> preResolvedProjects = null)
public IEnumerable<ProjectDependency> ResolveAllProjectDependenciesForFramework(
ProjectDependency projectToResolve,
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,
NuGetFramework framework,
IEnumerable<string> preResolvedProjects=null)
@ -98,7 +128,37 @@ namespace Microsoft.DotNet.ProjectJsonMigration
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>();
@ -144,34 +204,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration
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)
{
var projectRootDirectory = GetRootFromProjectJson(projectJsonFilePath);

View file

@ -244,7 +244,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes());
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
PathUtility.GetPathWithDirectorySeparator(p))));
var projectDependencies = _projectDependencyFinder.ResolveProjectDependenciesForFramework(
var projectDependencies = _projectDependencyFinder.ResolveDirectProjectDependenciesForFramework(
project,
framework,
preResolvedProjects: migratedXProjDependencyNames);

View file

@ -30,8 +30,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
_projectDirectory = migrationSettings.ProjectDirectory;
var migratedXProjDependencyPaths = MigrateXProjProjectDependencies(migrationRuleInputs);
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
PathUtility.GetPathWithDirectorySeparator(p))));
var migratedXProjDependencyNames = new HashSet<string>(
migratedXProjDependencyPaths.Select(p =>
Path.GetFileNameWithoutExtension(PathUtility.GetPathWithDirectorySeparator(p))));
MigrateProjectJsonProjectDependencies(
migrationRuleInputs.ProjectContexts,
migratedXProjDependencyNames,
@ -104,8 +105,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
HashSet<string> migratedXProjDependencyNames,
ProjectRootElement outputMSBuildProject)
{
var projectDependencies = _projectDependencyFinder.ResolveProjectDependenciesForFramework(
project,
var projectDependencies = _projectDependencyFinder.ResolveAllProjectDependenciesForFramework(
new ProjectDependency(project.Name, project.ProjectFilePath),
framework,
migratedXProjDependencyNames);

View file

@ -238,5 +238,25 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
migratedProjectReferenceItem.Include.Should().Be(projectReference);
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);
}
}
}

View file

@ -375,6 +375,21 @@ namespace Microsoft.DotNet.Migration.Tests
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)
{
if (projectName != null)