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);
        }
Example #2
0
        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);
        }