Analyze repository build order from AnalyzeBuildGraph

This commit is contained in:
Nate McMaster 2017-09-15 11:12:02 -07:00
parent 8f25a559a5
commit 8276bd163e
3 changed files with 78 additions and 5 deletions

View File

@ -5,9 +5,11 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Threading;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using RepoTools.BuildGraph;
using RepoTasks.ProjectModel;
using RepoTasks.Utilities;
@ -26,6 +28,8 @@ namespace RepoTasks
[Required]
public string Properties { get; set; }
public string StartGraphAt { get; set; }
/// <summary>
/// New packages we are compiling. Used in the pin tool.
/// </summary>
@ -58,7 +62,21 @@ namespace RepoTasks
return false;
}
PackagesProduced = solutions
EnsureConsistentGraph(solutions);
PackagesProduced = GetPackagesProduced(solutions);
RepositoryBuildOrder = GetRepositoryBuildOrder(solutions.Where(s => s.ShouldBuild));
return !Log.HasLoggedErrors;
}
private void EnsureConsistentGraph(IEnumerable<SolutionInfo> solutions)
{
// TODO
}
private ITaskItem[] GetPackagesProduced(IEnumerable<SolutionInfo> solutions)
{
return solutions
.Where(s => s.ShouldBuild)
.SelectMany(p => p.Projects)
.Where(p => p.IsPackable)
@ -67,8 +85,63 @@ namespace RepoTasks
["Version"] = p.PackageVersion
}))
.ToArray();
}
return !Log.HasLoggedErrors;
private ITaskItem[] GetRepositoryBuildOrder(IEnumerable<SolutionInfo> solutions)
{
var repositories = solutions.Select(s =>
{
var repoName = Path.GetFileName(Path.GetDirectoryName(s.FullPath));
var repo = new Repository(repoName);
repo.Projects = s.Projects
.Where(p => p.IsPackable)
.Select(p =>
new Project(p.PackageId)
{
Repository = repo,
PackageReferences = new HashSet<string>(p.Frameworks.SelectMany(f => f.Dependencies.Keys), StringComparer.OrdinalIgnoreCase),
})
.ToList();
repo.SupportProjects = s.Projects
.Where(p => !p.IsPackable)
.Select(p =>
new Project(p.PackageId)
{
Repository = repo,
PackageReferences = new HashSet<string>(p.Frameworks.SelectMany(f => f.Dependencies.Keys), StringComparer.OrdinalIgnoreCase),
})
.ToList();
return repo;
}).ToList();
var graph = GraphBuilder.Generate(repositories, StartGraphAt, Log);
var repositoriesWithOrder = new List<(ITaskItem repository, int order)>();
foreach (var repository in repositories)
{
var graphNodeRepository = graph.FirstOrDefault(g => g.Repository.Name == repository.Name);
if (graphNodeRepository == null)
{
// StartGraphAt was specified so the graph is incomplete.
continue;
}
var order = TopologicalSort.GetOrder(graphNodeRepository);
var repositoryTaskItem = new TaskItem(repository.Name);
repositoryTaskItem.SetMetadata("Order", order.ToString());
repositoriesWithOrder.Add((repositoryTaskItem, order));
}
Log.LogMessage(MessageImportance.High, "Repository build order:");
foreach (var buildGroup in repositoriesWithOrder.GroupBy(r => r.order).OrderBy(g => g.Key))
{
var buildGroupRepos = buildGroup.Select(b => b.repository.ItemSpec);
Log.LogMessage(MessageImportance.High, $"{buildGroup.Key.ToString().PadLeft(2, ' ')}: {string.Join(", ", buildGroupRepos)}");
}
return repositoriesWithOrder
.OrderBy(r => r.order)
.Select(r => r.repository)
.ToArray();
}
}
}

View File

@ -23,6 +23,6 @@ namespace RepoTools.BuildGraph
public Repository Repository { get; set; }
public ISet<string> PackageReferences { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
public ISet<string> PackageReferences { get; set; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
}
}

View File

@ -22,9 +22,9 @@ namespace RepoTools.BuildGraph
public string Name { get; private set; }
public IList<Project> Projects { get; } = new List<Project>();
public IList<Project> Projects { get; set; } = new List<Project>();
public IList<Project> SupportProjects { get; } = new List<Project>();
public IList<Project> SupportProjects { get; set; } = new List<Project>();
public IEnumerable<Project> AllProjects => Projects.Concat(SupportProjects);