Address PR Feedback

This commit is contained in:
Sridhar Periyasamy 2016-09-23 14:48:54 -07:00
parent b0565e6498
commit d43ade9629
3 changed files with 68 additions and 41 deletions

View file

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Build.Construction;
using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
@ -14,18 +15,32 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{ {
public class ProjectDependencyFinder public class ProjectDependencyFinder
{ {
public IEnumerable<ProjectDependency> ResolveProjectDependencies(IEnumerable<ProjectContext> projectContexts) public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null)
{
var projectContexts = ProjectContext.CreateContextForEachFramework(projectDir);
xprojFile = xprojFile ?? FindXprojFile(projectDir);
ProjectRootElement xproj = null;
if (xprojFile != null)
{
xproj = ProjectRootElement.Open(xprojFile);
}
return ResolveProjectDependencies(projectContexts, ResolveXProjProjectDependencyNames(xproj));
}
public IEnumerable<ProjectDependency> ResolveProjectDependencies(IEnumerable<ProjectContext> projectContexts, IEnumerable<string> preResolvedProjects=null)
{ {
foreach(var projectContext in projectContexts) foreach(var projectContext in projectContexts)
{ {
foreach(var projectDependency in ResolveProjectDependencies(projectContext)) foreach(var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects))
{ {
yield return projectDependency; yield return projectDependency;
} }
} }
} }
public IEnumerable<ProjectDependency> ResolveProjectDependencies(ProjectContext projectContext, HashSet<string> preResolvedProjects=null) public IEnumerable<ProjectDependency> ResolveProjectDependencies(ProjectContext projectContext, IEnumerable<string> preResolvedProjects=null)
{ {
preResolvedProjects = preResolvedProjects ?? new HashSet<string>(); preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
@ -59,6 +74,40 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return projectDependencies; return projectDependencies;
} }
private IEnumerable<string> ResolveXProjProjectDependencyNames(ProjectRootElement xproj)
{
var xprojDependencies = ResolveXProjProjectDependencies(xproj).SelectMany(r => r.Includes());
return new HashSet<string>(xprojDependencies.Select(p => Path.GetFileNameWithoutExtension(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);

View file

@ -40,14 +40,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
MigrateHelper(rootSettings); MigrateProject(rootSettings);
if (skipProjectReferences) if (skipProjectReferences)
{ {
return; return;
} }
var projectDependencies = ResolveTransitiveClosureProjectDependencies(rootSettings.ProjectDirectory); var projectDependencies = ResolveTransitiveClosureProjectDependencies(rootSettings.ProjectDirectory, rootSettings.ProjectXProjFilePath);
foreach(var project in projectDependencies) foreach(var project in projectDependencies)
{ {
@ -56,15 +56,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
projectDir, projectDir,
rootSettings.SdkPackageVersion, rootSettings.SdkPackageVersion,
rootSettings.MSBuildProjectTemplate); rootSettings.MSBuildProjectTemplate);
MigrateHelper(settings); MigrateProject(settings);
} }
} }
private IEnumerable<ProjectDependency> ResolveTransitiveClosureProjectDependencies(string rootProject) private IEnumerable<ProjectDependency> ResolveTransitiveClosureProjectDependencies(string rootProject, string xprojFile)
{ {
HashSet<ProjectDependency> projectsMap = new HashSet<ProjectDependency>(new ProjectDependencyComparer()); HashSet<ProjectDependency> projectsMap = new HashSet<ProjectDependency>(new ProjectDependencyComparer());
var projectContexts = ProjectContext.CreateContextForEachFramework(rootProject); var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile);
var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectContexts);
Queue<ProjectDependency> projectsQueue = new Queue<ProjectDependency>(projectDependencies); Queue<ProjectDependency> projectsQueue = new Queue<ProjectDependency>(projectDependencies);
while(projectsQueue.Count() != 0) while(projectsQueue.Count() != 0)
@ -78,8 +77,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration
projectsMap.Add(projectDependency); projectsMap.Add(projectDependency);
projectContexts = ProjectContext.CreateContextForEachFramework(projectDependency.ProjectFilePath); var projectDir = Path.GetDirectoryName(projectDependency.ProjectFilePath);
projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectContexts); projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectDir);
foreach(var project in projectDependencies) foreach(var project in projectDependencies)
{ {
@ -90,13 +89,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return projectsMap; return projectsMap;
} }
private void MigrateHelper(MigrationSettings migrationSettings) private void MigrateProject(MigrationSettings migrationSettings)
{ {
var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings); var migrationRuleInputs = ComputeMigrationRuleInputs(migrationSettings);
if (IsMigrated(migrationSettings, migrationRuleInputs)) if (IsMigrated(migrationSettings, migrationRuleInputs))
{ {
// TODO : Adding user-visible logging // TODO : Adding user-visible logging
MigrationTrace.Instance.WriteLine($"{nameof(ProjectMigrator)}: Skip migrating {migrationSettings.ProjectDirectory}, it is already migrated.");
return; return;
} }
@ -110,7 +110,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
private MigrationRuleInputs ComputeMigrationRuleInputs(MigrationSettings migrationSettings) private MigrationRuleInputs ComputeMigrationRuleInputs(MigrationSettings migrationSettings)
{ {
var projectContexts = ProjectContext.CreateContextForEachFramework(migrationSettings.ProjectDirectory); var projectContexts = ProjectContext.CreateContextForEachFramework(migrationSettings.ProjectDirectory);
var xprojFile = migrationSettings.ProjectXProjFilePath ?? FindXprojFile(migrationSettings.ProjectDirectory); var xprojFile = migrationSettings.ProjectXProjFilePath ?? _projectDependencyFinder.FindXprojFile(migrationSettings.ProjectDirectory);
ProjectRootElement xproj = null; ProjectRootElement xproj = null;
if (xprojFile != null) if (xprojFile != null)
@ -130,20 +130,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return new MigrationRuleInputs(projectContexts, templateMSBuildProject, itemGroup, propertyGroup, xproj); return new MigrationRuleInputs(projectContexts, templateMSBuildProject, itemGroup, propertyGroup, xproj);
} }
private 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 void VerifyInputs(MigrationRuleInputs migrationRuleInputs, MigrationSettings migrationSettings) private void VerifyInputs(MigrationRuleInputs migrationRuleInputs, MigrationSettings migrationSettings)
{ {
VerifyProject(migrationRuleInputs.ProjectContexts, migrationSettings.ProjectDirectory); VerifyProject(migrationRuleInputs.ProjectContexts, migrationSettings.ProjectDirectory);

View file

@ -30,7 +30,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{ {
_projectDirectory = migrationSettings.ProjectDirectory; _projectDirectory = migrationSettings.ProjectDirectory;
var migratedXProjDependencyPaths = MigrateXProjProjectDependencies(migrationSettings, migrationRuleInputs); var migratedXProjDependencyPaths = MigrateXProjProjectDependencies(migrationRuleInputs);
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(p))); var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(p)));
AddPropertyTransformsToCommonPropertyGroup(migrationRuleInputs.CommonPropertyGroup); AddPropertyTransformsToCommonPropertyGroup(migrationRuleInputs.CommonPropertyGroup);
@ -40,23 +40,17 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
migrationRuleInputs.OutputMSBuildProject); migrationRuleInputs.OutputMSBuildProject);
} }
private IEnumerable<string> MigrateXProjProjectDependencies(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs) private IEnumerable<string> MigrateXProjProjectDependencies(MigrationRuleInputs migrationRuleInputs)
{ {
var xproj = migrationRuleInputs.ProjectXproj; var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(migrationRuleInputs.ProjectXproj);
if (xproj == null)
if (!csprojReferenceItems.Any())
{ {
MigrationTrace.Instance.WriteLine($"{nameof(MigrateProjectDependenciesRule)}: No xproj file given.");
return Enumerable.Empty<string>(); return Enumerable.Empty<string>();
} }
var csprojTransformedReferences = new List<ProjectItemElement>(); var csprojTransformedReferences = new List<ProjectItemElement>();
var csprojReferenceItems = xproj.Items
.Where(i => i.ItemType == "ProjectReference")
.Where(p =>
p.Includes().Any(
include => string.Equals(Path.GetExtension(include), ".csproj", StringComparison.OrdinalIgnoreCase)));
foreach (var csprojReferenceItem in csprojReferenceItems) foreach (var csprojReferenceItem in csprojReferenceItems)
{ {
var conditionChain = csprojReferenceItem.ConditionChain(); var conditionChain = csprojReferenceItem.ConditionChain();
@ -72,7 +66,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
csprojTransformedReferences.Add(transformItem); csprojTransformedReferences.Add(transformItem);
} }
MigrationTrace.Instance.WriteLine($"{nameof(MigrateProjectDependenciesRule)}: Migrating {csprojTransformedReferences.Count()} xproj to csproj references"); MigrationTrace.Instance.WriteLine($"{nameof(MigrateProjectDependenciesRule)}: Migrating {csprojTransformedReferences.Count()} xproj to csproj references");
foreach (var csprojTransformedReference in csprojTransformedReferences) foreach (var csprojTransformedReference in csprojTransformedReferences)
@ -91,7 +84,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
foreach (var projectContext in projectContexts) foreach (var projectContext in projectContexts)
{ {
var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectContext, migratedXProjDependencyNames); var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectContext, migratedXProjDependencyNames);
var projectExports = projectContext.CreateExporter("_").GetDependencies();
var projectDependencyTransformResults = projectDependencies.Select(p => ProjectDependencyTransform.Transform(p)); var projectDependencyTransformResults = projectDependencies.Select(p => ProjectDependencyTransform.Transform(p));