Beispiel #1
0
        public void ConflictWithBackVersionPrimaryWithAutoUnify()
        {
            ResolveAssemblyReference t = new ResolveAssemblyReference();

            MockEngine e = new MockEngine(_output);

            t.BuildEngine = e;

            t.Assemblies = new ITaskItem[]
            {
                new TaskItem("B"),
                new TaskItem("A"),
                new TaskItem("D, Version=1.0.0.0, Culture=neutral, PublicKeyToken=aaaaaaaaaaaaaaaa")
            };

            t.AutoUnify = true;

            t.SearchPaths = new string[]
            {
                s_myLibrariesRootPath, s_myLibraries_V2Path, s_myLibraries_V1Path
            };

            t.TargetFrameworkDirectories = new string[] { s_myVersion20Path };

            bool result = Execute(t);

            Assert.Equal(1, e.Warnings); // @"Expected one warning."

            // Check that we have a message identifying conflicts with "D"
            string warningMessage = e.WarningEvents[0].Message;

            warningMessage.ShouldContain(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("ResolveAssemblyReference.FoundConflicts", "D", string.Empty));
            warningMessage.ShouldContain(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("ResolveAssemblyReference.ConflictFound", "D, Version=1.0.0.0, CulTUre=neutral, PublicKeyToken=aaaaaaaaaaaaaaaa", "D, Version=2.0.0.0, Culture=neutral, PublicKeyToken=aaaaaaaaaaaaaaaa"));
            warningMessage.ShouldContain(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("ResolveAssemblyReference.FourSpaceIndent", ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("ResolveAssemblyReference.ReferenceDependsOn", "D, Version=1.0.0.0, CulTUre=neutral, PublicKeyToken=aaaaaaaaaaaaaaaa", Path.Combine(s_myLibraries_V1Path, "D.dll"))));

            Assert.Empty(t.SuggestedRedirects);
            Assert.Equal(3, t.ResolvedFiles.Length);
            Assert.True(ContainsItem(t.ResolvedFiles, s_myLibraries_V1_DDllPath)); // "Expected to find assembly, but didn't."
        }
Beispiel #2
0
        private void VerifyImplementationArchitecture(string winmdName, string targetProcessorArchitecture, string implementationFileArch, string warnOrErrorOnTargetArchitectureMismatch)
        {
            // Create the engine.
            MockEngine engine = new MockEngine();
            TaskItem   item   = new TaskItem(winmdName);

            ITaskItem[] assemblyFiles = new TaskItem[] { item };

            ResolveAssemblyReference t = new ResolveAssemblyReference();

            t.BuildEngine = engine;
            t.Assemblies  = assemblyFiles;
            t.SearchPaths = new String[] { @"C:\WinMDArchVerification" };
            t.TargetProcessorArchitecture             = targetProcessorArchitecture;
            t.WarnOrErrorOnTargetArchitectureMismatch = warnOrErrorOnTargetArchitectureMismatch;

            bool succeeded = Execute(t);

            Assert.Equal(1, t.ResolvedFiles.Length);

            Assert.True(t.ResolvedFiles[0].ItemSpec.Equals(@"C:\WinMDArchVerification\" + winmdName + ".winmd", StringComparison.OrdinalIgnoreCase));
            Assert.True(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.imageRuntime).Equals(@"WindowsRuntime 1.0", StringComparison.OrdinalIgnoreCase));
            Assert.True(bool.Parse(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winMDFile)));

            string fullMessage = null;

            if (implementationFileArch.Equals("Unknown"))
            {
                fullMessage = ResourceUtilities.FormatResourceString("ResolveAssemblyReference.UnknownProcessorArchitecture", @"C:\WinMDArchVerification\" + winmdName + ".dll", @"C:\WinMDArchVerification\" + winmdName + ".winmd", NativeMethods.IMAGE_FILE_MACHINE_R4000.ToString("X", CultureInfo.InvariantCulture));
            }
            else
            {
                fullMessage = ResourceUtilities.FormatResourceString("ResolveAssemblyReference.MismatchBetweenTargetedAndReferencedArchOfImplementation", targetProcessorArchitecture, implementationFileArch, @"C:\WinMDArchVerification\" + winmdName + ".dll", @"C:\WinMDArchVerification\" + winmdName + ".winmd");
            }

            if (warnOrErrorOnTargetArchitectureMismatch.Equals("None", StringComparison.OrdinalIgnoreCase))
            {
                engine.AssertLogDoesntContain(fullMessage);
            }
            else
            {
                engine.AssertLogContains(fullMessage);
            }

            if (warnOrErrorOnTargetArchitectureMismatch.Equals("Warning", StringComparison.OrdinalIgnoreCase))
            {
                // Should fail since PE Header is not valid and this is always an error.
                Assert.True(succeeded);
                Assert.True(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winmdImplmentationFile).Equals(winmdName + ".dll"));
                Assert.Equal(0, engine.Errors);
                Assert.Equal(1, engine.Warnings);
            }
            else if (warnOrErrorOnTargetArchitectureMismatch.Equals("Error", StringComparison.OrdinalIgnoreCase))
            {
                // Should fail since PE Header is not valid and this is always an error.
                Assert.False(succeeded);
                Assert.Equal(0, t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winmdImplmentationFile).Length);
                Assert.Equal(1, engine.Errors);
                Assert.Equal(0, engine.Warnings);
            }
            else if (warnOrErrorOnTargetArchitectureMismatch.Equals("None", StringComparison.OrdinalIgnoreCase))
            {
                Assert.True(succeeded);
                Assert.True(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winmdImplmentationFile).Equals(winmdName + ".dll"));
                Assert.Equal(0, engine.Errors);
                Assert.Equal(0, engine.Warnings);
            }
        }
Beispiel #3
0
        /// <summary>
        /// This function will start a node and send requests to it
        /// </summary>
        private void LaunchNodeAndPostBuildRequest()
        {
            int nodeIndex = 0;

            // Find out what node to launch
            lock (nodesToLaunch)
            {
                nodeIndex = nodesToLaunch.Dequeue();
            }

            // If the provider is shutting down - don't launch the node
            if (shuttingDown)
            {
                nodeData[nodeIndex].NodeState = NodeState.NotLaunched;
                return;
            }

            try
            {
                // Either launch node or connect to an already running node
                InitializeNode(nodeIndex);

                if (!nodeData[nodeIndex].CommunicationFailed)
                {
                    // Change the state of the node to launched
                    lock (nodeStateLock)
                    {
                        nodeData[nodeIndex].NodeState = NodeState.Launched;
                    }

                    // Send all the requests to the node. Note that the requests may end up in
                    // mixed order with the request currently being posted.
                    LinkedListNode <BuildRequest> current = nodeData[nodeIndex].TargetList.First;
                    BuildRequest[] buildRequests          = new BuildRequest[nodeData[nodeIndex].TargetList.Count];
                    int            i = 0;
                    while (current != null)
                    {
                        buildRequests[i] = current.Value;
                        i++;

                        current = current.Next;
                    }
                    LocalCallDescriptorForPostBuildRequests callDescriptor =
                        new LocalCallDescriptorForPostBuildRequests(buildRequests);
                    nodeData[nodeIndex].NodeCommandQueue.Enqueue(callDescriptor);

                    nodeData[nodeIndex].TargetList = null;
                }
                else
                {
                    // Allow the engine to decide how to proceed since the node failed to launch
                    string message = ResourceUtilities.FormatResourceString("NodeProviderFailure");
                    ReportNodeCommunicationFailure(nodeIndex, new Exception(message), false);
                }
            }
            catch (Exception e)
            {
                // Allow the engine to deal with the exception
                ReportNodeCommunicationFailure(nodeIndex, e, false);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Finds or creates a child process which can act as a node.
        /// </summary>
        /// <returns>The pipe stream representing the node.</returns>
        protected NodeContext GetNode(string msbuildLocation, string commandLineArgs, int nodeId, INodePacketFactory factory, Handshake hostHandshake, NodeContextTerminateDelegate terminateNode)
        {
#if DEBUG
            if (Execution.BuildManager.WaitForDebugger)
            {
                commandLineArgs += " /wfd";
            }
#endif

            if (String.IsNullOrEmpty(msbuildLocation))
            {
                msbuildLocation = _componentHost.BuildParameters.NodeExeLocation;
            }

            if (String.IsNullOrEmpty(msbuildLocation))
            {
                string msbuildExeName = Environment.GetEnvironmentVariable("MSBUILD_EXE_NAME");

                if (!String.IsNullOrEmpty(msbuildExeName))
                {
                    // we assume that MSBUILD_EXE_NAME is, in fact, just the name.
                    msbuildLocation = Path.Combine(msbuildExeName, ".exe");
                }
            }

#if FEATURE_NODE_REUSE
            // Try to connect to idle nodes if node reuse is enabled.
            if (_componentHost.BuildParameters.EnableNodeReuse)
            {
                (string expectedProcessName, List <Process> processes)runningNodesTuple = GetPossibleRunningNodes(msbuildLocation);

                CommunicationsUtilities.Trace("Attempting to connect to each existing {1} process in turn to establish node {0}...", nodeId, runningNodesTuple.expectedProcessName);
                foreach (Process nodeProcess in runningNodesTuple.processes)
                {
                    if (nodeProcess.Id == Process.GetCurrentProcess().Id)
                    {
                        continue;
                    }

                    // Get the full context of this inspection so that we can always skip this process when we have the same taskhost context
                    string nodeLookupKey = GetProcessesToIgnoreKey(hostHandshake, nodeProcess.Id);
                    if (_processesToIgnore.Contains(nodeLookupKey))
                    {
                        continue;
                    }

                    // We don't need to check this again
                    _processesToIgnore.Add(nodeLookupKey);

                    // Attempt to connect to each process in turn.
                    Stream nodeStream = TryConnectToProcess(nodeProcess.Id, 0 /* poll, don't wait for connections */, hostHandshake);
                    if (nodeStream != null)
                    {
                        // Connection successful, use this node.
                        CommunicationsUtilities.Trace("Successfully connected to existed node {0} which is PID {1}", nodeId, nodeProcess.Id);
                        return(new NodeContext(nodeId, nodeProcess, nodeStream, factory, terminateNode));
                    }
                }
            }
#endif

            // None of the processes we tried to connect to allowed a connection, so create a new one.
            // We try this in a loop because it is possible that there is another MSBuild multiproc
            // host process running somewhere which is also trying to create nodes right now.  It might
            // find our newly created node and connect to it before we get a chance.
            CommunicationsUtilities.Trace("Could not connect to existing process, now creating a process...");
            int retries = NodeCreationRetries;
            while (retries-- > 0)
            {
#if FEATURE_NET35_TASKHOST
                // We will also check to see if .NET 3.5 is installed in the case where we need to launch a CLR2 OOP TaskHost.
                // Failure to detect this has been known to stall builds when Windows pops up a related dialog.
                // It's also a waste of time when we attempt several times to launch multiple MSBuildTaskHost.exe (CLR2 TaskHost)
                // nodes because we should never be able to connect in this case.
                string taskHostNameForClr2TaskHost = Path.GetFileNameWithoutExtension(NodeProviderOutOfProcTaskHost.TaskHostNameForClr2TaskHost);
                if (Path.GetFileNameWithoutExtension(msbuildLocation).Equals(taskHostNameForClr2TaskHost, StringComparison.OrdinalIgnoreCase))
                {
                    if (FrameworkLocationHelper.GetPathToDotNetFrameworkV35(DotNetFrameworkArchitecture.Current) == null)
                    {
                        CommunicationsUtilities.Trace
                        (
                            "Failed to launch node from {0}. The required .NET Framework v3.5 is not installed or enabled. CommandLine: {1}",
                            msbuildLocation,
                            commandLineArgs
                        );

                        string nodeFailedToLaunchError = ResourceUtilities.GetResourceString("TaskHostNodeFailedToLaunchErrorCodeNet35NotInstalled");
                        throw new NodeFailedToLaunchException(null, nodeFailedToLaunchError);
                    }
                }
#endif

                // Create the node process
                Process msbuildProcess = LaunchNode(msbuildLocation, commandLineArgs);
                _processesToIgnore.Add(GetProcessesToIgnoreKey(hostHandshake, msbuildProcess.Id));

                // Note, when running under IMAGEFILEEXECUTIONOPTIONS registry key to debug, the process ID
                // gotten back from CreateProcess is that of the debugger, which causes this to try to connect
                // to the debugger process. Instead, use MSBUILDDEBUGONSTART=1

                // Now try to connect to it.
                Stream nodeStream = TryConnectToProcess(msbuildProcess.Id, TimeoutForNewNodeCreation, hostHandshake);
                if (nodeStream != null)
                {
                    // Connection successful, use this node.
                    CommunicationsUtilities.Trace("Successfully connected to created node {0} which is PID {1}", nodeId, msbuildProcess.Id);
                    return(new NodeContext(nodeId, msbuildProcess, nodeStream, factory, terminateNode));
                }
            }

            // We were unable to launch a node.
            CommunicationsUtilities.Trace("FAILED TO CONNECT TO A CHILD NODE");
            return(null);
        }
Beispiel #5
0
        /// <summary>
        /// Load a graph with root node at entryProjectFile
        /// Maintain a queue of projects to be processed and evaluate projects in parallel
        /// Returns false if loading the graph is not successful
        /// </summary>
        private bool LoadGraph(
            ConcurrentQueue <ConfigurationMetadata> projectsToEvaluate,
            ProjectCollection projectCollection,
            ConcurrentDictionary <ConfigurationMetadata, object> tasksInProgress,
            ProjectInstanceFactoryFunc projectInstanceFactory,
            out List <Exception> exceptions)
        {
            var exceptionsInTasks    = new ConcurrentBag <Exception>();
            var evaluationWaitHandle = new AutoResetEvent(false);

            while (projectsToEvaluate.Count != 0 || tasksInProgress.Count != 0)
            {
                ConfigurationMetadata projectToEvaluate;
                if (projectsToEvaluate.Count != 0)
                {
                    projectToEvaluate = projectsToEvaluate.Dequeue();
                    var task = new Task(() =>
                    {
                        ProjectGraphNode parsedProject = CreateNewNode(projectToEvaluate, projectCollection, projectInstanceFactory);
                        IEnumerable <ProjectItemInstance> projectReferenceItems = parsedProject.ProjectInstance.GetItems(MSBuildConstants.ProjectReferenceItemName);
                        foreach (var projectReferenceToParse in projectReferenceItems)
                        {
                            if (!string.IsNullOrEmpty(projectReferenceToParse.GetMetadataValue(ToolsVersionMetadataName)))
                            {
                                throw new InvalidOperationException(string.Format(
                                                                        CultureInfo.InvariantCulture,
                                                                        ResourceUtilities.GetResourceString(
                                                                            "ProjectGraphDoesNotSupportProjectReferenceWithToolset"),
                                                                        projectReferenceToParse.EvaluatedInclude,
                                                                        parsedProject.ProjectInstance.FullPath));
                            }

                            string projectReferenceFullPath = projectReferenceToParse.GetMetadataValue(FullPathMetadataName);
                            PropertyDictionary <ProjectPropertyInstance> projectReferenceGlobalProperties = GetProjectReferenceGlobalProperties(projectReferenceToParse, projectToEvaluate.GlobalProperties);
                            var projectReferenceConfigurationMetadata = new ConfigurationMetadata(projectReferenceFullPath, projectReferenceGlobalProperties);
                            if (!tasksInProgress.ContainsKey(projectReferenceConfigurationMetadata))
                            {
                                if (!_allParsedProjects.ContainsKey(projectReferenceConfigurationMetadata))
                                {
                                    projectsToEvaluate.Enqueue(projectReferenceConfigurationMetadata);
                                    evaluationWaitHandle.Set();
                                }
                            }
                        }
                    });

                    if (tasksInProgress.TryAdd(projectToEvaluate, null))
                    {
                        // once the task completes, remove it from tasksInProgress using a chained task
                        // signal the wait handle to process new projects that have been discovered by this task or exit if all projects have been evaluated
                        task.ContinueWith(_ =>
                        {
                            if (task.IsFaulted)
                            {
                                exceptionsInTasks.Add(task.Exception.InnerException);
                            }
                            tasksInProgress.TryRemove(projectToEvaluate, out var _);
                            evaluationWaitHandle.Set();
                        });
                        task.Start();
                    }
                }
                else
                {
                    // if projectsToEvaluate is empty but there are tasks in progress, there is nothing to do till a task completes and discovers new projects
                    // wait till a task completes and sends a signal
                    evaluationWaitHandle.WaitOne();
                }
            }

            if (exceptionsInTasks.Count != 0)
            {
                exceptions = exceptionsInTasks.ToList();
                return(false);
            }

            exceptions = null;
            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// Initializes the logger by subscribing to events of IEventSource
        /// </summary>
        public void Initialize(IEventSource eventSource)
        {
            _initialTargetOutputLogging = Environment.GetEnvironmentVariable("MSBUILDTARGETOUTPUTLOGGING");
            _initialLogImports          = Traits.Instance.EscapeHatches.LogProjectImports;

            Environment.SetEnvironmentVariable("MSBUILDTARGETOUTPUTLOGGING", "true");
            Environment.SetEnvironmentVariable("MSBUILDLOGIMPORTS", "1");
            Traits.Instance.EscapeHatches.LogProjectImports = true;

            ProcessParameters();

            try
            {
                string logDirectory = null;
                try
                {
                    logDirectory = Path.GetDirectoryName(FilePath);
                }
                catch (Exception)
                {
                    // Directory creation is best-effort; if finding its path fails don't create the directory
                    // and possibly let the FileStream constructor below report the failure
                }

                if (logDirectory != null)
                {
                    Directory.CreateDirectory(logDirectory);
                }

                stream = new FileStream(FilePath, FileMode.Create);

                if (CollectProjectImports != ProjectImportsCollectionMode.None)
                {
                    projectImportsCollector = new ProjectImportsCollector(FilePath, CollectProjectImports == ProjectImportsCollectionMode.ZipFile);
                }

                if (eventSource is IEventSource3 eventSource3)
                {
                    eventSource3.IncludeEvaluationMetaprojects();
                }
            }
            catch (Exception e)
            {
                string errorCode;
                string helpKeyword;
                string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(out errorCode, out helpKeyword, "InvalidFileLoggerFile", FilePath, e.Message);
                throw new LoggerException(message, e, errorCode, helpKeyword);
            }

            stream = new GZipStream(stream, CompressionLevel.Optimal);

            // wrapping the GZipStream in a buffered stream significantly improves performance
            // and the max throughput is reached with a 32K buffer. See details here:
            // https://github.com/dotnet/runtime/issues/39233#issuecomment-745598847
            stream          = new BufferedStream(stream, bufferSize: 32768);
            binaryWriter    = new BinaryWriter(stream);
            eventArgsWriter = new BuildEventArgsWriter(binaryWriter);

            binaryWriter.Write(FileFormatVersion);

            LogInitialInfo();

            eventSource.AnyEventRaised += EventSource_AnyEventRaised;
        }
Beispiel #7
0
        private (IReadOnlyCollection <ProjectGraphEntryPoint> NewEntryPoints, IReadOnlyDictionary <string, IReadOnlyCollection <string> > SolutionDependencies) ExpandSolutionIfPresent(IReadOnlyCollection <ProjectGraphEntryPoint> entryPoints)
        {
            if (entryPoints.Count == 0 || !entryPoints.Any(e => FileUtilities.IsSolutionFilename(e.ProjectFile)))
            {
                return(entryPoints, null);
            }

            if (entryPoints.Count != 1)
            {
                throw new ArgumentException(
                          ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(
                              "StaticGraphAcceptsSingleSolutionEntryPoint",
                              string.Join(";", entryPoints.Select(e => e.ProjectFile))));
            }

            ErrorUtilities.VerifyThrowArgument(entryPoints.Count == 1, "StaticGraphAcceptsSingleSolutionEntryPoint");

            var solutionEntryPoint       = entryPoints.Single();
            var solutionGlobalProperties = ImmutableDictionary.CreateRange(
                keyComparer: StringComparer.OrdinalIgnoreCase,
                valueComparer: StringComparer.OrdinalIgnoreCase,
                items: solutionEntryPoint.GlobalProperties ?? ImmutableDictionary <string, string> .Empty);

            var solution = SolutionFile.Parse(solutionEntryPoint.ProjectFile);

            if (solution.SolutionParserWarnings.Count != 0 || solution.SolutionParserErrorCodes.Count != 0)
            {
                throw new InvalidProjectFileException(
                          ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword(
                              "StaticGraphSolutionLoaderEncounteredSolutionWarningsAndErrors",
                              solutionEntryPoint.ProjectFile,
                              string.Join(";", solution.SolutionParserWarnings),
                              string.Join(";", solution.SolutionParserErrorCodes)));
            }

            var projectsInSolution = GetBuildableProjects(solution);

            var currentSolutionConfiguration = SelectSolutionConfiguration(solution, solutionGlobalProperties);

            var newEntryPoints = new List <ProjectGraphEntryPoint>(projectsInSolution.Count);

            foreach (var project in projectsInSolution)
            {
                if (project.ProjectConfigurations.Count == 0)
                {
                    continue;
                }

                var projectConfiguration = SelectProjectConfiguration(currentSolutionConfiguration, project.ProjectConfigurations);

                if (projectConfiguration.IncludeInBuild)
                {
                    newEntryPoints.Add(
                        new ProjectGraphEntryPoint(
                            project.AbsolutePath,
                            solutionGlobalProperties
                            .SetItem("Configuration", projectConfiguration.ConfigurationName)
                            .SetItem("Platform", projectConfiguration.PlatformName)
                            ));
                }
            }

            newEntryPoints.TrimExcess();

            return(newEntryPoints, GetSolutionDependencies(solution));

            IReadOnlyCollection <ProjectInSolution> GetBuildableProjects(SolutionFile solutionFile)
            {
                return(solutionFile.ProjectsInOrder.Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat && solutionFile.ProjectShouldBuild(p.RelativePath)).ToImmutableArray());
            }

            SolutionConfigurationInSolution SelectSolutionConfiguration(SolutionFile solutionFile, ImmutableDictionary <string, string> globalProperties)
            {
                var solutionConfiguration = globalProperties.TryGetValue("Configuration", out string configuration)
                    ? configuration
                    : solutionFile.GetDefaultConfigurationName();

                var solutionPlatform = globalProperties.TryGetValue("Platform", out string platform)
                    ? platform
                    : solutionFile.GetDefaultPlatformName();

                return(new SolutionConfigurationInSolution(solutionConfiguration, solutionPlatform));
            }

            ProjectConfigurationInSolution SelectProjectConfiguration(
                SolutionConfigurationInSolution solutionConfig,
                IReadOnlyDictionary <string, ProjectConfigurationInSolution> projectConfigs)
            {
                // implements the matching described in https://docs.microsoft.com/en-us/visualstudio/ide/understanding-build-configurations?view=vs-2019#how-visual-studio-assigns-project-configuration

                var solutionConfigFullName = solutionConfig.FullName;

                if (projectConfigs.TryGetValue(solutionConfigFullName, out ProjectConfigurationInSolution projectConfiguration))
                {
                    return(projectConfiguration);
                }

                var partiallyMarchedConfig = projectConfigs.FirstOrDefault(pc => pc.Value.ConfigurationName.Equals(solutionConfig.ConfigurationName, StringComparison.OrdinalIgnoreCase)).Value;

                return(partiallyMarchedConfig ?? projectConfigs.First().Value);
            }

            IReadOnlyDictionary <string, IReadOnlyCollection <string> > GetSolutionDependencies(SolutionFile solutionFile)
            {
                var solutionDependencies = new Dictionary <string, IReadOnlyCollection <string> >();

                foreach (var projectWithDependencies in solutionFile.ProjectsInOrder.Where(p => p.Dependencies.Count != 0))
                {
                    solutionDependencies[projectWithDependencies.AbsolutePath] = projectWithDependencies.Dependencies.Select(
                        dependencyGuid =>
                    {
                        // code snippet cloned from SolutionProjectGenerator.AddPropertyGroupForSolutionConfiguration

                        if (!solutionFile.ProjectsByGuid.TryGetValue(dependencyGuid, out var dependencyProject))
                        {
                            // If it's not itself part of the solution, that's an invalid solution
                            ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(
                                dependencyProject != null,
                                "SubCategoryForSolutionParsingErrors",
                                new BuildEventFileInfo(solutionFile.FullPath),
                                "SolutionParseProjectDepNotFoundError",
                                projectWithDependencies.ProjectGuid,
                                dependencyGuid);
                        }

                        // Add it to the list of dependencies, but only if it should build in this solution configuration
                        // (If a project is not selected for build in the solution configuration, it won't build even if it's depended on by something that IS selected for build)
                        // .. and only if it's known to be MSBuild format, as projects can't use the information otherwise
                        return(dependencyProject?.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat
                                ? dependencyProject.AbsolutePath
                                : null);
                    })
                                                                                 .Where(p => p != null)
                                                                                 .ToArray();
                }

                return(solutionDependencies);
            }
        }
Beispiel #8
0
 /// <summary>
 /// Increases the error count by 1, and logs the error message
 /// </summary>
 /// <param name="messageResourceName"></param>
 /// <param name="messageArgs"></param>
 private void LogError(string messageResourceName, params object[] messageArgs)
 {
     _errorLog.AddLast(ResourceUtilities.FormatResourceString(messageResourceName, messageArgs));
     _errorCount++;
 }
Beispiel #9
0
        /// <summary>
        /// Gets a text serialized value of a parameter for logging.
        /// </summary>
        internal static string GetParameterText(string prefix, string parameterName, IList parameterValue, bool logItemMetadata = true)
        {
            if (parameterValue == null || parameterValue.Count == 0)
            {
                return(parameterName);
            }

            using (var sb = new ReuseableStringBuilder())
            {
                sb.Append(prefix);

                bool firstEntryIsTaskItemWithSomeCustomMetadata = false;
                var  firstItem = parameterValue[0] as ITaskItem;
                if (firstItem != null)
                {
                    if (firstItem.CloneCustomMetadata().Count > 0)
                    {
                        firstEntryIsTaskItemWithSomeCustomMetadata = true;
                    }
                }

                // If it's just one entry in the list, and it's not a task item with metadata, keep it on one line like a scalar
                bool specialTreatmentForSingle = (parameterValue.Count == 1 && !firstEntryIsTaskItemWithSomeCustomMetadata);

                if (!specialTreatmentForSingle)
                {
                    sb.Append("\n    ");
                }

                sb.Append(parameterName);
                sb.Append('=');

                if (!specialTreatmentForSingle)
                {
                    sb.Append("\n");
                }

                bool truncateTaskInputs = Traits.Instance.EscapeHatches.TruncateTaskInputs;

                for (int i = 0; i < parameterValue.Count; i++)
                {
                    if (parameterValue[i] == null)
                    {
                        continue;
                    }

                    if (!specialTreatmentForSingle)
                    {
                        sb.Append("        ");
                    }

                    AppendStringFromParameterValue(sb, parameterValue[i], logItemMetadata);

                    if (!specialTreatmentForSingle && i < parameterValue.Count - 1)
                    {
                        sb.Append("\n");
                    }

                    if (truncateTaskInputs && (sb.Length >= parameterCharacterLimit || i > parameterLimit))
                    {
                        sb.Append(ResourceUtilities.GetResourceString("LogTaskInputs.Truncated"));
                        break;
                    }
                }

                return(sb.ToString());
            }
        }
 private void SetImageSource(Bitmap bmp)
 {
     seeImageView.imageBox2.Source = ResourceUtilities.ConvertToImageSource(bmp);
 }
Beispiel #11
0
 private static Exception InvalidVersionFormat()
 {
     return(new FormatException(ResourceUtilities.GetResourceString(nameof(InvalidVersionFormat))));
 }
Beispiel #12
0
        public static string SerializeCaches(IConfigCache configCache, IResultsCache resultsCache, string outputCacheFile)
        {
            ErrorUtilities.VerifyThrowInternalNull(outputCacheFile, nameof(outputCacheFile));

            try
            {
                if (string.IsNullOrWhiteSpace(outputCacheFile))
                {
                    return(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("EmptyOutputCacheFile"));
                }

                var fullPath = FileUtilities.NormalizePath(outputCacheFile);

                Directory.CreateDirectory(Path.GetDirectoryName(fullPath));

                using (var fileStream = File.OpenWrite(fullPath))
                {
                    var translator = BinaryTranslator.GetWriteTranslator(fileStream);

                    ConfigCache  configCacheToSerialize  = null;
                    ResultsCache resultsCacheToSerialize = null;

                    switch (configCache)
                    {
                    case ConfigCache asConfigCache:
                        configCacheToSerialize = asConfigCache;
                        break;

                    case ConfigCacheWithOverride configCacheWithOverride:
                        configCacheToSerialize = configCacheWithOverride.CurrentCache;
                        break;

                    default:
                        ErrorUtilities.ThrowInternalErrorUnreachable();
                        break;
                    }

                    switch (resultsCache)
                    {
                    case ResultsCache asResultsCache:
                        resultsCacheToSerialize = asResultsCache;
                        break;

                    case ResultsCacheWithOverride resultsCacheWithOverride:
                        resultsCacheToSerialize = resultsCacheWithOverride.CurrentCache;
                        break;

                    default:
                        ErrorUtilities.ThrowInternalErrorUnreachable();
                        break;
                    }

                    translator.Translate(ref configCacheToSerialize);
                    translator.Translate(ref resultsCacheToSerialize);
                }
            }
            catch (Exception e)
            {
                return(ResourceUtilities.FormatResourceStringIgnoreCodeAndKeyword("ErrorWritingCacheFile", outputCacheFile, e.Message));
            }

            return(null);
        }
Beispiel #13
0
 public object GetResource(string resource, string language)
 {
     return(ResourceUtilities.GetResource(resource, language));
 }
Beispiel #14
0
        private void NodeLocalEngineLoop()
        {
            buildInProgress = true;

            // Create a logging service for this build request
            localEngine =
                new Engine(parentGlobalProperties, toolsetSearchLocations, 1 /* cpus */, true /* child node */, this.nodeId, parentStartupDirectory, null);
            localEngine.Router.ChildMode  = true;
            localEngine.Router.ParentNode = this;

            this.outProcLoggingService = new EngineLoggingServicesOutProc(this, localEngine.FlushRequestEvent);

            if (nodeLoggers.Length != 0)
            {
                foreach (LoggerDescription loggerDescription in nodeLoggers)
                {
                    IForwardingLogger newLogger = null;
                    bool exitedDueToError       = true;
                    try
                    {
                        newLogger = loggerDescription.CreateForwardingLogger();
                        // Check if the class was not found in the assembly
                        if (newLogger == null)
                        {
                            InternalLoggerException.Throw(null, null, "FatalErrorWhileInitializingLogger", true, loggerDescription.Name);
                        }
                        newLogger.Verbosity  = loggerDescription.Verbosity;
                        newLogger.Parameters = loggerDescription.LoggerSwitchParameters;
                        newLogger.NodeId     = nodeId;
                        EventRedirector newRedirector = new EventRedirector(loggerDescription.LoggerId, outProcLoggingService);
                        newLogger.BuildEventRedirector = newRedirector;
                        exitedDueToError = false;
                    }
                    // Polite logger failure
                    catch (LoggerException e)
                    {
                        ReportUnhandledError(e);
                    }
                    // Logger class was not found
                    catch (InternalLoggerException e)
                    {
                        ReportUnhandledError(e);
                    }
                    catch (Exception e)
                    {
                        // Wrap the exception in a InternalLoggerException and send it to the parent node
                        string errorCode;
                        string helpKeyword;
                        string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "FatalErrorWhileInitializingLogger", loggerDescription.Name);
                        ReportUnhandledError(new InternalLoggerException(message, e, null, errorCode, helpKeyword, true));
                    }

                    // If there was a failure registering loggers, null out the engine pointer
                    if (exitedDueToError)
                    {
                        localEngine = null;
                        return;
                    }

                    localEngine.RegisterLogger(newLogger);
                }

                localEngine.ExternalLoggingServices = outProcLoggingService;
            }

            // Hook up logging service to forward all events to the central engine if necessary
            if (centralizedLogging)
            {
                if (nodeLoggers.Length != 0)
                {
                    localEngine.LoggingServices.ForwardingService = outProcLoggingService;
                    localEngine.ExternalLoggingServices           = outProcLoggingService;
                }
                else
                {
                    localEngine.LoggingServices = outProcLoggingService;
                }
            }

            localEngine.LoggingServices.OnlyLogCriticalEvents = this.logOnlyCriticalEvents;

            if (!useBreadthFirstTraversal)
            {
                localEngine.PostEngineCommand(new ChangeTraversalTypeCommand(useBreadthFirstTraversal, true));
            }

            // Post all the requests that passed in while the engine was being constructed
            // into the engine queue
            lock (buildRequests)
            {
                while (buildRequests.Count != 0)
                {
                    BuildRequest buildRequest = buildRequests.Dequeue();
                    localEngine.PostBuildRequest(buildRequest);
                }
            }

            try
            {
                // If there are forwarding loggers registered - generate a custom  build started
                if (nodeLoggers.Length > 0)
                {
                    localEngine.LoggingServices.LogBuildStarted(EngineLoggingServicesInProc.CENTRAL_ENGINE_EVENTSOURCE);
                    localEngine.LoggingServices.ProcessPostedLoggingEvents();
                }

                // Trigger the actual build if shutdown was not called while the engine was being initialized
                if (!nodeShutdown)
                {
                    localEngine.EngineBuildLoop(null);
                }
            }
            catch (Exception e)
            {
                // Unhandled exception during execution. The node has to be shutdown.
                ReportUnhandledError(e);
            }
            finally
            {
                if (localEngine != null)
                {
                    // Flush all the messages associated before shutting down
                    localEngine.LoggingServices.ProcessPostedLoggingEvents();

                    NodeManager nodeManager = localEngine.NodeManager;

                    // If the local engine is already shutting down, the TEM will be nulled out
                    if (nodeManager.TaskExecutionModule != null && nodeManager.TaskExecutionModule.TaskExecutionTime != 0)
                    {
                        TimeSpan taskTimeSpan = new TimeSpan(localEngine.NodeManager.TaskExecutionModule.TaskExecutionTime);
                        totalTaskTime = (int)taskTimeSpan.TotalMilliseconds;
                    }
                    localEngine.Shutdown();
                }
                // Flush all the events to the parent engine
                outProcLoggingService.ProcessPostedLoggingEvents();
                // Indicate that the node logger thread should exit
                exitNodeEvent.Set();
            }
        }
Beispiel #15
0
        /// <summary>
        /// Gets the delta time of the physics (?) update.  First it confirms the game is in a valid state.  Then it calculats
        /// the time between physics update by comparing with Planetarium.GetUniversalTime() and GetMaxDeltaTime().
        /// </summary>
        /// <returns>The delta time.</returns>
        protected double GetDeltaTimex()
        {
            if (Time.timeSinceLevelLoad < 1.0f || !FlightGlobals.ready)
            {
                //Error:  Not sure what this error is for...maybe not enough time since load?
                Debug.Log(this.GetType().Name + "WARNING:  check timeSinceLevelLoad/FlightGlobals");
                Debug.Log(this.GetType().Name + "timeSinceLevelLoad = " + Time.timeSinceLevelLoad);
                Debug.Log(this.GetType().Name + "FlightGlobals.ready = " + !FlightGlobals.ready);
                return(-1);
            }

            if (Math.Abs(lastUpdateTime) < float.Epsilon)
            {
                //Error:  Just started running
                Debug.Log(this.GetType().Name + "ERROR:  check lastUpdateTime");
                Debug.Log(this.GetType().Name + "lastUpdateTime = " + lastUpdateTime);
                lastUpdateTime = Planetarium.GetUniversalTime();
                return(-1);
            }

            var deltaTime = Math.Min(Planetarium.GetUniversalTime() - lastUpdateTime, ResourceUtilities.GetMaxDeltaTime());

            return(deltaTime);

            //why is deltaTime == 0?
            //return deltaTime;
        }
Beispiel #16
0
        /// <summary>
        /// Reads a plan for the specified submission Id.
        /// </summary>
        public void ReadPlan(int submissionId, ILoggingService loggingService, BuildEventContext buildEventContext)
        {
            if (!BuildParameters.EnableBuildPlan)
            {
                return;
            }

            SchedulableRequest rootRequest = GetRootRequest(submissionId);

            if (rootRequest == null)
            {
                return;
            }

            string planName = GetPlanName(rootRequest);

            if (String.IsNullOrEmpty(planName))
            {
                return;
            }

            if (!FileSystems.Default.FileExists(planName))
            {
                return;
            }

            try
            {
                using (StreamReader file = new StreamReader(File.Open(planName, FileMode.Open)))
                {
                    ReadTimes(file);
                    ReadHierarchy(file);
                }

                if (_configIdToData.Count > 0)
                {
                    AnalyzeData();
                }
            }
            catch (IOException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceStringStripCodeAndKeyword("CantReadBuildPlan", planName));
            }
            catch (InvalidDataException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceStringStripCodeAndKeyword("BuildPlanCorrupt", planName));
            }
            catch (FormatException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceStringStripCodeAndKeyword("BuildPlanCorrupt", planName));
            }
        }
Beispiel #17
0
        /// <summary>
        /// Load content of Platform.xml
        /// </summary>
        private void LoadManifestFile()
        {
            /*
             * Platform.xml format:
             *
             * <ApplicationPlatform name="UAP" friendlyName="Universal Application Platform" version="1.0.0.0">
             *    <DependentPlatform name="UAP" version="1.0.0.0" />
             *    <ContainedApiContracts>
             *       <ApiContract name="UAP" version="1.0.0.0" />
             *    </ContainedApiContracts>
             * </ApplicationPlatform>
             */
            try
            {
                string platformManifestPath = Path.Combine(_pathToManifest, "Platform.xml");

                if (File.Exists(platformManifestPath))
                {
                    XmlDocument       doc            = new XmlDocument();
                    XmlReaderSettings readerSettings = new XmlReaderSettings();
                    readerSettings.DtdProcessing = DtdProcessing.Ignore;

                    using (XmlReader xmlReader = XmlReader.Create(platformManifestPath, readerSettings))
                    {
                        doc.Load(xmlReader);
                    }

                    XmlElement rootElement = null;

                    foreach (XmlNode childNode in doc.ChildNodes)
                    {
                        if (childNode.NodeType == XmlNodeType.Element &&
                            String.Equals(childNode.Name, Elements.ApplicationPlatform, StringComparison.Ordinal))
                        {
                            rootElement = (XmlElement)childNode;
                            break;
                        }
                    }

                    DependentPlatforms = new List <DependentPlatform>();
                    ApiContracts       = new List <ApiContract>();

                    if (rootElement != null)
                    {
                        Name            = rootElement.GetAttribute(Attributes.Name);
                        FriendlyName    = rootElement.GetAttribute(Attributes.FriendlyName);
                        PlatformVersion = rootElement.GetAttribute(Attributes.Version);

                        foreach (XmlNode childNode in rootElement.ChildNodes)
                        {
                            XmlElement childElement = childNode as XmlElement;
                            if (childElement == null)
                            {
                                continue;
                            }

                            if (ApiContract.IsContainedApiContractsElement(childElement.Name))
                            {
                                ApiContract.ReadContractsElement(childElement, ApiContracts);
                            }
                            else if (ApiContract.IsVersionedContentElement(childElement.Name))
                            {
                                bool versionedContent = false;
                                bool.TryParse(childElement.InnerText, out versionedContent);
                                this.VersionedContent = versionedContent;
                            }
                            else if (String.Equals(childElement.Name, Elements.DependentPlatform, StringComparison.Ordinal))
                            {
                                DependentPlatforms.Add(new DependentPlatform(childElement.GetAttribute(Attributes.Name), childElement.GetAttribute(Attributes.Version)));
                            }
                        }
                    }
                }
                else
                {
                    this.ReadErrorMessage = ResourceUtilities.FormatResourceString("PlatformManifest.MissingPlatformXml", platformManifestPath);
                }
            }
            catch (Exception e)
            {
                if (ExceptionHandling.IsCriticalException(e))
                {
                    throw;
                }

                this.ReadErrorMessage = e.Message;
            }
        }
Beispiel #18
0
        /// <summary>
        /// Writes a plan for the specified submission id.
        /// </summary>
        public void WritePlan(int submissionId, ILoggingService loggingService, BuildEventContext buildEventContext)
        {
            if (!BuildParameters.EnableBuildPlan)
            {
                return;
            }

            SchedulableRequest rootRequest = GetRootRequest(submissionId);

            if (rootRequest == null)
            {
                return;
            }

            string planName = GetPlanName(rootRequest);

            if (String.IsNullOrEmpty(planName))
            {
                return;
            }

            try
            {
                using (StreamWriter file = new StreamWriter(File.Open(planName, FileMode.Create)))
                {
                    // Write the accumulated configuration times.
                    Dictionary <int, double> accumulatedTimeByConfiguration = new Dictionary <int, double>();
                    RecursiveAccumulateConfigurationTimes(rootRequest, accumulatedTimeByConfiguration);

                    List <int> configurationsInOrder = new List <int>(accumulatedTimeByConfiguration.Keys);
                    configurationsInOrder.Sort();
                    foreach (int configId in configurationsInOrder)
                    {
                        file.WriteLine(String.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", configId, accumulatedTimeByConfiguration[configId], _configCache[configId].ProjectFullPath));
                    }

                    file.WriteLine();

                    // Write out the dependency information.
                    RecursiveWriteDependencies(file, rootRequest);
                }
            }
            catch (IOException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceStringStripCodeAndKeyword("CantWriteBuildPlan", planName));
            }
        }
Beispiel #19
0
        /// <summary>
        /// Apply a parameter
        /// </summary>
        private void ApplyFileLoggerParameter(string parameterName, string parameterValue)
        {
            if (String.Compare("LOGFILE", parameterName, StringComparison.OrdinalIgnoreCase) == 0)
            {
                if (string.IsNullOrEmpty(parameterValue))
                {
                    string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword("InvalidFileLoggerFile", string.Empty, ResourceUtilities.GetResourceString("logfilePathNullOrEmpty"));
                    throw new LoggerException(message);
                }

                // Set log file to the right half of the parameter string and then remove it as it is going to be replaced in Initialize
                _logFile = parameterValue;
                int indexOfParameter = _parameters.IndexOf(parameterName + s_fileLoggerParameterValueSplitCharacter[0] + parameterValue, 0, StringComparison.OrdinalIgnoreCase);
                int length           = ((string)(parameterName + s_fileLoggerParameterValueSplitCharacter[0] + parameterValue)).Length;
                // Check to see if the next char is a ; if so remove that as well
                if ((indexOfParameter + length) < _parameters.Length && _parameters[indexOfParameter + length] == ';')
                {
                    length++;
                }
                _parameters = _parameters.Remove(indexOfParameter, length);
            }
        }
        /// <summary>
        /// Initialize this class if it hasn't been initialized yet.
        /// </summary>
        private void LazyInitialize()
        {
            if (_isInitialized)
            {
                return;
            }

            _isInitialized = true;

            // Crack the search path just one time.
            Match match = s_crackAssemblyFoldersFromConfigSentinel.Value.Match(this.searchPathElement);

            _wasMatch = false;

            if (match.Success)
            {
                _targetRuntimeVersion     = match.Groups["TARGETRUNTIMEVERSION"].Value.Trim();
                _assemblyFolderConfigFile = match.Groups["ASSEMBLYFOLDERCONFIGFILE"].Value.Trim();

                if (_targetRuntimeVersion.Length != 0)
                {
                    // Tolerate version keys that don't begin with "v" as these could come from user input
                    if (!_targetRuntimeVersion.StartsWith("v", StringComparison.OrdinalIgnoreCase))
                    {
                        _targetRuntimeVersion = _targetRuntimeVersion.Insert(0, "v");
                    }

                    _wasMatch = true;

                    bool   useCache = Environment.GetEnvironmentVariable("MSBUILDDISABLEASSEMBLYFOLDERSEXCACHE") == null;
                    string key      = "6f7de854-47fe-4ae2-9cfe-9b33682abd91" + searchPathElement;

                    if (useCache && _buildEngine != null)
                    {
                        _assemblyFoldersCache = _buildEngine.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.Build) as AssemblyFoldersFromConfigCache;
                    }

                    if (_assemblyFoldersCache == null)
                    {
                        // This should never happen. Microsoft.Common.CurrentVersion.targets will not specify a AssemblyFoldersFromConfig search path
                        // if the specified (or default) file is not found.
                        ErrorUtilities.VerifyThrow(File.Exists(_assemblyFolderConfigFile),
                                                   $"The AssemblyFolders config file specified does not exist: {_assemblyFolderConfigFile}");

                        try
                        {
                            AssemblyFoldersFromConfig assemblyFolders = new AssemblyFoldersFromConfig(_assemblyFolderConfigFile, _targetRuntimeVersion, targetProcessorArchitecture);
                            _assemblyFoldersCache = new AssemblyFoldersFromConfigCache(assemblyFolders, fileExists);
                            if (useCache)
                            {
                                _buildEngine?.RegisterTaskObject(key, _assemblyFoldersCache, RegisteredTaskObjectLifetime.Build, true /* dispose early ok*/);
                            }
                        }
                        catch (SerializationException e)
                        {
                            _taskLogger.LogError(ResourceUtilities.GetResourceString("ResolveAssemblyReference.AssemblyFoldersConfigFileMalformed"), _assemblyFolderConfigFile, e.Message);
                            return;
                        }
                    }

                    fileExists = _assemblyFoldersCache.FileExists;
                }
            }
        }
Beispiel #21
0
        private void DetectCycles(
            IReadOnlyCollection <ProjectGraphNode> entryPointNodes,
            ProjectInterpretation projectInterpretation,
            Dictionary <ConfigurationMetadata, ParsedProject> allParsedProjects)
        {
            var nodeStates = new Dictionary <ProjectGraphNode, NodeVisitationState>();

            foreach (var entryPointNode in entryPointNodes)
            {
                if (!nodeStates.TryGetValue(entryPointNode, out NodeVisitationState state))
                {
                    VisitNode(entryPointNode, nodeStates);
                }
                else
                {
                    ErrorUtilities.VerifyThrow(
                        state == NodeVisitationState.Processed,
                        "entrypoints should get processed after a call to detect cycles");
                }
            }

            return;

            (bool success, List <string> projectsInCycle) VisitNode(
                ProjectGraphNode node,
                IDictionary <ProjectGraphNode, NodeVisitationState> nodeState)
            {
                nodeState[node] = NodeVisitationState.InProcess;

                foreach (var referenceNode in node.ProjectReferences)
                {
                    if (nodeState.TryGetValue(referenceNode, out var projectReferenceNodeState))
                    {
                        // Because this is a depth-first search, we should only encounter new nodes or nodes whose subgraph has been completely processed.
                        // If we encounter a node that is currently being processed(InProcess state), it must be one of the ancestors in a circular dependency.
                        if (projectReferenceNodeState == NodeVisitationState.InProcess)
                        {
                            if (node.Equals(referenceNode))
                            {
                                // the project being evaluated has a reference to itself
                                var selfReferencingProjectString =
                                    FormatCircularDependencyError(new List <string> {
                                    node.ProjectInstance.FullPath, node.ProjectInstance.FullPath
                                });
                                throw new CircularDependencyException(
                                          string.Format(
                                              ResourceUtilities.GetResourceString("CircularDependencyInProjectGraph"),
                                              selfReferencingProjectString));
                            }

                            // the project being evaluated has a circular dependency involving multiple projects
                            // add this project to the list of projects involved in cycle
                            var projectsInCycle = new List <string> {
                                referenceNode.ProjectInstance.FullPath
                            };
                            return(false, projectsInCycle);
                        }
                    }
                    else
                    {
                        // recursively process newly discovered references
                        var loadReference = VisitNode(referenceNode, nodeState);
                        if (!loadReference.success)
                        {
                            if (loadReference.projectsInCycle[0].Equals(node.ProjectInstance.FullPath))
                            {
                                // we have reached the nth project in the cycle, form error message and throw
                                loadReference.projectsInCycle.Add(referenceNode.ProjectInstance.FullPath);
                                loadReference.projectsInCycle.Add(node.ProjectInstance.FullPath);

                                var errorMessage = FormatCircularDependencyError(loadReference.projectsInCycle);
                                throw new CircularDependencyException(
                                          string.Format(
                                              ResourceUtilities.GetResourceString("CircularDependencyInProjectGraph"),
                                              errorMessage));
                            }

                            // this is one of the projects in the circular dependency
                            // update the list of projects in cycle and return the list to the caller
                            loadReference.projectsInCycle.Add(referenceNode.ProjectInstance.FullPath);
                            return(false, loadReference.projectsInCycle);
                        }
                    }
                }

                nodeState[node] = NodeVisitationState.Processed;
                return(true, null);
            }
        }
        /// <summary>
        /// Creates a new MSBuild process
        /// </summary>
        private int LaunchNode(string msbuildLocation, string commandLineArgs)
        {
            // Should always have been set already.
            ErrorUtilities.VerifyThrowInternalLength(msbuildLocation, "msbuildLocation");

            if (!File.Exists(msbuildLocation))
            {
                throw new BuildAbortedException(ResourceUtilities.FormatResourceString("CouldNotFindMSBuildExe", msbuildLocation));
            }

            // Repeat the executable name as the first token of the command line because the command line
            // parser logic expects it and will otherwise skip the first argument
            commandLineArgs = msbuildLocation + " " + commandLineArgs;

            BackendNativeMethods.STARTUP_INFO startInfo = new BackendNativeMethods.STARTUP_INFO();
            startInfo.cb = Marshal.SizeOf(startInfo);

            // Null out the process handles so that the parent process does not wait for the child process
            // to exit before it can exit.
            uint creationFlags = BackendNativeMethods.NORMALPRIORITYCLASS;

            startInfo.dwFlags = BackendNativeMethods.STARTFUSESTDHANDLES;

            if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDNODEWINDOW")))
            {
                startInfo.hStdError  = BackendNativeMethods.InvalidHandle;
                startInfo.hStdInput  = BackendNativeMethods.InvalidHandle;
                startInfo.hStdOutput = BackendNativeMethods.InvalidHandle;
                creationFlags        = creationFlags | BackendNativeMethods.CREATENOWINDOW;
            }
            else
            {
                creationFlags = creationFlags | BackendNativeMethods.CREATE_NEW_CONSOLE;
            }

            BackendNativeMethods.SECURITY_ATTRIBUTES processSecurityAttributes = new BackendNativeMethods.SECURITY_ATTRIBUTES();
            BackendNativeMethods.SECURITY_ATTRIBUTES threadSecurityAttributes  = new BackendNativeMethods.SECURITY_ATTRIBUTES();
            processSecurityAttributes.nLength = Marshal.SizeOf(processSecurityAttributes);
            threadSecurityAttributes.nLength  = Marshal.SizeOf(threadSecurityAttributes);

            BackendNativeMethods.PROCESS_INFORMATION processInfo = new BackendNativeMethods.PROCESS_INFORMATION();

            string appName = msbuildLocation;

            CommunicationsUtilities.Trace("Launching node from {0}", msbuildLocation);
            bool result = BackendNativeMethods.CreateProcess
                          (
                msbuildLocation,
                commandLineArgs,
                ref processSecurityAttributes,
                ref threadSecurityAttributes,
                false,
                creationFlags,
                BackendNativeMethods.NullPtr,
                null,
                ref startInfo,
                out processInfo
                          );

            if (!result)
            {
                // Creating an instance of this exception calls GetLastWin32Error and also converts it to a user-friendly string.
                System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception();

                CommunicationsUtilities.Trace
                (
                    "Failed to launch node from {0}. System32 Error code {1}. Description {2}. CommandLine: {2}",
                    msbuildLocation,
                    e.NativeErrorCode.ToString(CultureInfo.InvariantCulture),
                    e.Message,
                    commandLineArgs
                );

                throw new NodeFailedToLaunchException(e.NativeErrorCode.ToString(CultureInfo.InvariantCulture), e.Message);
            }

            CommunicationsUtilities.Trace("Successfully launched msbuild.exe node with PID {0}", processInfo.dwProcessId);
            return(processInfo.dwProcessId);
        }
Beispiel #23
0
        /// <summary>
        /// Creates a new MSBuild process
        /// </summary>
        private Process LaunchNode(string msbuildLocation, string commandLineArgs)
        {
            // Should always have been set already.
            ErrorUtilities.VerifyThrowInternalLength(msbuildLocation, nameof(msbuildLocation));

            if (!FileSystems.Default.FileExists(msbuildLocation))
            {
                throw new BuildAbortedException(ResourceUtilities.FormatResourceStringStripCodeAndKeyword("CouldNotFindMSBuildExe", msbuildLocation));
            }

            // Repeat the executable name as the first token of the command line because the command line
            // parser logic expects it and will otherwise skip the first argument
            commandLineArgs = msbuildLocation + " " + commandLineArgs;

            BackendNativeMethods.STARTUP_INFO startInfo = new BackendNativeMethods.STARTUP_INFO();
            startInfo.cb = Marshal.SizeOf <BackendNativeMethods.STARTUP_INFO>();

            // Null out the process handles so that the parent process does not wait for the child process
            // to exit before it can exit.
            uint creationFlags = 0;

            if (Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout)
            {
                creationFlags = BackendNativeMethods.NORMALPRIORITYCLASS;
            }

            if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDNODEWINDOW")))
            {
                if (!Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout)
                {
                    // Redirect the streams of worker nodes so that this MSBuild.exe's
                    // parent doesn't wait on idle worker nodes to close streams
                    // after the build is complete.
                    startInfo.hStdError  = BackendNativeMethods.InvalidHandle;
                    startInfo.hStdInput  = BackendNativeMethods.InvalidHandle;
                    startInfo.hStdOutput = BackendNativeMethods.InvalidHandle;
                    startInfo.dwFlags    = BackendNativeMethods.STARTFUSESTDHANDLES;
                    creationFlags       |= BackendNativeMethods.CREATENOWINDOW;
                }
            }
            else
            {
                creationFlags |= BackendNativeMethods.CREATE_NEW_CONSOLE;
            }

            BackendNativeMethods.SECURITY_ATTRIBUTES processSecurityAttributes = new BackendNativeMethods.SECURITY_ATTRIBUTES();
            BackendNativeMethods.SECURITY_ATTRIBUTES threadSecurityAttributes  = new BackendNativeMethods.SECURITY_ATTRIBUTES();
            processSecurityAttributes.nLength = Marshal.SizeOf <BackendNativeMethods.SECURITY_ATTRIBUTES>();
            threadSecurityAttributes.nLength  = Marshal.SizeOf <BackendNativeMethods.SECURITY_ATTRIBUTES>();

            CommunicationsUtilities.Trace("Launching node from {0}", msbuildLocation);

            string exeName = msbuildLocation;

#if RUNTIME_TYPE_NETCORE || MONO
            // Mono automagically uses the current mono, to execute a managed assembly
            if (!NativeMethodsShared.IsMono)
            {
                // Run the child process with the same host as the currently-running process.
                exeName         = GetCurrentHost();
                commandLineArgs = "\"" + msbuildLocation + "\" " + commandLineArgs;
            }
#endif

            if (!NativeMethodsShared.IsWindows)
            {
                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.FileName  = exeName;
                processStartInfo.Arguments = commandLineArgs;
                if (!Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout)
                {
                    // Redirect the streams of worker nodes so that this MSBuild.exe's
                    // parent doesn't wait on idle worker nodes to close streams
                    // after the build is complete.
                    processStartInfo.RedirectStandardInput  = true;
                    processStartInfo.RedirectStandardOutput = true;
                    processStartInfo.RedirectStandardError  = true;
                    processStartInfo.CreateNoWindow         = (creationFlags | BackendNativeMethods.CREATENOWINDOW) == BackendNativeMethods.CREATENOWINDOW;
                }
                processStartInfo.UseShellExecute = false;

                Process process;
                try
                {
                    process = Process.Start(processStartInfo);
                }
                catch (Exception ex)
                {
                    CommunicationsUtilities.Trace
                    (
                        "Failed to launch node from {0}. CommandLine: {1}" + Environment.NewLine + "{2}",
                        msbuildLocation,
                        commandLineArgs,
                        ex.ToString()
                    );

                    throw new NodeFailedToLaunchException(ex);
                }

                CommunicationsUtilities.Trace("Successfully launched {1} node with PID {0}", process.Id, exeName);
                return(process);
            }
            else
            {
#if RUNTIME_TYPE_NETCORE
                if (NativeMethodsShared.IsWindows)
                {
                    // Repeat the executable name in the args to suit CreateProcess
                    commandLineArgs = "\"" + exeName + "\" " + commandLineArgs;
                }
#endif

                BackendNativeMethods.PROCESS_INFORMATION processInfo = new BackendNativeMethods.PROCESS_INFORMATION();

                bool result = BackendNativeMethods.CreateProcess
                              (
                    exeName,
                    commandLineArgs,
                    ref processSecurityAttributes,
                    ref threadSecurityAttributes,
                    false,
                    creationFlags,
                    BackendNativeMethods.NullPtr,
                    null,
                    ref startInfo,
                    out processInfo
                              );

                if (!result)
                {
                    // Creating an instance of this exception calls GetLastWin32Error and also converts it to a user-friendly string.
                    System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception();

                    CommunicationsUtilities.Trace
                    (
                        "Failed to launch node from {0}. System32 Error code {1}. Description {2}. CommandLine: {2}",
                        msbuildLocation,
                        e.NativeErrorCode.ToString(CultureInfo.InvariantCulture),
                        e.Message,
                        commandLineArgs
                    );

                    throw new NodeFailedToLaunchException(e.NativeErrorCode.ToString(CultureInfo.InvariantCulture), e.Message);
                }

                int childProcessId = processInfo.dwProcessId;

                if (processInfo.hProcess != IntPtr.Zero && processInfo.hProcess != NativeMethods.InvalidHandle)
                {
                    NativeMethodsShared.CloseHandle(processInfo.hProcess);
                }

                if (processInfo.hThread != IntPtr.Zero && processInfo.hThread != NativeMethods.InvalidHandle)
                {
                    NativeMethodsShared.CloseHandle(processInfo.hThread);
                }

                CommunicationsUtilities.Trace("Successfully launched {1} node with PID {0}", childProcessId, exeName);
                return(Process.GetProcessById(childProcessId));
            }
        }
        private string GenerateCode(out string extension)
        {
            extension = null;
            bool haveGeneratedContent = false;

            CodeDomProvider provider;

            try
            {
                provider = CodeDomProvider.CreateProvider(Language);
            }
            catch (SystemException e) when
#if FEATURE_SYSTEM_CONFIGURATION
                (e is ConfigurationException || e is SecurityException)
#else
            (e.GetType().Name == "ConfigurationErrorsException") //TODO: catch specific exception type once it is public https://github.com/dotnet/corefx/issues/40456
#endif
            {
                Log.LogErrorWithCodeFromResources("WriteCodeFragment.CouldNotCreateProvider", Language, e.Message);
                return(null);
            }

            extension = provider.FileExtension;

            var unit = new CodeCompileUnit();

            var globalNamespace = new CodeNamespace();
            unit.Namespaces.Add(globalNamespace);

            // Declare authorship. Unfortunately CodeDOM puts this comment after the attributes.
            string comment = ResourceUtilities.GetResourceString("WriteCodeFragment.Comment");
            globalNamespace.Comments.Add(new CodeCommentStatement(comment));

            if (AssemblyAttributes == null)
            {
                return(String.Empty);
            }

            // For convenience, bring in the namespaces, where many assembly attributes lie
            globalNamespace.Imports.Add(new CodeNamespaceImport("System"));
            globalNamespace.Imports.Add(new CodeNamespaceImport("System.Reflection"));

            foreach (ITaskItem attributeItem in AssemblyAttributes)
            {
                var attribute = new CodeAttributeDeclaration(new CodeTypeReference(attributeItem.ItemSpec));

                // Some attributes only allow positional constructor arguments, or the user may just prefer them.
                // To set those, use metadata names like "_Parameter1", "_Parameter2" etc.
                // If a parameter index is skipped, it's an error.
                IDictionary customMetadata = attributeItem.CloneCustomMetadata();

                var orderedParameters = new List <CodeAttributeArgument>(new CodeAttributeArgument[customMetadata.Count + 1] /* max possible slots needed */);
                var namedParameters   = new List <CodeAttributeArgument>();

                foreach (DictionaryEntry entry in customMetadata)
                {
                    string name  = (string)entry.Key;
                    string value = (string)entry.Value;

                    if (name.StartsWith("_Parameter", StringComparison.OrdinalIgnoreCase))
                    {
                        if (!Int32.TryParse(name.Substring("_Parameter".Length), out int index))
                        {
                            Log.LogErrorWithCodeFromResources("General.InvalidValue", name, "WriteCodeFragment");
                            return(null);
                        }

                        if (index > orderedParameters.Count || index < 1)
                        {
                            Log.LogErrorWithCodeFromResources("WriteCodeFragment.SkippedNumberedParameter", index);
                            return(null);
                        }

                        // "_Parameter01" and "_Parameter1" would overwrite each other
                        orderedParameters[index - 1] = new CodeAttributeArgument(String.Empty, new CodePrimitiveExpression(value));
                    }
                    else
                    {
                        namedParameters.Add(new CodeAttributeArgument(name, new CodePrimitiveExpression(value)));
                    }
                }

                bool encounteredNull = false;
                for (int i = 0; i < orderedParameters.Count; i++)
                {
                    if (orderedParameters[i] == null)
                    {
                        // All subsequent args should be null, else a slot was missed
                        encounteredNull = true;
                        continue;
                    }

                    if (encounteredNull)
                    {
                        Log.LogErrorWithCodeFromResources("WriteCodeFragment.SkippedNumberedParameter", i + 1 /* back to 1 based */);
                        return(null);
                    }

                    attribute.Arguments.Add(orderedParameters[i]);
                }

                foreach (CodeAttributeArgument namedParameter in namedParameters)
                {
                    attribute.Arguments.Add(namedParameter);
                }

                unit.AssemblyCustomAttributes.Add(attribute);
                haveGeneratedContent = true;
            }

            var generatedCode = new StringBuilder();
            using (var writer = new StringWriter(generatedCode, CultureInfo.CurrentCulture))
            {
                provider.GenerateCodeFromCompileUnit(unit, writer, new CodeGeneratorOptions());
            }

            string code = generatedCode.ToString();

            // If we just generated infrastructure, don't bother returning anything
            // as there's no point writing the file
            return(haveGeneratedContent ? code : String.Empty);
        }
    }
Beispiel #25
0
        /// <remarks>
        /// Traverse an evaluated graph
        /// Maintain the state of each node (InProcess and Processed) to detect cycles
        /// returns false if loading the graph is not successful
        /// </remarks>
        private (bool success, List <string> projectsInCycle) DetectCycles(ProjectGraphNode node,
                                                                           Dictionary <ProjectGraphNode, NodeState> nodeState,
                                                                           ProjectCollection projectCollection,
                                                                           PropertyDictionary <ProjectPropertyInstance> globalProperties)
        {
            nodeState[node] = NodeState.InProcess;
            IEnumerable <ProjectItemInstance> projectReferenceItems = node.ProjectInstance.GetItems(MSBuildConstants.ProjectReferenceItemName);

            foreach (var projectReferenceToParse in projectReferenceItems)
            {
                string projectReferenceFullPath = projectReferenceToParse.GetMetadataValue(FullPathMetadataName);
                PropertyDictionary <ProjectPropertyInstance> projectReferenceGlobalProperties = GetProjectReferenceGlobalProperties(projectReferenceToParse, globalProperties);
                var projectReferenceConfigurationMetadata = new ConfigurationMetadata(projectReferenceFullPath, projectReferenceGlobalProperties);
                ProjectGraphNode projectReference         = _allParsedProjects[projectReferenceConfigurationMetadata];
                if (nodeState.TryGetValue(projectReference, out NodeState projectReferenceNodeState))
                {
                    // Because this is a depth-first search, we should only encounter new nodes or nodes whose subgraph has been completely processed.
                    // If we encounter a node that is currently being processed(InProcess state), it must be one of the ancestors in a circular dependency.
                    if (projectReferenceNodeState == NodeState.InProcess)
                    {
                        if (node.Equals(projectReference))
                        {
                            // the project being evaluated has a reference to itself
                            var selfReferencingProjectString = FormatCircularDependencyError(new List <string> {
                                node.ProjectInstance.FullPath, node.ProjectInstance.FullPath
                            });
                            throw new CircularDependencyException(string.Format(
                                                                      ResourceUtilities.GetResourceString("CircularDependencyInProjectGraph"),
                                                                      selfReferencingProjectString));
                        }
                        else
                        {
                            // the project being evaluated has a circular dependency involving multiple projects
                            // add this project to the list of projects involved in cycle
                            var projectsInCycle = new List <string> {
                                projectReferenceConfigurationMetadata.ProjectFullPath
                            };
                            return(false, projectsInCycle);
                        }
                    }
                }
                else
                {
                    // recursively process newly discovered references
                    var loadReference = DetectCycles(projectReference, nodeState, projectCollection,
                                                     projectReferenceGlobalProperties);
                    if (!loadReference.success)
                    {
                        if (loadReference.projectsInCycle[0].Equals(node.ProjectInstance.FullPath))
                        {
                            // we have reached the nth project in the cycle, form error message and throw
                            loadReference.projectsInCycle.Add(projectReferenceConfigurationMetadata.ProjectFullPath);
                            loadReference.projectsInCycle.Add(node.ProjectInstance.FullPath);
                            var errorMessage = FormatCircularDependencyError(loadReference.projectsInCycle);
                            throw new CircularDependencyException(string.Format(
                                                                      ResourceUtilities.GetResourceString("CircularDependencyInProjectGraph"),
                                                                      errorMessage));
                        }
                        else
                        {
                            // this is one of the projects in the circular dependency
                            // update the list of projects in cycle and return the list to the caller
                            loadReference.projectsInCycle.Add(projectReferenceConfigurationMetadata.ProjectFullPath);
                            return(false, loadReference.projectsInCycle);
                        }
                    }
                }
                ProjectGraphNode parsedProjectReference = _allParsedProjects[projectReferenceConfigurationMetadata];
                node.AddProjectReference(parsedProjectReference);
                parsedProjectReference.AddReferencingProject(node);
            }
            nodeState[node] = NodeState.Processed;
            return(true, null);
        }
Beispiel #26
0
        /// <summary>
        /// Instructs the MSBuild engine to build one or more project files whose locations are specified by the
        /// <see cref="Projects"/> property.
        /// </summary>
        /// <returns>true if all projects build successfully; false if any project fails</returns>
        public override bool Execute()
        {
            // If no projects were passed in, just return success.
            if ((Projects == null) || (Projects.Length == 0))
            {
                return(true);
            }

            // We have been asked to unescape all escaped characters before processing
            if (TargetAndPropertyListSeparators != null && TargetAndPropertyListSeparators.Length > 0)
            {
                ExpandAllTargetsAndProperties();
            }

            // Parse the global properties into a hashtable.
            if (!PropertyParser.GetTableWithEscaping(Log, ResourceUtilities.GetResourceString("General.GlobalProperties"), "Properties", Properties, out Dictionary <string, string> propertiesTable))
            {
                return(false);
            }

            // Parse out the properties to undefine, if any.
            string[] undefinePropertiesArray = null;
            if (!String.IsNullOrEmpty(RemoveProperties))
            {
                Log.LogMessageFromResources(MessageImportance.Low, "General.UndefineProperties");
                undefinePropertiesArray = RemoveProperties.Split(';');
                foreach (string property in undefinePropertiesArray)
                {
                    Log.LogMessageFromText($"  {property}", MessageImportance.Low);
                }
            }

            bool isRunningMultipleNodes = BuildEngine2.IsRunningMultipleNodes;

            // If we are in single proc mode and stopOnFirstFailure is true, we cannot build in parallel because
            // building in parallel sends all of the projects to the engine at once preventing us from not sending
            // any more projects after the first failure. Therefore, to preserve compatibility with whidbey if we are in this situation disable buildInParallel.
            if (!isRunningMultipleNodes && StopOnFirstFailure && BuildInParallel)
            {
                BuildInParallel = false;
                Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.NotBuildingInParallel");
            }

            // When the condition below is met, provide an information message indicating stopOnFirstFailure
            // will have no effect. The reason there will be no effect is, when buildInParallel is true
            // All project files will be submitted to the engine all at once, this mean there is no stopping for failures between projects.
            // When RunEachTargetSeparately is false, all targets will be submitted to the engine at once, this means there is no way to stop between target failures.
            // therefore the first failure seen will be the only failure seen.
            if (isRunningMultipleNodes && BuildInParallel && StopOnFirstFailure && !RunEachTargetSeparately)
            {
                Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.NoStopOnFirstFailure");
            }

            // This is a list of string[].  That is, each element in the list is a string[].  Each
            // string[] represents a set of target names to build.  Depending on the value
            // of the RunEachTargetSeparately parameter, we each just call the engine to run all
            // the targets together, or we call the engine separately for each target.
            List <string[]> targetLists = CreateTargetLists(Targets, RunEachTargetSeparately);

            bool             success       = true;
            List <ITaskItem> singleProject = null;

            bool[] skipProjects = null;

            if (BuildInParallel)
            {
                skipProjects = new bool[Projects.Length];
                for (int i = 0; i < skipProjects.Length; i++)
                {
                    skipProjects[i] = true;
                }
            }
            else
            {
                singleProject = new List <ITaskItem>(1)
                {
                    null
                };
            }

            // Read in each project file.  If there are any errors opening the file or parsing the XML,
            // raise an event and return False.  If any one of the projects fails to build, return False,
            // otherwise return True. If parallel build is requested we first check for file existence so
            // that we don't pass a non-existent file to IBuildEngine causing an exception
            for (int i = 0; i < Projects.Length; i++)
            {
                ITaskItem project = Projects[i];

                string projectPath = FileUtilities.AttemptToShortenPath(project.ItemSpec);

                if (StopOnFirstFailure && !success)
                {
                    // Inform the user that we skipped the remaining projects because StopOnFirstFailure=true.
                    Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingProjects");

                    // We have encountered a failure.  Caller has requested that we not
                    // continue with remaining projects.
                    break;
                }

                if (File.Exists(projectPath) || (_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Build))
                {
                    if (FileUtilities.IsVCProjFilename(projectPath))
                    {
                        Log.LogErrorWithCodeFromResources("MSBuild.ProjectUpgradeNeededToVcxProj", project.ItemSpec);
                        success = false;
                        continue;
                    }

                    // If we are building in parallel we want to only make one call to
                    // ExecuteTargets once we verified that all projects exist
                    if (!BuildInParallel)
                    {
                        singleProject[0] = project;

                        if (!ExecuteTargets
                            (
                                singleProject,
                                propertiesTable,
                                undefinePropertiesArray,
                                targetLists,
                                StopOnFirstFailure,
                                RebaseOutputs,
                                BuildEngine3,
                                Log,
                                _targetOutputs,
                                UseResultsCache,
                                UnloadProjectsOnCompletion,
                                ToolsVersion
                            )
                            )
                        {
                            success = false;
                        }
                    }
                    else
                    {
                        skipProjects[i] = false;
                    }
                }
                else
                {
                    if (_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Skip)
                    {
                        Log.LogMessageFromResources(MessageImportance.High, "MSBuild.ProjectFileNotFoundMessage", project.ItemSpec);
                    }
                    else
                    {
                        ErrorUtilities.VerifyThrow(_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Error, "skipNonexistentProjects has unexpected value {0}", _skipNonexistentProjects);
                        Log.LogErrorWithCodeFromResources("MSBuild.ProjectFileNotFound", project.ItemSpec);
                        success = false;
                    }
                }
            }

            // We need to build all the projects that were not skipped
            if (BuildInParallel)
            {
                success = BuildProjectsInParallel(propertiesTable, undefinePropertiesArray, targetLists, success, skipProjects);
            }

            return(success);
        }
Beispiel #27
0
        /// <summary>
        /// Writes a line from a resource string to the log, using the specified indentation.
        /// </summary>
        internal void WriteLinePrettyFromResource(int indentLevel, string resourceString, params object[] args)
        {
            string formattedString = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(resourceString, args);

            WriteLinePretty(indentLevel, formattedString);
        }
Beispiel #28
0
        /// <returns>True if the operation was successful</returns>
        internal static bool ExecuteTargets
        (
            List <ITaskItem> projects,
            Dictionary <string, string> propertiesTable,
            string[] undefineProperties,
            List <string[]> targetLists,
            bool stopOnFirstFailure,
            bool rebaseOutputs,
            IBuildEngine3 buildEngine,
            TaskLoggingHelper log,
            List <ITaskItem> targetOutputs,
            bool useResultsCache,
            bool unloadProjectsOnCompletion,
            string toolsVersion
        )
        {
            bool success = true;

            // We don't log a message about the project and targets we're going to
            // build, because it'll all be in the immediately subsequent ProjectStarted event.

            var projectDirectory             = new string[projects.Count];
            var projectNames                 = new string[projects.Count];
            var toolsVersions                = new string[projects.Count];
            var projectProperties            = new Dictionary <string, string> [projects.Count];
            var undefinePropertiesPerProject = new IList <string> [projects.Count];

            for (int i = 0; i < projectNames.Length; i++)
            {
                projectNames[i]      = null;
                projectProperties[i] = propertiesTable;

                if (projects[i] != null)
                {
                    // Retrieve projectDirectory only the first time.  It never changes anyway.
                    string projectPath = FileUtilities.AttemptToShortenPath(projects[i].ItemSpec);
                    projectDirectory[i] = Path.GetDirectoryName(projectPath);
                    projectNames[i]     = projects[i].ItemSpec;
                    toolsVersions[i]    = toolsVersion;

                    // If the user specified a different set of global properties for this project, then
                    // parse the string containing the properties
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("Properties")))
                    {
                        if (!PropertyParser.GetTableWithEscaping
                                (log, ResourceUtilities.FormatResourceString("General.OverridingProperties", projectNames[i]), "Properties", projects[i].GetMetadata("Properties").Split(';'),
                                out Dictionary <string, string> preProjectPropertiesTable)
                            )
                        {
                            return(false);
                        }
                        projectProperties[i] = preProjectPropertiesTable;
                    }

                    if (undefineProperties != null)
                    {
                        undefinePropertiesPerProject[i] = new List <string>(undefineProperties);
                    }

                    // If the user wanted to undefine specific global properties for this project, parse
                    // that string and remove them now.
                    string projectUndefineProperties = projects[i].GetMetadata("UndefineProperties");
                    if (!String.IsNullOrEmpty(projectUndefineProperties))
                    {
                        string[] propertiesToUndefine = projectUndefineProperties.Split(';');
                        if (undefinePropertiesPerProject[i] == null)
                        {
                            undefinePropertiesPerProject[i] = new List <string>(propertiesToUndefine.Length);
                        }

                        if (log != null && propertiesToUndefine.Length > 0)
                        {
                            log.LogMessageFromResources(MessageImportance.Low, "General.ProjectUndefineProperties", projectNames[i]);
                            foreach (string property in propertiesToUndefine)
                            {
                                undefinePropertiesPerProject[i].Add(property);
                                log.LogMessageFromText($"  {property}", MessageImportance.Low);
                            }
                        }
                    }

                    // If the user specified a different set of global properties for this project, then
                    // parse the string containing the properties
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("AdditionalProperties")))
                    {
                        if (!PropertyParser.GetTableWithEscaping
                                (log, ResourceUtilities.FormatResourceString("General.AdditionalProperties", projectNames[i]), "AdditionalProperties", projects[i].GetMetadata("AdditionalProperties").Split(';'),
                                out Dictionary <string, string> additionalProjectPropertiesTable)
                            )
                        {
                            return(false);
                        }
                        var combinedTable = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                        // First copy in the properties from the global table that not in the additional properties table
                        if (projectProperties[i] != null)
                        {
                            foreach (KeyValuePair <string, string> entry in projectProperties[i])
                            {
                                if (!additionalProjectPropertiesTable.ContainsKey(entry.Key))
                                {
                                    combinedTable.Add(entry.Key, entry.Value);
                                }
                            }
                        }
                        // Add all the additional properties
                        foreach (KeyValuePair <string, string> entry in additionalProjectPropertiesTable)
                        {
                            combinedTable.Add(entry.Key, entry.Value);
                        }
                        projectProperties[i] = combinedTable;
                    }

                    // If the user specified a different toolsVersion for this project - then override the setting
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("ToolsVersion")))
                    {
                        toolsVersions[i] = projects[i].GetMetadata("ToolsVersion");
                    }
                }
            }

            foreach (string[] targetList in targetLists)
            {
                if (stopOnFirstFailure && !success)
                {
                    // Inform the user that we skipped the remaining targets StopOnFirstFailure=true.
                    log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingTargets");

                    // We have encountered a failure.  Caller has requested that we not
                    // continue with remaining targets.
                    break;
                }

                // Send the project off to the build engine.  By passing in null to the
                // first param, we are indicating that the project to build is the same
                // as the *calling* project file.

                BuildEngineResult result =
                    buildEngine.BuildProjectFilesInParallel(projectNames, targetList, projectProperties, undefinePropertiesPerProject, toolsVersions, true /* ask that target outputs are returned in the buildengineresult */);

                bool currentTargetResult = result.Result;
                IList <IDictionary <string, ITaskItem[]> > targetOutputsPerProject = result.TargetOutputsPerProject;
                success = success && currentTargetResult;

                // If the engine was able to satisfy the build request
                if (currentTargetResult)
                {
                    for (int i = 0; i < projects.Count; i++)
                    {
                        IEnumerable <string> nonNullTargetList = targetList ?? targetOutputsPerProject[i].Keys;

                        foreach (string targetName in nonNullTargetList)
                        {
                            if (targetOutputsPerProject[i].ContainsKey(targetName))
                            {
                                ITaskItem[] outputItemsFromTarget = targetOutputsPerProject[i][targetName];

                                foreach (ITaskItem outputItemFromTarget in outputItemsFromTarget)
                                {
                                    // No need to rebase if the calling project is the same as the callee project
                                    // (project == null).  Also no point in trying to copy item metadata either,
                                    // because no items were passed into the Projects parameter!
                                    if (projects[i] != null)
                                    {
                                        // Rebase the output item paths if necessary.  No need to rebase if the calling
                                        // project is the same as the callee project (project == null).
                                        if (rebaseOutputs)
                                        {
                                            try
                                            {
                                                outputItemFromTarget.ItemSpec = Path.Combine(projectDirectory[i], outputItemFromTarget.ItemSpec);
                                            }
                                            catch (ArgumentException e)
                                            {
                                                log.LogWarningWithCodeFromResources(null, projects[i].ItemSpec, 0, 0, 0, 0, "MSBuild.CannotRebaseOutputItemPath", outputItemFromTarget.ItemSpec, e.Message);
                                            }
                                        }

                                        // Copy the custom item metadata from the "Projects" items to these
                                        // output items.
                                        projects[i].CopyMetadataTo(outputItemFromTarget);

                                        // Set a metadata on the output items called "MSBuildProjectFile" which tells you which project file produced this item.
                                        if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceProjectFile)))
                                        {
                                            outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceProjectFile, projects[i].GetMetadata(FileUtilities.ItemSpecModifiers.FullPath));
                                        }
                                    }

                                    // Set a metadata on the output items called "MSBuildTargetName" which tells you which target produced this item.
                                    if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceTargetName)))
                                    {
                                        outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceTargetName, targetName);
                                    }
                                }

                                targetOutputs.AddRange(outputItemsFromTarget);
                            }
                        }
                    }
                }
            }

            return(success);
        }
Beispiel #29
0
        /// <summary>
        /// Retrieves the list of dependencies this target needs to have built and moves the target to the next state.
        /// Never returns null.
        /// </summary>
        /// <returns>A collection of targets on which this target depends.</returns>
        internal List <TargetSpecification> GetDependencies(ProjectLoggingContext projectLoggingContext)
        {
            VerifyState(_state, TargetEntryState.Dependencies);

            // Resolve the target now, since from this point on we are going to be doing work with the actual instance.
            GetTargetInstance();

            // We first make sure no batching was attempted with the target's condition.
            // UNDONE: (Improvement) We want to allow this actually.  In order to do this we need to determine what the
            // batching buckets are, and if there are any which aren't empty, return our list of dependencies.
            // Only in the case where all bucket conditions fail do we want to skip the target entirely (and
            // this skip building the dependencies.)
            if (ExpressionShredder.ContainsMetadataExpressionOutsideTransform(_target.Condition))
            {
                ProjectErrorUtilities.ThrowInvalidProject(_target.ConditionLocation, "TargetConditionHasInvalidMetadataReference", _target.Name, _target.Condition);
            }

            // If condition is false (based on propertyBag), set this target's state to
            // "Skipped" since we won't actually build it.
            bool condition = ConditionEvaluator.EvaluateCondition
                             (
                _target.Condition,
                ParserOptions.AllowPropertiesAndItemLists,
                _expander,
                ExpanderOptions.ExpandPropertiesAndItems,
                _requestEntry.ProjectRootDirectory,
                _target.ConditionLocation,
                projectLoggingContext.LoggingService,
                projectLoggingContext.BuildEventContext,
                FileSystems.Default);

            if (!condition)
            {
                _targetResult = new TargetResult(Array.Empty <TaskItem>(), new WorkUnitResult(WorkUnitResultCode.Skipped, WorkUnitActionCode.Continue, null));
                _state        = TargetEntryState.Completed;

                if (!projectLoggingContext.LoggingService.OnlyLogCriticalEvents)
                {
                    // Expand the expression for the Log.  Since we know the condition evaluated to false, leave unexpandable properties in the condition so as not to cause an error
                    string expanded = _expander.ExpandIntoStringAndUnescape(_target.Condition, ExpanderOptions.ExpandPropertiesAndItems | ExpanderOptions.LeavePropertiesUnexpandedOnError, _target.ConditionLocation);

                    // By design: Not building dependencies. This is what NAnt does too.
                    // NOTE: In the original code, this was logged from the target logging context.  However, the target
                    // hadn't been "started" by then, so you'd get a target message outside the context of a started
                    // target.  In the Task builder (and original Task Engine), a Task Skipped message would be logged in
                    // the context of the target, not the task.  This should be the same, especially given that we
                    // wish to allow batching on the condition of a target.
                    var skippedTargetEventArgs = new TargetSkippedEventArgs(
                        ResourceUtilities.GetResourceString("TargetSkippedFalseCondition"),
                        _target.Name,
                        _target.Condition,
                        expanded)
                    {
                        BuildEventContext = projectLoggingContext.BuildEventContext,
                        TargetName        = _target.Name,
                        TargetFile        = _target.Location.File,
                        ParentTarget      = ParentEntry?.Target?.Name,
                        BuildReason       = BuildReason
                    };

                    projectLoggingContext.LogBuildEvent(skippedTargetEventArgs);
                }

                return(new List <TargetSpecification>());
            }

            var dependencies = _expander.ExpandIntoStringListLeaveEscaped(_target.DependsOnTargets, ExpanderOptions.ExpandPropertiesAndItems, _target.DependsOnTargetsLocation);
            List <TargetSpecification> dependencyTargets = new List <TargetSpecification>();

            foreach (string escapedDependency in dependencies)
            {
                string dependencyTargetName = EscapingUtilities.UnescapeAll(escapedDependency);
                dependencyTargets.Add(new TargetSpecification(dependencyTargetName, _target.DependsOnTargetsLocation));
            }

            _state = TargetEntryState.Execution;

            return(dependencyTargets);
        }
Beispiel #30
0
 private string TranslateKudos(string textToTranslate, CultureInfo culture)
 {
     return(ResourceUtilities.GetResourceValue(_resourceManager, textToTranslate, culture));
 }