예제 #1
0
        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);
        }
예제 #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}"))
                        .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);
        }
예제 #3
0
        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);
        }