Beispiel #1
0
        /// <summary>
        /// Simulates callback. Access the configuration for the primary project. Retrieve the test test data definition.
        /// Get the child definitions if available and simulate a callback for each of the child definitions. Note that the
        /// targets to build parameter is the same for all the projects - that is we instruct to build the same set of targets
        /// for all of the projects. Thus the child test definitions of the entry should have the same set of targets available
        /// or a common set of targets available
        /// </summary>
        private void SimulateCallBacks()
        {
            if (_testDefinition.ChildDefinitions == null || _testDefinition.ChildDefinitions.Count < 1)
            {
                return;
            }

            int count = _testDefinition.ChildDefinitions.Count;

            string[] projectFiles = new string[count];
            PropertyDictionary <ProjectPropertyInstance>[] properties = new PropertyDictionary <ProjectPropertyInstance> [count];
            string[] toolsVersions  = new string[count];
            string[] targetsToBuild = null;

            count = 0;
            foreach (RequestDefinition d in _testDefinition.ChildDefinitions)
            {
                projectFiles[count]  = d.FileName;
                properties[count]    = d.GlobalProperties;
                toolsVersions[count] = d.ToolsVersion;
                targetsToBuild       = d.TargetsToBuild;
                count++;
            }

            _requestCallBack.BuildProjects(projectFiles, properties, toolsVersions, targetsToBuild, true);
        }
        public Task <BuildResult> BuildTargets(ProjectLoggingContext loggingContext, BuildRequestEntry entry, IRequestBuilderCallback callback, string[] targets, Lookup baseLookup, CancellationToken cancellationToken)
        {
            _requestBuilderCallback = callback;

            if (cancellationToken.WaitHandle.WaitOne(1500))
            {
                BuildResult result = new BuildResult(entry.Request);
                foreach (string target in targets)
                {
                    result.AddResultsForTarget(target, BuildResultUtilities.GetEmptyFailingTargetResult());
                }
                return(Task <BuildResult> .FromResult(result));
            }

            if (_newRequests != null)
            {
                string[] projectFiles = new string[_newRequests.Length];
                PropertyDictionary <ProjectPropertyInstance>[] properties = new PropertyDictionary <ProjectPropertyInstance> [_newRequests.Length];
                string[] toolsVersions = new string[_newRequests.Length];

                for (int i = 0; i < projectFiles.Length; ++i)
                {
                    projectFiles[i]  = _newRequests[i].Config.ProjectFullPath;
                    properties[i]    = new PropertyDictionary <ProjectPropertyInstance>(_newRequests[i].Config.GlobalProperties);
                    toolsVersions[i] = _newRequests[i].Config.ToolsVersion;
                }

                _requestBuilderCallback.BuildProjects(projectFiles, properties, toolsVersions, _newRequests[0].Targets, _newRequests[0].ResultsNeeded);

                if (cancellationToken.WaitHandle.WaitOne(1500))
                {
                    BuildResult result = new BuildResult(entry.Request);
                    foreach (string target in targets)
                    {
                        result.AddResultsForTarget(target, BuildResultUtilities.GetEmptyFailingTargetResult());
                    }
                    return(Task <BuildResult> .FromResult(result));
                }
            }

            return(Task <BuildResult> .FromResult(_cache.GetResultForRequest(entry.Request)));
        }
 /// <summary>
 /// Forwarding implementation of BuildProjects
 /// </summary>
 async Task <BuildResult[]> IRequestBuilderCallback.BuildProjects(string[] projectFiles, Microsoft.Build.Collections.PropertyDictionary <ProjectPropertyInstance>[] properties, string[] toolsVersions, string[] targets, bool waitForResults, bool skipNonexistentTargets)
 {
     return(await _requestBuilderCallback.BuildProjects(projectFiles, properties, toolsVersions, targets, waitForResults, skipNonexistentTargets));
 }
Beispiel #4
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));
            }
        }
        public Task<BuildResult> BuildTargets(ProjectLoggingContext loggingContext, BuildRequestEntry entry, IRequestBuilderCallback callback, string[] targets, Lookup baseLookup, CancellationToken cancellationToken)
        {
            _requestBuilderCallback = callback;

            if (cancellationToken.WaitHandle.WaitOne(1500, false))
            {
                BuildResult result = new BuildResult(entry.Request);
                foreach (string target in targets)
                {
                    result.AddResultsForTarget(target, TestUtilities.GetEmptyFailingTargetResult());
                }
                return Task<BuildResult>.FromResult(result);
            }

            if (null != _newRequests)
            {
                string[] projectFiles = new string[_newRequests.Length];
                PropertyDictionary<ProjectPropertyInstance>[] properties = new PropertyDictionary<ProjectPropertyInstance>[_newRequests.Length];
                string[] toolsVersions = new string[_newRequests.Length];

                for (int i = 0; i < projectFiles.Length; ++i)
                {
                    projectFiles[i] = _newRequests[i].Config.ProjectFullPath;
                    properties[i] = new PropertyDictionary<ProjectPropertyInstance>(_newRequests[i].Config.Properties);
                    toolsVersions[i] = _newRequests[i].Config.ToolsVersion;
                }

                _requestBuilderCallback.BuildProjects(projectFiles, properties, toolsVersions, _newRequests[0].Targets, _newRequests[0].ResultsNeeded);

                if (cancellationToken.WaitHandle.WaitOne(1500, false))
                {
                    BuildResult result = new BuildResult(entry.Request);
                    foreach (string target in targets)
                    {
                        result.AddResultsForTarget(target, TestUtilities.GetEmptyFailingTargetResult());
                    }
                    return Task<BuildResult>.FromResult(result);
                }
            }

            return Task<BuildResult>.FromResult(_cache.GetResultForRequest(entry.Request));
        }