/// <summary>
        /// Handles the NodeConfiguration packet.
        /// </summary>
        private void HandleNodeConfiguration(NodeConfiguration configuration)
        {
            // Set the culture.
#if FEATURE_CULTUREINFO_SETTERS
            CultureInfo.CurrentCulture   = configuration.BuildParameters.Culture;
            CultureInfo.CurrentUICulture = configuration.BuildParameters.UICulture;
#else
            Thread.CurrentThread.CurrentCulture   = configuration.BuildParameters.Culture;
            Thread.CurrentThread.CurrentUICulture = configuration.BuildParameters.UICulture;
#endif

            // Snapshot the initial environment.
            _savedEnvironment = CommunicationsUtilities.GetEnvironmentVariables();

            // Save the current directory.
            _savedCurrentDirectory = NativeMethodsShared.GetCurrentDirectory();

            // Set the node id.
            _componentHost.BuildParameters.NodeId = configuration.NodeId;
            _shutdownException = null;

#if FEATURE_APPDOMAIN
            // And the AppDomainSetup
            _componentHost.BuildParameters.AppDomainSetup = configuration.AppDomainSetup;
#endif

            // Declare in-proc
            _componentHost.BuildParameters.IsOutOfProc = false;

            // Set the logging exception handler
            ILoggingService loggingService = _componentHost.LoggingService;
            loggingService.OnLoggingThreadException += new LoggingExceptionDelegate(OnLoggingThreadException);

            // Now prep the buildRequestEngine for the build.
            _loggingContext = new NodeLoggingContext(loggingService, configuration.NodeId, true /* inProcNode */);

            _buildRequestEngine.OnEngineException         += _engineExceptionEventHandler;
            _buildRequestEngine.OnNewConfigurationRequest += _newConfigurationRequestEventHandler;
            _buildRequestEngine.OnRequestBlocked          += _requestBlockedEventHandler;
            _buildRequestEngine.OnRequestComplete         += _requestCompleteEventHandler;

            if (_shutdownException != null)
            {
                Exception exception;
                HandleShutdown(out exception);
                throw exception;
            }

            _buildRequestEngine.InitializeForBuild(_loggingContext);

            // Finally store off this configuration packet.
            _currentConfiguration = configuration;
        }
Beispiel #2
0
 /// <summary>
 /// Constructor
 /// </summary>
 internal QAMockHost(GetComponentDelegate getComponentCallback)
 {
     this.buildParameters          = new BuildParameters();
     this.getComponentCallback     = getComponentCallback;
     this.engineStatusChangedEvent = new AutoResetEvent(false);
     this.lastEngineStatus         = BuildRequestEngineStatus.Shutdown;
     this.loggingService           = this;
     this.requestEngine            = null;
     this.testDataProvider         = null;
     this.buildComponents          = new Queue <IBuildComponent>();
     this.legacyThreadingData      = new LegacyThreadingData();
 }
Beispiel #3
0
        /// <summary>
        /// Shuts down the component. First shutdown the request engine. Then shutdown the remaining of the component.
        /// Check if the test data provider exists before shutting it down as it may not have been registered yet because this is also
        /// called in TearDown and teardown is called if an exception is received.
        /// </summary>
        public void ShutdownComponent()
        {
            ShutDownRequestEngine();
            if (this.testDataProvider != null)
            {
                ((IBuildComponent)this.testDataProvider).ShutdownComponent();
            }

            this.buildComponents.Clear();
            this.loggingService = null;
            this.requestEngine  = null;
        }
Beispiel #4
0
        /// <summary>
        /// Shuts down the component. First shutdown the request engine. Then shutdown the remaining of the component.
        /// Check if the test data provider exists before shutting it down as it may not have been registered yet because this is also
        /// called in TearDown and teardown is called if an exception is received.
        /// </summary>
        public void ShutdownComponent()
        {
            ShutDownRequestEngine();
            if (_testDataProvider != null)
            {
                ((IBuildComponent)_testDataProvider).ShutdownComponent();
            }

            _buildComponents.Clear();
            _loggingService = null;
            _requestEngine  = null;
        }
Beispiel #5
0
            /// <summary>
            /// Constructor
            ///
            /// UNDONE: Refactor this, and the other MockHosts, to use a common base implementation.  The duplication of the
            /// logging implementation alone is unfortunate.
            /// </summary>
            public MockHost()
            {
                _buildParameters     = new BuildParameters();
                _legacyThreadingData = new LegacyThreadingData();

                _configCache = new ConfigCache();
                ((IBuildComponent)_configCache).InitializeComponent(this);

                _loggingService = this;

                _resultsCache = new ResultsCache();
                ((IBuildComponent)_resultsCache).InitializeComponent(this);

                _requestBuilder = new RequestBuilder();
                ((IBuildComponent)_requestBuilder).InitializeComponent(this);

                _targetBuilder = new TargetBuilder();
                ((IBuildComponent)_targetBuilder).InitializeComponent(this);

                _sdkResolverService = new MockSdkResolverService();
                ((IBuildComponent)_sdkResolverService).InitializeComponent(this);
            }
Beispiel #6
0
 /// <summary>
 /// Return a task registry for the override tasks in the *.overridetasks file for this toolset         
 /// </summary>
 /// <param name="loggingServices">The logging services used to log during task registration.</param>
 /// <param name="buildEventContext">The build event context used to log during task registration.</param>
 /// <returns>The task registry</returns>
 internal TaskRegistry GetOverrideTaskRegistry(ILoggingService loggingServices, BuildEventContext buildEventContext, ProjectRootElementCache projectRootElementCache)
 {
     RegisterOverrideTasks(loggingServices, buildEventContext, projectRootElementCache);
     return _overrideTaskRegistry;
 }
Beispiel #7
0
 /// <summary>
 /// Return a task registry stub for the tasks in the *.tasks file for this toolset         
 /// </summary>
 /// <param name="loggingServices">The logging services used to log during task registration.</param>
 /// <param name="buildEventContext">The build event context used to log during task registration.</param>
 /// <returns>The task registry</returns>
 internal TaskRegistry GetTaskRegistry(ILoggingService loggingServices, BuildEventContext buildEventContext, ProjectRootElementCache projectRootElementCache)
 {
     RegisterDefaultTasks(loggingServices, buildEventContext, projectRootElementCache);
     return _defaultTaskRegistry;
 }
Beispiel #8
0
        /// <summary>
        /// Given a search path and a task pattern get a list of task or override task files.
        /// </summary>
        internal static string[] GetTaskFiles(DirectoryGetFiles getFiles, ILoggingService loggingServices, BuildEventContext buildEventContext, string taskPattern, string searchPath, string taskFileWarning)
        {
            string[] defaultTasksFiles = { };

            try
            {
                if (null != getFiles)
                {
                    defaultTasksFiles = getFiles(searchPath, taskPattern);
                }
                else
                {
                    // The order of the returned file names is not guaranteed per msdn
                    defaultTasksFiles = Directory.GetFiles(searchPath, taskPattern);
                }

                if (defaultTasksFiles.Length == 0)
                {
                    loggingServices.LogWarning
                        (
                        buildEventContext,
                        null,
                        new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                        taskFileWarning,
                        taskPattern,
                        searchPath,
                        String.Empty
                        );
                }
            }
            catch (Exception e)
            {
                // handle problems when reading the default tasks files
                if (ExceptionHandling.NotExpectedException(e))
                {
                    // Catching Exception, but rethrowing unless it's an IO related exception.
                    throw;
                }

                loggingServices.LogWarning
                    (
                    buildEventContext,
                    null,
                    new BuildEventFileInfo(/* this warning truly does not involve any file */ String.Empty),
                    taskFileWarning,
                    taskPattern,
                    searchPath,
                    e.Message
                    );
            }

            // Sort the file names to give a deterministic order
            Array.Sort<string>(defaultTasksFiles, StringComparer.OrdinalIgnoreCase);
            return defaultTasksFiles;
        }
Beispiel #9
0
        /// <summary>
        /// Do the actual loading of the tasks or override tasks file and register the tasks in the task registry
        /// </summary>
        private void LoadAndRegisterFromTasksFile(string searchPath, string[] defaultTaskFiles, ILoggingService loggingServices, BuildEventContext buildEventContext, string defaultTasksFilePattern, string taskFileError, ProjectRootElementCache projectRootElementCache, TaskRegistry registry)
        {
            foreach (string defaultTasksFile in defaultTaskFiles)
            {
                try
                {
                    // Important to keep the following line since unit tests use the delegate.
                    ProjectRootElement projectRootElement;
                    if (_loadXmlFromPath != null)
                    {
                        XmlDocumentWithLocation defaultTasks = _loadXmlFromPath(defaultTasksFile);
                        projectRootElement = ProjectRootElement.Open(defaultTasks);
                    }
                    else
                    {
                        projectRootElement = ProjectRootElement.Open(defaultTasksFile, projectRootElementCache, false /*The tasks file is not a explicitly loaded file*/);
                    }

                    foreach (ProjectElement elementXml in projectRootElement.Children)
                    {
                        ProjectUsingTaskElement usingTask = elementXml as ProjectUsingTaskElement;

                        if (null == usingTask)
                        {
                            ProjectErrorUtilities.ThrowInvalidProject
                                (
                                elementXml.Location,
                                "UnrecognizedElement",
                                elementXml.XmlElement.Name
                                );
                        }

                        TaskRegistry.RegisterTasksFromUsingTaskElement<ProjectPropertyInstance, ProjectItemInstance>
                            (
                            loggingServices,
                            buildEventContext,
                            Path.GetDirectoryName(defaultTasksFile),
                            usingTask,
                            registry,
                            _expander,
                            ExpanderOptions.ExpandProperties
                            );
                    }
                }
                catch (XmlException e)
                {
                    // handle XML errors in the default tasks file
                    ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false, new BuildEventFileInfo(e), taskFileError, e.Message);
                }
                catch (Exception e)
                {
                    if (ExceptionHandling.NotExpectedException(e))
                    {
                        // Catching Exception, but rethrowing unless it's an IO related exception.
                        throw;
                    }

                    loggingServices.LogError(buildEventContext, new BuildEventFileInfo(defaultTasksFile), taskFileError, e.Message);
                    break;
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Shuts down the component. First shutdown the request engine. Then shutdown the remaining of the component.
        /// Check if the test data provider exists before shutting it down as it may not have been registered yet because this is also
        /// called in TearDown and teardown is called if an exception is received.
        /// </summary>
        public void ShutdownComponent()
        {
            ShutDownRequestEngine();
            if (this.testDataProvider != null)
            {
                ((IBuildComponent)this.testDataProvider).ShutdownComponent();
            }

            this.buildComponents.Clear();
            this.loggingService = null;
            this.requestEngine = null;
        }
Beispiel #11
0
        /// <summary>
        /// Used to load information about MSBuild override tasks i.e. tasks that override tasks declared in tasks or project files.
        /// </summary>
        private void RegisterOverrideTasks(ILoggingService loggingServices, BuildEventContext buildEventContext, ProjectRootElementCache projectRootElementCache)
        {
            if (!_overrideTasksRegistrationAttempted)
            {
                try
                {
                    _overrideTaskRegistry = new TaskRegistry(projectRootElementCache);
                    bool overrideDirectoryExists = false;

                    try
                    {
                        // Make sure the override directory exists and is not empty before trying to find the files
                        if (!String.IsNullOrEmpty(_overrideTasksPath))
                        {
                            if (Path.IsPathRooted(_overrideTasksPath))
                            {
                                if (null != _directoryExists)
                                {
                                    overrideDirectoryExists = _directoryExists(_overrideTasksPath);
                                }
                                else
                                {
                                    overrideDirectoryExists = Directory.Exists(_overrideTasksPath);
                                }
                            }

                            if (!overrideDirectoryExists)
                            {
                                string rootedPathMessage = ResourceUtilities.FormatResourceString("OverrideTaskNotRootedPath", _overrideTasksPath);
                                loggingServices.LogWarning(buildEventContext, null, new BuildEventFileInfo(String.Empty /* this warning truly does not involve any file*/), "OverrideTasksFileFailure", rootedPathMessage);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        if (ExceptionHandling.NotExpectedException(e))
                        {
                            // Catching Exception, but rethrowing unless it's an IO related exception.
                            throw;
                        }

                        string rootedPathMessage = ResourceUtilities.FormatResourceString("OverrideTaskProblemWithPath", _overrideTasksPath, e.Message);
                        loggingServices.LogWarning(buildEventContext, null, new BuildEventFileInfo(String.Empty /* this warning truly does not involve any file*/), "OverrideTasksFileFailure", rootedPathMessage);
                    }

                    if (overrideDirectoryExists)
                    {
                        InitializeProperties(loggingServices, buildEventContext);
                        string[] overrideTasksFiles = GetTaskFiles(_getFiles, loggingServices, buildEventContext, OverrideTasksFilePattern, _overrideTasksPath, "OverrideTasksFileLoadFailureWarning");

                        // Load and register any override tasks
                        LoadAndRegisterFromTasksFile(_overrideTasksPath, overrideTasksFiles, loggingServices, buildEventContext, OverrideTasksFilePattern, "OverrideTasksFileFailure", projectRootElementCache, _overrideTaskRegistry);
                    }
                }
                finally
                {
                    _overrideTasksRegistrationAttempted = true;
                }
            }
        }
Beispiel #12
0
        /// <summary>
        /// Recursively dumps the build information for the specified hierarchy
        /// </summary>
        private void WriteRecursiveSummary(ILoggingService loggingService, BuildEventContext context, int submissionId, SchedulableRequest request, int level, bool useConfigurations, bool isLastChild)
        {
            int postPad = Math.Max(20 /* field width */ - (2 * level) /* spacing for hierarchy lines */ - 3 /* length allocated for config/request id */, 0);

            StringBuilder prePadString = new StringBuilder(2 * level);
            if (level != 0)
            {
                int levelsToPad = level;
                if (isLastChild)
                {
                    levelsToPad--;
                }

                while (levelsToPad > 0)
                {
                    prePadString.Append("| ");
                    levelsToPad--;
                }

                if (isLastChild)
                {
                    prePadString.Append(@". ");
                }
            }

            loggingService.LogComment
            (
                context,
                MessageImportance.Normal,
                "BuildHierarchyEntry",
                prePadString.ToString(),
                useConfigurations ? request.BuildRequest.ConfigurationId : request.BuildRequest.GlobalRequestId,
                new String(' ', postPad),
                String.Format(CultureInfo.InvariantCulture, "{0:0.000}", request.GetTimeSpentInState(SchedulableRequestState.Executing).TotalSeconds),
                String.Format(CultureInfo.InvariantCulture, "{0:0.000}", request.GetTimeSpentInState(SchedulableRequestState.Executing).TotalSeconds + request.GetTimeSpentInState(SchedulableRequestState.Blocked).TotalSeconds + request.GetTimeSpentInState(SchedulableRequestState.Ready).TotalSeconds),
                _configCache[request.BuildRequest.ConfigurationId].ProjectFullPath,
                String.Join(", ", request.BuildRequest.Targets.ToArray())
            );

            List<SchedulableRequest> childRequests = new List<SchedulableRequest>(_schedulingData.GetRequestsByHierarchy(request));
            childRequests.Sort(delegate (SchedulableRequest left, SchedulableRequest right)
            {
                if (left.StartTime < right.StartTime)
                {
                    return -1;
                }
                else if (left.StartTime > right.StartTime)
                {
                    return 1;
                }

                return 0;
            });

            for (int i = 0; i < childRequests.Count; i++)
            {
                SchedulableRequest childRequest = childRequests[i];
                WriteRecursiveSummary(loggingService, context, submissionId, childRequest, level + 1, useConfigurations, i == childRequests.Count - 1);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Writes a single line of node utilization information.
        /// </summary>
        private void WriteNodeUtilizationGraphLine(ILoggingService loggingService, BuildEventContext context, int[] currentWork, int[] previousWork, DateTime currentEventTime, DateTime previousEventTime, int invalidWorkId, ref double accumulatedDuration)
        {
            if (currentEventTime == DateTime.MinValue)
            {
                return;
            }

            bool haveNonIdleNode = false;
            StringBuilder stringBuilder = new StringBuilder(64);
            stringBuilder.AppendFormat("{0}:   ", previousEventTime.Ticks);
            for (int i = 0; i < currentWork.Length; i++)
            {
                if (currentWork[i] == invalidWorkId)
                {
                    stringBuilder.Append("x       "); // Idle
                }
                else if (currentWork[i] == previousWork[i])
                {
                    stringBuilder.Append("|       "); // Continuing the work from the previous time.
                    haveNonIdleNode = true;
                }
                else
                {
                    stringBuilder.Append(String.Format(CultureInfo.InvariantCulture, "{0,-5}   ", currentWork[i]));
                    haveNonIdleNode = true;
                }
            }

            double duration = 0;
            if (previousEventTime != DateTime.MinValue)
            {
                duration = (currentEventTime - previousEventTime).TotalSeconds;
                accumulatedDuration += duration;
            }

            string durationBar = new String('#', (int)(duration / 0.05));
            if (haveNonIdleNode)
            {
                loggingService.LogComment(context, MessageImportance.Normal, "NodeUtilizationEntry", stringBuilder, duration, accumulatedDuration, durationBar);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Writes the graph representation of how the nodes were utilized.
        /// </summary>
        private void WriteNodeUtilizationGraph(ILoggingService loggingService, BuildEventContext context, bool useConfigurations)
        {
            int[] currentWork = new int[_availableNodes.Count];
            int[] previousWork = new int[currentWork.Length];
            HashSet<int>[] runningRequests = new HashSet<int>[currentWork.Length];
            DateTime currentEventTime = DateTime.MinValue;
            DateTime previousEventTime = DateTime.MinValue;
            double accumulatedDuration = 0;

            TimeSpan[] nodeActiveTimes = new TimeSpan[_availableNodes.Count];
            DateTime[] nodeStartTimes = new DateTime[_availableNodes.Count];
            int eventIndex = 0;

            Dictionary<int, int> availableNodeIdsToIndex = new Dictionary<int, int>(_availableNodes.Count);
            int[] indexToAvailableNodeId = new int[_availableNodes.Count];
            int indexIntoArrays = 0;

            foreach (int availableNodeId in _availableNodes.Keys)
            {
                availableNodeIdsToIndex[availableNodeId] = indexIntoArrays;
                indexToAvailableNodeId[indexIntoArrays] = availableNodeId;
                indexIntoArrays++;
            }

            // Prepare the arrays and headers.
            StringBuilder nodeIndices = new StringBuilder();
            int invalidWorkId = useConfigurations ? BuildRequestConfiguration.InvalidConfigurationId : BuildRequest.InvalidGlobalRequestId;
            for (int i = 0; i < currentWork.Length; i++)
            {
                currentWork[i] = invalidWorkId;
                previousWork[i] = invalidWorkId;
                runningRequests[i] = new HashSet<int>();
                nodeIndices.Append(String.Format(CultureInfo.InvariantCulture, "{0,-5}   ", indexToAvailableNodeId[i]));
            }

            loggingService.LogComment(context, MessageImportance.Normal, "NodeUtilizationHeader", nodeIndices.ToString());

            // Walk through each of the events and grab all of the events which have the same timestamp to determine what occurred.
            foreach (SchedulingData.SchedulingEvent buildEvent in _schedulingData.BuildEvents)
            {
                int workId = useConfigurations ? buildEvent.Request.BuildRequest.ConfigurationId : buildEvent.Request.BuildRequest.GlobalRequestId;

                if (buildEvent.EventTime > currentEventTime)
                {
                    WriteNodeUtilizationGraphLine(loggingService, context, currentWork, previousWork, buildEvent.EventTime, currentEventTime, invalidWorkId, ref accumulatedDuration);

                    if (currentEventTime != DateTime.MinValue)
                    {
                        // Accumulate time for nodes which were not idle.
                        for (int i = 0; i < currentWork.Length; i++)
                        {
                            if (currentWork[i] != invalidWorkId)
                            {
                                for (int x = 0; x < runningRequests[i].Count; x++)
                                {
                                    nodeActiveTimes[i] += buildEvent.EventTime - currentEventTime;
                                }
                            }
                        }
                    }

                    currentWork.CopyTo(previousWork, 0);
                    previousEventTime = currentEventTime;
                    currentEventTime = buildEvent.EventTime;
                    eventIndex++;
                }

                // The assigned node may be invalid if the request was completed from the cache.
                // In that case, just skip assessing it -- it did effectively no work.
                if (buildEvent.Request.AssignedNode != InvalidNodeId)
                {
                    int nodeForEvent = availableNodeIdsToIndex[buildEvent.Request.AssignedNode];

                    switch (buildEvent.NewState)
                    {
                        case SchedulableRequestState.Executing:
                        case SchedulableRequestState.Yielding:
                            currentWork[nodeForEvent] = workId;
                            if (!runningRequests[nodeForEvent].Contains(workId))
                            {
                                runningRequests[nodeForEvent].Add(workId);
                            }

                            if (nodeStartTimes[nodeForEvent] == DateTime.MinValue)
                            {
                                nodeStartTimes[nodeForEvent] = buildEvent.EventTime;
                            }

                            break;

                        default:
                            if (runningRequests[nodeForEvent].Contains(workId))
                            {
                                runningRequests[nodeForEvent].Remove(workId);
                            }

                            if (previousWork[nodeForEvent] == workId)
                            {
                                // The previously executing request is no longer executing here.
                                if (runningRequests[nodeForEvent].Count == 0)
                                {
                                    currentWork[nodeForEvent] = invalidWorkId; // Idle
                                }
                                else
                                {
                                    currentWork[nodeForEvent] = runningRequests[nodeForEvent].First();
                                }
                            }

                            break;
                    }
                }
            }

            WriteNodeUtilizationGraphLine(loggingService, context, currentWork, previousWork, currentEventTime, previousEventTime, invalidWorkId, ref accumulatedDuration);

            // Write out the node utilization percentage.
            double utilizationAverage = 0;
            StringBuilder utilitzationPercentages = new StringBuilder();
            for (int i = 0; i < nodeActiveTimes.Length; i++)
            {
                TimeSpan totalDuration = currentEventTime - nodeStartTimes[i];
                double utilizationPercent = (double)nodeActiveTimes[i].TotalMilliseconds / (double)totalDuration.TotalMilliseconds;

                utilitzationPercentages.AppendFormat("{0,-5:###.0}   ", utilizationPercent * 100);
                utilizationAverage += utilizationPercent;
            }

            loggingService.LogComment(context, MessageImportance.Normal, "NodeUtilizationSummary", utilitzationPercentages.ToString(), (utilizationAverage / (double)_availableNodes.Count) * 100);
        }
        /// <summary>
        /// Creates a ProjectRootElement representing a file, where the file may be a .sln instead of
        /// an MSBuild format file.
        /// Assumes path is already normalized.
        /// If the file is in MSBuild format, may throw InvalidProjectFileException.
        /// If the file is a solution, will throw an IO-related exception if the file cannot be read.
        /// </summary>
        private static ProjectRootElement CreateProjectFromPath
            (
                string projectFile,
                IDictionary<string, string> globalProperties,
                string toolsVersion,
                ILoggingService loggingService,
                ProjectRootElementCache projectRootElementCache,
                BuildEventContext buildEventContext
            )
        {
            ErrorUtilities.VerifyThrowInternalRooted(projectFile);

            try
            {
                if (FileUtilities.IsVCProjFilename(projectFile))
                {
                    ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(projectFile), "ProjectUpgradeNeededToVcxProj", projectFile);
                }

                // OK it's a regular project file, load it normally.
                return new ProjectRootElement(projectFile, projectRootElementCache, buildEventContext);
            }
            catch (InvalidProjectFileException)
            {
                throw;
            }
            catch (Exception ex)
            {
                if (!ExceptionHandling.NotExpectedException(ex))
                {
                    ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(projectFile), ex, "InvalidProjectFile", ex.Message);
                }

                throw;
            }
        }
        /// <summary>
        /// Gets a ProjectRootElement representing an MSBuild file.
        /// Path provided must be a canonicalized full path.
        /// May throw InvalidProjectFileException or an IO-related exception.
        /// </summary>
        internal static ProjectRootElement OpenProjectOrSolution(string fullPath, IDictionary<string, string> globalProperties, string toolsVersion, ILoggingService loggingService, ProjectRootElementCache projectRootElementCache, BuildEventContext buildEventContext, bool isExplicitlyLoaded)
        {
            ErrorUtilities.VerifyThrowInternalRooted(fullPath);

            ProjectRootElement projectRootElement = projectRootElementCache.Get(
                fullPath,
                (path, cache) => CreateProjectFromPath(path, globalProperties, toolsVersion, loggingService, cache, buildEventContext),
                isExplicitlyLoaded);

            return projectRootElement;
        }
Beispiel #17
0
        /// <summary>
        /// Used to load information about default MSBuild tasks i.e. tasks that do not need to be explicitly declared in projects
        /// with the &lt;UsingTask&gt; element. Default task information is read from special files, which are located in the same
        /// directory as the MSBuild binaries.
        /// </summary>
        /// <remarks>
        /// 1) a default tasks file needs the &lt;Project&gt; root tag in order to be well-formed
        /// 2) the XML declaration tag &lt;?xml ...&gt; is ignored
        /// 3) comment tags are always ignored regardless of their placement
        /// 4) the rest of the tags are expected to be &lt;UsingTask&gt; tags
        /// </remarks>
        /// <param name="loggingServices">The logging services to use to log during this registration.</param>
        /// <param name="buildEventContext">The build event context to use to log during this registration.</param>
        private void RegisterDefaultTasks(ILoggingService loggingServices, BuildEventContext buildEventContext, ProjectRootElementCache projectRootElementCache)
        {
            if (!_defaultTasksRegistrationAttempted)
            {
                try
                {
                    _defaultTaskRegistry = new TaskRegistry(projectRootElementCache);

                    InitializeProperties(loggingServices, buildEventContext);

                    string[] defaultTasksFiles = GetTaskFiles(_getFiles, loggingServices, buildEventContext, DefaultTasksFilePattern, ToolsPath, "DefaultTasksFileLoadFailureWarning");
                    LoadAndRegisterFromTasksFile(ToolsPath, defaultTasksFiles, loggingServices, buildEventContext, DefaultTasksFilePattern, "DefaultTasksFileFailure", projectRootElementCache, _defaultTaskRegistry);
                }
                finally
                {
                    _defaultTasksRegistrationAttempted = true;
                }
            }
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 private SolutionProjectGenerator
     (
     SolutionFile solution,
     IDictionary<string, string> globalProperties,
     string toolsVersionOverride,
     BuildEventContext projectBuildEventContext,
     ILoggingService loggingService
     )
 {
     _solutionFile = solution;
     _globalProperties = globalProperties ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
     _toolsVersionOverride = toolsVersionOverride;
     _projectBuildEventContext = projectBuildEventContext;
     _loggingService = loggingService;
 }
Beispiel #19
0
        /// <summary>
        /// Initialize the properties which are used to evaluate the tasks files.
        /// </summary>
        private void InitializeProperties(ILoggingService loggingServices, BuildEventContext buildEventContext)
        {
            try
            {
                if (_propertyBag == null)
                {
                    List<ProjectPropertyInstance> reservedProperties = new List<ProjectPropertyInstance>();

                    reservedProperties.Add(ProjectPropertyInstance.Create(ReservedPropertyNames.binPath, EscapingUtilities.Escape(ToolsPath), mayBeReserved: true));
                    reservedProperties.Add(ProjectPropertyInstance.Create(ReservedPropertyNames.toolsVersion, ToolsVersion, mayBeReserved: true));

                    reservedProperties.Add(ProjectPropertyInstance.Create(ReservedPropertyNames.toolsPath, EscapingUtilities.Escape(ToolsPath), mayBeReserved: true));
                    reservedProperties.Add(ProjectPropertyInstance.Create(ReservedPropertyNames.assemblyVersion, Constants.AssemblyVersion, mayBeReserved: true));

                    // Add one for the subtoolset version property -- it may or may not be set depending on whether it has already been set by the 
                    // environment or global properties, but it's better to create a dictionary that's one too big than one that's one too small.  
                    int count = _environmentProperties.Count + reservedProperties.Count + Properties.Values.Count + _globalProperties.Count + 1;

                    // GenerateSubToolsetVersion checks the environment and global properties, so it's safe to go ahead and gather the 
                    // subtoolset properties here without fearing that we'll have somehow come up with the wrong subtoolset version. 
                    string subToolsetVersion = this.GenerateSubToolsetVersion();
                    SubToolset subToolset;
                    ICollection<ProjectPropertyInstance> subToolsetProperties = null;

                    if (subToolsetVersion != null)
                    {
                        if (SubToolsets.TryGetValue(subToolsetVersion, out subToolset))
                        {
                            subToolsetProperties = subToolset.Properties.Values;
                            count += subToolsetProperties.Count;
                        }
                    }

                    _propertyBag = new PropertyDictionary<ProjectPropertyInstance>(count);

                    // Should be imported in the same order as in the evaluator:  
                    // - Environment
                    // - Toolset
                    // - Subtoolset (if any) 
                    // - Global
                    _propertyBag.ImportProperties(_environmentProperties);

                    _propertyBag.ImportProperties(reservedProperties);

                    _propertyBag.ImportProperties(Properties.Values);

                    if (subToolsetVersion != null)
                    {
                        _propertyBag.Set(ProjectPropertyInstance.Create(Constants.SubToolsetVersionPropertyName, subToolsetVersion));
                    }

                    if (subToolsetProperties != null)
                    {
                        _propertyBag.ImportProperties(subToolsetProperties);
                    }

                    _propertyBag.ImportProperties(_globalProperties);
                }

                if (_expander == null)
                {
                    _expander = new Expander<ProjectPropertyInstance, ProjectItemInstance>(_propertyBag);
                }
            }
            catch (Exception e)
            {
                if (ExceptionHandling.NotExpectedException(e))
                {
                    // Catching Exception, but rethrowing unless it's an IO related exception.
                    throw;
                }

                loggingServices.LogError(buildEventContext, new BuildEventFileInfo(/* this warning truly does not involve any file it is just gathering properties */String.Empty), "TasksPropertyBagError", e.Message);
            }
        }
Beispiel #20
0
        /// <summary>
        /// Creates a ProjectRootElement representing a file, where the file may be a .sln instead of
        /// an MSBuild format file.
        /// Assumes path is already normalized.
        /// If the file is in MSBuild format, may throw InvalidProjectFileException.
        /// If the file is a solution, will throw an IO-related exception if the file cannot be read.
        /// </summary>
        private static ProjectRootElement CreateProjectFromPath
            (
                string projectFile,
                IDictionary<string, string> globalProperties,
                string toolsVersion,
                ILoggingService loggingService,
                ProjectRootElementCache projectRootElementCache,
                BuildEventContext buildEventContext,
                bool preserveFormatting
            )
        {
            ErrorUtilities.VerifyThrowInternalRooted(projectFile);

            try
            {
                if (FileUtilities.IsVCProjFilename(projectFile))
                {
                    ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(projectFile), "ProjectUpgradeNeededToVcxProj", projectFile);
                }

                // OK it's a regular project file, load it normally.
                return new ProjectRootElement(projectFile, projectRootElementCache, buildEventContext, preserveFormatting);
            }
            catch (InvalidProjectFileException)
            {
                throw;
            }
            catch (Exception ex) when (ExceptionHandling.IsIoRelatedException(ex))
            {
                ProjectFileErrorUtilities.ThrowInvalidProjectFile(new BuildEventFileInfo(projectFile), ex, "InvalidProjectFile", ex.Message);
                throw; // Without this there's a spurious CS0161 because csc 1.2.0.60317 can't see that the above is an unconditional throw.
            }
        }
Beispiel #21
0
            /// <summary>
            /// Constructor
            /// 
            /// UNDONE: Refactor this, and the other MockHosts, to use a common base implementation.  The duplication of the
            /// logging implementation alone is unfortunate.
            /// </summary>
            public MockHost()
            {
                _buildParameters = new BuildParameters();
                _legacyThreadingData = new LegacyThreadingData();

                _configCache = new ConfigCache();
                ((IBuildComponent)_configCache).InitializeComponent(this);

                _loggingService = this;

                _resultsCache = new ResultsCache();
                ((IBuildComponent)_resultsCache).InitializeComponent(this);

                _requestBuilder = new RequestBuilder();
                ((IBuildComponent)_requestBuilder).InitializeComponent(this);

                _targetBuilder = new TargetBuilder();
                ((IBuildComponent)_targetBuilder).InitializeComponent(this);
            }
Beispiel #22
0
 /// <summary>
 /// Constructor 
 /// </summary>
 internal QAMockHost(GetComponentDelegate getComponentCallback)
 {
     this.buildParameters = new BuildParameters();
     this.getComponentCallback = getComponentCallback;
     this.engineStatusChangedEvent = new AutoResetEvent(false);
     this.lastEngineStatus = BuildRequestEngineStatus.Shutdown;
     this.loggingService = this;
     this.requestEngine = null;
     this.testDataProvider = null;
     this.buildComponents = new Queue<IBuildComponent>();
     this.legacyThreadingData = new LegacyThreadingData();
 }
        /// <summary>
        /// This method generates an MSBuild project file from the list of projects and project dependencies 
        /// that have been collected from the solution file.
        /// </summary>
        /// <param name="solution">The parser which contains the solution file.</param>
        /// <param name="globalProperties">The global properties.</param>
        /// <param name="toolsVersionOverride">Tools Version override (may be null).  This should be any tools version explicitly passed to the command-line or from an MSBuild ToolsVersion parameter.</param>
        /// <param name="projectBuildEventContext">The logging context for this project.</param>
        /// <param name="loggingService">The logging service.</param>
        /// <returns>An array of ProjectInstances.  The first instance is the traversal project, the remaining are the metaprojects for each project referenced in the solution.</returns>
        internal static ProjectInstance[] Generate
            (
            SolutionFile solution,
            IDictionary<string, string> globalProperties,
            string toolsVersionOverride,
            BuildEventContext projectBuildEventContext,
            ILoggingService loggingService
            )
        {
            SolutionProjectGenerator projectGenerator = new SolutionProjectGenerator
                (
                solution,
                globalProperties,
                toolsVersionOverride,
                projectBuildEventContext,
                loggingService
                );

            return projectGenerator.Generate();
        }
Beispiel #24
0
        /// <summary>
        /// Shuts down the component. First shutdown the request engine. Then shutdown the remaining of the component.
        /// Check if the test data provider exists before shutting it down as it may not have been registered yet because this is also
        /// called in TearDown and teardown is called if an exception is received.
        /// </summary>
        public void ShutdownComponent()
        {
            ShutDownRequestEngine();
            if (_testDataProvider != null)
            {
                ((IBuildComponent)_testDataProvider).ShutdownComponent();
            }

            _buildComponents.Clear();
            _loggingService = null;
            _requestEngine = null;
        }