Marking hoisted P2P projects with a FromP2P attribute. (#4598)

This commit is contained in:
Livar 2016-11-03 10:27:51 -07:00 committed by Piotr Puszkiewicz
parent 016a88b52a
commit de5da5870f
4 changed files with 103 additions and 23 deletions

View file

@ -7,11 +7,25 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{
public string Name { get; }
public string ProjectFilePath { get; }
public bool Hoisted { get; }
public ProjectDependency(string name, string projectFilePath)
public ProjectDependency(string name, string projectFilePath, bool hoisted)
{
Name = name;
ProjectFilePath = System.IO.Path.GetFullPath(projectFilePath);
Hoisted = hoisted;
}
public override bool Equals(object obj)
{
var other = obj as ProjectDependency;
return other != null && other.ProjectFilePath == ProjectFilePath;
}
public override int GetHashCode()
{
return ProjectFilePath.GetHashCode();
}
}
}

View file

@ -50,7 +50,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
IEnumerable<string> preResolvedProjects=null)
{
var projects = new List<ProjectDependency> { projectToResolve };
var allDependencies = new List<ProjectDependency>();
var allDependencies = new HashSet<ProjectDependency>();
while (projects.Count > 0)
{
var project = projects.First();
@ -65,24 +65,33 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var dependencies = ResolveDirectProjectDependenciesForFramework(
projectContext.ProjectFile,
framework,
preResolvedProjects
preResolvedProjects,
HoistDependenciesThatAreNotDirectDependencies(projectToResolve, project)
);
projects.AddRange(dependencies);
allDependencies.AddRange(dependencies);
allDependencies.UnionWith(dependencies);
}
return allDependencies;
}
private bool HoistDependenciesThatAreNotDirectDependencies(
ProjectDependency originalProject,
ProjectDependency dependenciesOwner)
{
return originalProject != dependenciesOwner;
}
public IEnumerable<ProjectDependency> ResolveDirectProjectDependenciesForFramework(
Project project,
NuGetFramework framework,
IEnumerable<string> preResolvedProjects=null)
IEnumerable<string> preResolvedProjects=null,
bool hoistedDependencies = false)
{
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
var possibleProjectDependencies =
FindPossibleProjectDependencies(project.ProjectFilePath);
FindPossibleProjectDependencies(project.ProjectFilePath, hoistedDependencies);
var projectDependencies = new List<ProjectDependency>();
@ -205,7 +214,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration
PathUtility.GetPathWithDirectorySeparator(p))));
}
private Dictionary<string, ProjectDependency> FindPossibleProjectDependencies(string projectJsonFilePath)
private Dictionary<string, ProjectDependency> FindPossibleProjectDependencies(
string projectJsonFilePath,
bool hoistedDependencies = false)
{
var projectRootDirectory = GetRootFromProjectJson(projectJsonFilePath);
@ -217,7 +228,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var projects = new Dictionary<string, ProjectDependency>(StringComparer.Ordinal);
foreach (var project in GetPotentialProjects(projectSearchPaths))
foreach (var project in GetPotentialProjects(projectSearchPaths, hoistedDependencies))
{
if (projects.ContainsKey(project.Name))
{
@ -278,7 +289,9 @@ namespace Microsoft.DotNet.ProjectJsonMigration
/// <summary>
/// Create the list of potential projects from the search paths.
/// </summary>
private static List<ProjectDependency> GetPotentialProjects(IEnumerable<string> searchPaths)
private static List<ProjectDependency> GetPotentialProjects(
IEnumerable<string> searchPaths,
bool hoistedDependencies = false)
{
var projects = new List<ProjectDependency>();
@ -301,7 +314,10 @@ namespace Microsoft.DotNet.ProjectJsonMigration
// Instead, we'll do an exists check when we try to resolve
// Check if we've already added this, just in case it was pre-loaded into the cache
var project = new ProjectDependency(projectDirectory.Name, projectFilePath);
var project = new ProjectDependency(
projectDirectory.Name,
projectFilePath,
hoistedDependencies);
projects.Add(project);
}

View file

@ -106,12 +106,15 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
ProjectRootElement outputMSBuildProject)
{
var projectDependencies = _projectDependencyFinder.ResolveAllProjectDependenciesForFramework(
new ProjectDependency(project.Name, project.ProjectFilePath),
new ProjectDependency(project.Name, project.ProjectFilePath, false),
framework,
migratedXProjDependencyNames);
var projectDependencyTransformResults =
projectDependencies.Select(p => ProjectDependencyTransform.Transform(p));
projectDependencies.Select(p =>
p.Hoisted ?
HoistedDependencyTransform.Transform(p) :
ProjectDependencyTransform.Transform(p));
if (projectDependencyTransformResults.Any())
{
@ -138,18 +141,26 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
}
}
private AddItemTransform<ProjectDependency> ProjectDependencyTransform => new AddItemTransform<ProjectDependency>(
"ProjectReference",
dep =>
{
var projectDir = Path.GetDirectoryName(dep.ProjectFilePath);
var migratedProjectFileName = Path.GetFileName(projectDir) + ".csproj";
var relativeProjectDir = PathUtility.GetRelativePath(_projectDirectory + "/", projectDir);
private AddItemTransform<ProjectDependency> ProjectDependencyTransform =>
GetProjectDependencyTransfrom();
return Path.Combine(relativeProjectDir, migratedProjectFileName);
},
dep => "",
dep => true);
private AddItemTransform<ProjectDependency> HoistedDependencyTransform =>
GetProjectDependencyTransfrom()
.WithMetadata("FromP2P", "true");
private Func<AddItemTransform<ProjectDependency>> GetProjectDependencyTransfrom =>
() => new AddItemTransform<ProjectDependency>(
"ProjectReference",
dep =>
{
var projectDir = Path.GetDirectoryName(dep.ProjectFilePath);
var migratedProjectFileName = Path.GetFileName(projectDir) + ".csproj";
var relativeProjectDir = PathUtility.GetRelativePath(_projectDirectory + "/", projectDir);
return Path.Combine(relativeProjectDir, migratedProjectFileName);
},
dep => "",
dep => true);
private AddItemTransform<string> ProjectDependencyStringTransform => new AddItemTransform<string>(
"ProjectReference",

View file

@ -249,6 +249,45 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Tests
projectReferences.Count().Should().Be(7);
}
[Fact]
public void All_promoted_P2P_references_are_marked_with_a_FromP2P_attribute()
{
var expectedHoistedProjectReferences = new [] {
Path.Combine("..", "ProjectD", "ProjectD.csproj"),
Path.Combine("..", "ProjectE", "ProjectE.csproj"),
Path.Combine("..", "CsprojLibrary1", "CsprojLibrary1.csproj"),
Path.Combine("..", "CsprojLibrary2", "CsprojLibrary2.csproj"),
Path.Combine("..", "CsprojLibrary3", "CsprojLibrary3.csproj")
};
var mockProj = MigrateProject("TestAppDependencyGraph", "ProjectA");
var projectReferences = mockProj.Items
.Where(item =>
item.ItemType == "ProjectReference" && item.GetMetadataWithName("FromP2P") != null)
.Select(i => i.Include);
projectReferences.Should().BeEquivalentTo(expectedHoistedProjectReferences);
}
[Fact]
public void All_non_promoted_P2P_references_are_not_marked_with_a_FromP2P_attribute()
{
var expectedNonHoistedProjectReferences = new [] {
Path.Combine("..", "ProjectB", "ProjectB.csproj"),
Path.Combine("..", "ProjectC", "ProjectC.csproj")
};
var mockProj = MigrateProject("TestAppDependencyGraph", "ProjectA");
var projectReferences = mockProj.Items
.Where(item =>
item.ItemType == "ProjectReference" && item.GetMetadataWithName("FromP2P") == null)
.Select(i => i.Include);
projectReferences.Should().BeEquivalentTo(expectedNonHoistedProjectReferences);
}
[Fact]
public void It_migrates_unqualified_dependencies_as_ProjectReference_when_a_matching_project_is_found()
{