Ejemplo n.º 1
0
        /// <summary>
        /// Expand (recursively) set of active targets to include targets which reference any
        /// of the active targets with BeforeTarget or AfterTarget.
        /// </summary>
        /// <param name="projectInstance">An MSBuild Project instance to use for context.</param>
        /// <param name="activeTargets">
        /// Set of active targets. Will be modified in place to add targets that reference this
        /// graph with BeforeTarget or AfterTarget.
        /// </param>
        public static void AddBeforeAndAfterTargets(this ProjectInstance projectInstance, Dictionary <string, ProjectTargetInstance> activeTargets)
        {
            var newTargetsToConsider = true;

            while (newTargetsToConsider)
            {
                newTargetsToConsider = false;

                foreach (KeyValuePair <string, ProjectTargetInstance> pair in projectInstance.Targets)
                {
                    string targetName = pair.Key;
                    ProjectTargetInstance targetInstance = pair.Value;

                    // If the target is not already in our list of active targets ...
                    if (!activeTargets.ContainsKey(targetName))
                    {
                        IEnumerable <string> hookedTargets = projectInstance.EvaluateValue(targetInstance.AfterTargets)
                                                             .Concat(projectInstance.EvaluateValue(targetInstance.BeforeTargets));
                        foreach (string hookedTarget in hookedTargets)
                        {
                            // ... and it hooks a running target with BeforeTargets/AfterTargets ...
                            if (activeTargets.ContainsKey(hookedTarget))
                            {
                                // ... then add it to the list of running targets ...
                                projectInstance.AddToActiveTargets(targetName, activeTargets);

                                // ... and make a note to run again, since activeTargets has changed.
                                newTargetsToConsider = true;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Given a target name, gets set of targets that are to be executed,
        /// for the provided target name and all targets that those depend on.
        /// </summary>
        /// <param name="projectInstance">An MSBuild Project instance to use for context.</param>
        /// <param name="evaluatedTargetName">Evaluated target name that we should analyze.</param>
        /// <param name="activeTargets">Collection into which targets should be added.</param>
        public static void AddToActiveTargets(
            this ProjectInstance projectInstance,
            string evaluatedTargetName,
            Dictionary <string, ProjectTargetInstance> activeTargets)
        {
            // Avoid circular dependencies
            if (activeTargets.ContainsKey(evaluatedTargetName))
            {
                return;
            }

            // The Project or its includes might not actually include the target name.
            if (projectInstance.Targets.TryGetValue(evaluatedTargetName, out ProjectTargetInstance target))
            {
                activeTargets.Add(evaluatedTargetName, target);

                // Parse all parent targets that current target depends on.
                var dependsOnTargets = projectInstance.EvaluateValue(target.DependsOnTargets);
                foreach (string dependsOnTarget in dependsOnTargets)
                {
                    AddToActiveTargets(projectInstance, dependsOnTarget, activeTargets);
                }
            }
        }