public ISet<TargetRelativePath> Run(IBuilder rootBuilder = null, Func<IBuilder, bool> filter = null)
{
var result = new HashSet<TargetRelativePath>();
partialResults.Clear();
var cancel = RunTransformations();
if (!cancel)
{
var graph = builders.ToAdjacencyGraph<IBuilder, EquatableEdge<IBuilder>>();
graph.RemoveEdgeIf(edge => edge.IsSelfEdge<IBuilder, EquatableEdge<IBuilder>>());
if (rootBuilder != null)
RemoveIrrelevantBranches(graph, rootBuilder);
if (!HasCycles(graph))
{
var sortedBuilders = graph.TopologicalSort().Reverse().ToList();
log.DebugFormat("Build order:\n {0}\n", String.Join("\n ", sortedBuilders));
var statistics = createBuilderStatistics();
foreach (var builder in sortedBuilders)
{
if (filter == null || filter(builder))
{
log.DebugFormat("===> {0}", builder);
var wrappedBuilder = WrapBuilder(builder, statistics);
var builderResult = wrappedBuilder.Run(this);
log.DebugFormat("Storing results of {0}: {1}", builder, String.Join(", ", builderResult));
partialResults.Add(builder, builderResult);
result.UnionWith(builderResult);
}
}
statistics.Dump();
}
else
{
log.ErrorFormat("Build graph has cycle");
result.Clear();
}
}
else
{
log.DebugFormat("Build cancelled by graph transformation");
result.Clear();
}
return result;
}