private static List <TargetDefinition> GetUnfilteredExecutingTargets(NukeBuild build, IReadOnlyCollection <TargetDefinition> invokedTargets) { var vertexDictionary = build.TargetDefinitions.ToDictionary(x => x, x => new Vertex <TargetDefinition>(x)); foreach (var pair in vertexDictionary) { pair.Value.Dependencies = pair.Key.TargetDefinitionDependencies.Select(x => vertexDictionary[x]).ToList(); } var graphAsList = vertexDictionary.Values.ToList(); var executingTargets = new List <TargetDefinition>(); while (graphAsList.Any()) { var independents = graphAsList.Where(x => !graphAsList.Any(y => y.Dependencies.Contains(x))).ToList(); if (EnvironmentInfo.ArgumentSwitch("strict") && independents.Count > 1) { ControlFlow.Fail( new[] { "Incomplete target definition order." } .Concat(independents.Select(x => $" - {x.Value.Name}")) .JoinNewLine()); } var independent = independents.FirstOrDefault(); if (independent == null) { var scc = new StronglyConnectedComponentFinder <TargetDefinition>(); var cycles = scc.DetectCycle(graphAsList) .Cycles() .Select(x => string.Join(" -> ", x.Select(y => y.Value.Name))); ControlFlow.Fail( new[] { "Circular dependencies between target definitions." } .Concat(independents.Select(x => $" - {cycles}")) .JoinNewLine()); } graphAsList.Remove(independent); var targetDefinition = independent.Value; var dependencies = executingTargets.SelectMany(x => x.TargetDefinitionDependencies); if (!invokedTargets.Contains(targetDefinition) && !dependencies.Contains(targetDefinition)) { continue; } executingTargets.Add(targetDefinition); } executingTargets.Reverse(); return(executingTargets); }
private static List <TargetDefinition> GetSortedList( IReadOnlyCollection <TargetDefinition> specifiedTargets, IReadOnlyCollection <TargetDefinition> allTargets) { var vertexDictionary = allTargets.ToDictionary(x => x, x => new Vertex <TargetDefinition>(x)); foreach (var pair in vertexDictionary) { pair.Value.Dependencies = pair.Key.TargetDefinitionDependencies.Select(x => vertexDictionary[x]).ToList(); } var graphAsList = vertexDictionary.Values.ToList(); var result = new List <TargetDefinition>(); while (graphAsList.Any()) { var independents = graphAsList.Where(x => !graphAsList.Any(y => y.Dependencies.Contains(x))).ToList(); if (EnvironmentInfo.ArgumentSwitch("strict") && independents.Count > 1) { ControlFlow.Fail( new[] { "Incomplete target definition order." } .Concat(independents.Select(x => $" - {x.Value.Name}")) .Join(Environment.NewLine)); } var independent = independents.FirstOrDefault(); if (independent == null) { var scc = new StronglyConnectedComponentFinder <TargetDefinition>(); var cycles = scc.DetectCycle(graphAsList) .Cycles() .Select(x => string.Join(" -> ", x.Select(y => y.Value.Name))); ControlFlow.Fail( new[] { "Circular dependencies between target definitions." } .Concat(independents.Select(x => $" - {cycles}")) .Join(Environment.NewLine)); } graphAsList.Remove(independent); var targetDefinition = independent.Value; var executableDependency = result.SelectMany(x => x.TargetDefinitionDependencies).Contains(targetDefinition) && !EnvironmentInfo.ArgumentSwitch("nodeps"); if (specifiedTargets.Contains(targetDefinition) || executableDependency) { result.Add(targetDefinition); } } result.Reverse(); return(result); }