Esempio n. 1
0
        /// <summary>
        /// Suspends full tracking.
        /// </summary>
        /// <returns>An object that will resume full tracking when disposed.</returns>
        internal static IDisposable Suspend()
        {
            FullTracking tracking = new FullTracking();

            if (tracking._trackingMode == TrackingMode.Active)
            {
                InprocTrackingNativeMethods.SuspendTracking();
                tracking._trackingMode = TrackingMode.Suspended;
            }

            return(tracking);
        }
Esempio n. 2
0
        /// <summary>
        /// Starts full tracking.
        /// </summary>
        /// <param name="targetName">taskLoggingContext.TargetLoggingContext.Target.Name</param>
        /// <param name="taskName">taskNode.Name</param>
        /// <param name="projectRootDirectory">buildRequestEntry.ProjectRootDirectory</param>
        /// <param name="projectProperties">buildRequestEntry.RequestConfiguration.Project.PropertiesToBuildWith</param>
        /// <returns>
        /// An object that will stop full tracking when disposed.
        /// </returns>
        internal static IDisposable Track(string targetName, string taskName, string projectRootDirectory, PropertyDictionary <ProjectPropertyInstance> projectProperties)
        {
            FullTracking tracking = new FullTracking();

            ProjectPropertyInstance tlogRelativeDirectoryProperty = projectProperties[FullTrackingDirectoryPropertyName];
            string tlogRelativeDirectoryValue = null;

            if (tlogRelativeDirectoryProperty != null)
            {
                tlogRelativeDirectoryValue = tlogRelativeDirectoryProperty.EvaluatedValue;
            }

            if (!String.IsNullOrEmpty(tlogRelativeDirectoryValue))
            {
                tracking._taskName      = GenerateUniqueTaskName(targetName, taskName);
                tracking._tlogDirectory = Path.Combine(projectRootDirectory, tlogRelativeDirectoryValue);
                InprocTrackingNativeMethods.StartTrackingContext(tracking._tlogDirectory, tracking._taskName);
                tracking._trackingMode = TrackingMode.Active;
            }

            return(tracking);
        }
Esempio n. 3
0
        /// <summary>
        /// Async version of BuildProjectFilesInParallel.
        /// </summary>
        /// <param name="projectFileNames">The list of projects to build</param>
        /// <param name="targetNames">The set of targets to build</param>
        /// <param name="globalProperties">The global properties to use for each project</param>
        /// <param name="undefineProperties">The list of global properties to undefine</param>
        /// <param name="toolsVersion">The tools versions to use</param>
        /// <param name="returnTargetOutputs">Should the target outputs be returned in the BuildEngineResult</param>
        /// <param name="skipNonexistentTargets">If set, skip targets that are not defined in the projects to be built.</param>
        /// <returns>A Task returning a structure containing the result of the build, success or failure and the list of target outputs per project</returns>
        private async Task <BuildEngineResult> BuildProjectFilesInParallelAsync(string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IList <String>[] undefineProperties, string[] toolsVersion, bool returnTargetOutputs, bool skipNonexistentTargets = false)
        {
            ErrorUtilities.VerifyThrowArgumentNull(projectFileNames, "projectFileNames");
            ErrorUtilities.VerifyThrowArgumentNull(globalProperties, "globalProperties");
            VerifyActiveProxy();

            List <IDictionary <string, ITaskItem[]> > targetOutputsPerProject = null;

#if FEATURE_FILE_TRACKER
            using (FullTracking.Suspend())
#endif
            {
                bool overallSuccess = true;

                if (projectFileNames.Length == 1 && projectFileNames[0] == null && globalProperties[0] == null && (undefineProperties == null || undefineProperties[0] == null) && toolsVersion[0] == null)
                {
                    // This is really a legacy CallTarget invocation
                    ITargetResult[] results = await _targetBuilderCallback.LegacyCallTarget(targetNames, ContinueOnError, _taskLocation);

                    if (returnTargetOutputs)
                    {
                        targetOutputsPerProject = new List <IDictionary <string, ITaskItem[]> >(1)
                        {
                            new Dictionary <string, ITaskItem[]>(StringComparer.OrdinalIgnoreCase)
                        };
                    }

                    for (int i = 0; i < targetNames.Length; i++)
                    {
                        targetOutputsPerProject[0][targetNames[i]] = results[i].Items;
                        if (results[i].ResultCode == TargetResultCode.Failure)
                        {
                            overallSuccess = false;
                        }
                    }
                }
                else
                {
                    // UNDONE: (Refactor) Investigate making this a ReadOnly collection of some sort.
                    PropertyDictionary <ProjectPropertyInstance>[] propertyDictionaries = new PropertyDictionary <ProjectPropertyInstance> [projectFileNames.Length];

                    for (int i = 0; i < projectFileNames.Length; i++)
                    {
                        // Copy in the original project's global properties
                        propertyDictionaries[i] = new PropertyDictionary <ProjectPropertyInstance>(_requestEntry.RequestConfiguration.Project.GlobalPropertiesDictionary);

                        // Now add/replace any which may have been specified.
                        if (globalProperties[i] != null)
                        {
                            foreach (DictionaryEntry entry in globalProperties[i])
                            {
                                propertyDictionaries[i].Set(ProjectPropertyInstance.Create(entry.Key as string, entry.Value as string, _taskLocation));
                            }
                        }

                        // Finally, remove any which were requested to be removed.
                        if (undefineProperties?[i] != null)
                        {
                            foreach (string property in undefineProperties[i])
                            {
                                propertyDictionaries[i].Remove(property);
                            }
                        }
                    }

                    IRequestBuilderCallback builderCallback = _requestEntry.Builder as IRequestBuilderCallback;
                    BuildResult[]           results         = await builderCallback.BuildProjects(
                        projectFileNames,
                        propertyDictionaries,
                        toolsVersion ?? Array.Empty <string>(),
                        targetNames ?? Array.Empty <string>(),
                        waitForResults : true,
                        skipNonexistentTargets : skipNonexistentTargets);

                    // Even if one of the projects fails to build and therefore has no outputs, it should still have an entry in the results array (albeit with an empty list in it)
                    ErrorUtilities.VerifyThrow(results.Length == projectFileNames.Length, "{0}!={1}.", results.Length, projectFileNames.Length);

                    if (returnTargetOutputs)
                    {
                        targetOutputsPerProject = new List <IDictionary <string, ITaskItem[]> >(results.Length);
                    }

                    // Now walk through the results, and report that subset which was asked for.
                    for (int i = 0; i < results.Length; i++)
                    {
                        if (targetOutputsPerProject != null)
                        {
                            targetOutputsPerProject.Add(new Dictionary <string, ITaskItem[]>(StringComparer.OrdinalIgnoreCase));
                        }

                        foreach (KeyValuePair <string, TargetResult> resultEntry in results[i].ResultsByTarget)
                        {
                            if (targetOutputsPerProject != null)
                            {
                                // We need to clone the task items because if we did not then we would be passing live references
                                // out to the caller of the msbuild callback and any modifications they make to those items
                                // would appear in the results cache.
                                ITaskItem[] clonedTaskItem = new ITaskItem[resultEntry.Value.Items.Length];
                                for (int j = 0; j < resultEntry.Value.Items.Length; j++)
                                {
                                    clonedTaskItem[j] = ((TaskItem)resultEntry.Value.Items[j]).DeepClone();
                                }

                                targetOutputsPerProject[i][resultEntry.Key] = clonedTaskItem;
                            }
                        }

                        if (results[i].OverallResult == BuildResultCode.Failure)
                        {
                            overallSuccess = false;
                        }

                        if (!string.IsNullOrEmpty(results[i].SchedulerInducedError))
                        {
                            LoggingContext.LogErrorFromText(
                                subcategoryResourceName: null,
                                errorCode: null,
                                helpKeyword: null,
                                file: new BuildEventFileInfo(ProjectFileOfTaskNode, LineNumberOfTaskNode, ColumnNumberOfTaskNode),
                                message: results[i].SchedulerInducedError);
                        }
                    }

                    ErrorUtilities.VerifyThrow(results.Length == projectFileNames.Length || overallSuccess == false, "The number of results returned {0} cannot be less than the number of project files {1} unless one of the results indicated failure.", results.Length, projectFileNames.Length);
                }

                BuildRequestsSucceeded = overallSuccess;

                return(new BuildEngineResult(overallSuccess, targetOutputsPerProject));
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Starts full tracking.
        /// </summary>
        /// <param name="targetName">taskLoggingContext.TargetLoggingContext.Target.Name</param>
        /// <param name="taskName">taskNode.Name</param>
        /// <param name="projectRootDirectory">buildRequestEntry.ProjectRootDirectory</param>
        /// <param name="projectProperties">buildRequestEntry.RequestConfiguration.Project.PropertiesToBuildWith</param>
        /// <returns>
        /// An object that will stop full tracking when disposed.
        /// </returns>
        internal static IDisposable Track(string targetName, string taskName, string projectRootDirectory, PropertyDictionary<ProjectPropertyInstance> projectProperties)
        {
            FullTracking tracking = new FullTracking();

            ProjectPropertyInstance tlogRelativeDirectoryProperty = projectProperties[FullTrackingDirectoryPropertyName];
            string tlogRelativeDirectoryValue = null;
            if (tlogRelativeDirectoryProperty != null)
            {
                tlogRelativeDirectoryValue = tlogRelativeDirectoryProperty.EvaluatedValue;
            }

            if (!String.IsNullOrEmpty(tlogRelativeDirectoryValue))
            {
                tracking._taskName = GenerateUniqueTaskName(targetName, taskName);
                tracking._tlogDirectory = Path.Combine(projectRootDirectory, tlogRelativeDirectoryValue);
                InprocTrackingNativeMethods.StartTrackingContext(tracking._tlogDirectory, tracking._taskName);
                tracking._trackingMode = TrackingMode.Active;
            }

            return tracking;
        }
Esempio n. 5
0
        /// <summary>
        /// Suspends full tracking.
        /// </summary>
        /// <returns>An object that will resume full tracking when disposed.</returns>
        internal static IDisposable Suspend()
        {
            FullTracking tracking = new FullTracking();

            if (tracking._trackingMode == TrackingMode.Active)
            {
                InprocTrackingNativeMethods.SuspendTracking();
                tracking._trackingMode = TrackingMode.Suspended;
            }

            return tracking;
        }