private bool MergeSolutionBuilds(ISet<EquatableEdge<IBuilder>> graph)
{
log.Debug("### Merging solution builds");
// Searching for [MSBuildRunner] -> [SlnBuilder] -> [ISlnProjectBuilder*] patterns
var patterns =
graph
.Where(edge => edge.Source is MSBuildRunner && edge.Target is SlnBuilder)
.ToDictionary(
edge => (SlnBuilder)edge.Target,
edge => new SolutionBuildPattern(graph, (MSBuildRunner)edge.Source, (SlnBuilder)edge.Target));
foreach (var edge in graph)
{
if (edge.Source is SlnBuilder && edge.Target is ISlnProjectBuilder)
{
SolutionBuildPattern pattern;
if (patterns.TryGetValue((SlnBuilder)edge.Source, out pattern))
{
var targetBuilder = (ISlnProjectBuilder)edge.Target;
pattern.ProjectBuilders.Add(targetBuilder);
pattern.Projects.Add(targetBuilder.Project);
}
}
}
// Finding involved modules
var modules = new HashSet<Module>();
var projects = new HashSet<Project>();
foreach (var pattern in patterns.Values)
{
foreach (var prj in pattern.ProjectBuilders)
{
projects.Add(prj.Project);
modules.Add(prj.Project.Module);
}
}
// Creating merge plan
foreach (var module in modules)
{
bool testsCovered = module.TestProjects.Any() && module.TestProjects.All(projects.Contains);
bool covered = module.Projects.Any() && module.Projects.All(projects.Contains);
if (covered)
{
log.DebugFormat("Merging project builders of module {0} into a single solution", module.Name);
MergeProjects(graph, patterns, module.Projects.ToArray(), module.Name);
}
if (testsCovered)
{
log.DebugFormat("Merging test project builders of module {0} into a single solution", module.Name);
MergeProjects(graph, patterns, module.TestProjects.Cast<Project>().ToArray(), module.Name + " tests");
}
}
return true;
}