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 factoryDependencies = executingTargets.SelectMany(x => x.FactoryDependencies); var nameDependencies = executingTargets.SelectMany(x => x.NamedDependencies); if (!invokedTargets.Contains(targetDefinition) && !(factoryDependencies.Contains(targetDefinition.Factory) || nameDependencies.Contains(targetDefinition.Name))) { 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}")) .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 executableDependency = result.SelectMany(x => x.TargetDefinitionDependencies).Contains(targetDefinition) && !EnvironmentInfo.ArgumentSwitch("nodeps"); if (specifiedTargets.Contains(targetDefinition) || executableDependency) { result.Add(targetDefinition); } } result.Reverse(); return(result); }
private static IReadOnlyCollection <ExecutableTarget> GetExecutionPlanInternal( IReadOnlyCollection <ExecutableTarget> executableTargets, ICollection <ExecutableTarget> invokedTargets) { var vertexDictionary = GetVertexDictionary(executableTargets); var graphAsList = vertexDictionary.Values.ToList(); var executingTargets = new List <ExecutableTarget>(); 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 <ExecutableTarget>(); 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 executableTarget = independent.Value; if (!invokedTargets.Contains(executableTarget) && !executingTargets.SelectMany(x => x.ExecutionDependencies).Contains(executableTarget)) { continue; } executingTargets.Add(executableTarget); } executingTargets.Reverse(); return(executingTargets); }