Exemple #1
0
        /// <summary>
        /// Executes a specific target.
        /// </summary>
        /// <param name="targetName">The name of the target to execute.</param>
        /// <param name="forceDependencies">Whether dependencies should be forced to execute</param>
        /// <remarks>
        /// Global tasks are not executed.
        /// </remarks>
        public void Execute(string targetName, bool forceDependencies)
        {
            bool singleThreaded = !RunTargetsInParallel;
            if (singleThreaded) {
                // sort the dependency tree, and run everything from the
                // beginning until we hit our targetName.
                //
                // sorting checks if all the targets (and dependencies)
                // exist, and if there is any cycle in the dependency
                // graph.
                TargetCollection sortedTargets = TopologicalTargetSort(targetName, Targets);
                int currentIndex = 0;
                Target currentTarget;

                // store calling target
                Target callingTarget = _currentTarget;

                do {
                    // determine target that should be executed
                    currentTarget = (Target) sortedTargets[currentIndex++];

                    // store target that will be executed
                    _currentTarget = currentTarget;

                    // only execute targets that have not been executed already, if
                    // we are not forcing.
                    if (forceDependencies || !currentTarget.Executed || currentTarget.Name == targetName) {
                        currentTarget.Execute();
                    }
                } while (currentTarget.Name != targetName);

                // restore calling target, as a <call> task might have caused the
                // current target to be executed and when finished executing this
                // target, the target that contained the <call> task should be
                // considered the current target again
                _currentTarget = callingTarget;
            }
            else {
                // sorting checks if all the targets (and dependencies)
                // exist, and if there is any cycle in the dependency
                // graph.
                TopologicalTargetSort (targetName, Targets);

                // Dictionary is faster than implementation in TargetCollection.Find
                System.Collections.Generic.Dictionary<string, Target> targets = new System.Collections.Generic.Dictionary<string, Target>();
                foreach (Target target in Targets) {
                    targets [target.Name] = target;
                }

                // Use execution graph to run targets in parallel
                using (ExecutionGraph graph = new ExecutionGraph()) {

                    PopulateExecutionGraph(targetName, Targets, graph);
                    graph.WalkThrough(delegate(string currentTargetName) {

                        Target currentTarget;
                        if (!targets.TryGetValue(currentTargetName, out currentTarget)) {
                            Target wildcardTarget = targets [WildTarget];
                            currentTarget = wildcardTarget.Clone ();
                            currentTarget.Name = targetName;
                        }

                        Target savedTarget = _currentTarget;
                        _currentTarget = currentTarget;

                        try {
                            lock (currentTarget) {
                                if (forceDependencies || !currentTarget.Executed || currentTarget.Name == targetName) {
                                    currentTarget.Execute ();
                                }
                            }
                        } finally {
                            _currentTarget = savedTarget;
                        }
                    }
                    );
                }
            }
        }