private bool TryExecuteArgumentsToPipBuilder(
            JavaScriptProject project,
            QualifierId qualifierId,
            out string failureDetail,
            out Process process)
        {
            // We create a pip construction helper for each project
            var pipConstructionHelper = GetPipConstructionHelperForProject(project, qualifierId);

            using (var processBuilder = ProcessBuilder.Create(PathTable, m_context.GetPipDataBuilder()))
            {
                // Configure the process to add an assortment of settings: arguments, response file, etc.
                ConfigureProcessBuilder(processBuilder, project);

                // Process all predicted outputs and inputs, including the predicted project dependencies
                ProcessInputs(project, processBuilder);
                ProcessOutputs(project, processBuilder);

                // Try to schedule the process pip
                if (!pipConstructionHelper.TryAddProcess(processBuilder, out ProcessOutputs outputs, out process))
                {
                    failureDetail = "Failed to schedule the pip";
                    return(false);
                }

                m_processOutputsPerProject[project] = outputs;

                failureDetail = string.Empty;
                return(true);
            }
        }
Example #2
0
        private ProcessBuilder CreatePipBuilder(TestEnv env)
        {
            var processBuilder = ProcessBuilder.Create(env.PathTable, env.PipDataBuilderPool.GetInstance());

            var exe = FileArtifact.CreateSourceFile(AbsolutePath.Create(env.Context.PathTable, @"\\dummyPath\DummyFile.exe"));

            processBuilder.Executable = exe;
            processBuilder.AddInputFile(exe);
            return(processBuilder);
        }
Example #3
0
        private bool TryExecuteArgumentsToPipBuilder(
            ProjectWithPredictions project,
            QualifierId qualifierId,
            out string failureDetail,
            out Process scheduledProcess)
        {
            // We create a pip construction helper for each project
            var pipConstructionHelper = GetPipConstructionHelperForProject(project, qualifierId);

            using (var processBuilder = ProcessBuilder.Create(PathTable, m_context.GetPipDataBuilder()))
            {
                // Configure the process to add an assortment of settings: arguments, response file, etc.
                if (!TryConfigureProcessBuilder(processBuilder, pipConstructionHelper, project, qualifierId, out AbsolutePath outputResultCacheFile, out failureDetail))
                {
                    scheduledProcess = null;
                    return(false);
                }

                // Process all predicted outputs and inputs, including the predicted project dependencies
                ProcessOutputs(project, processBuilder);
                ProcessInputs(project, processBuilder);

                // Try to schedule the process pip
                if (!pipConstructionHelper.TryAddProcess(processBuilder, out ProcessOutputs outputs, out scheduledProcess))
                {
                    failureDetail = "Failed to schedule the pip";
                    return(false);
                }

                // Add the computed outputs for this project, so dependencies can consume it
                var outputDirectories = outputs.GetOutputDirectories();

                // A valid output cache path indicates that the project is building in isolation
                MSBuildProjectOutputs projectOutputs;
                if (outputResultCacheFile == AbsolutePath.Invalid)
                {
                    projectOutputs = MSBuildProjectOutputs.CreateLegacy(outputDirectories);
                }
                else
                {
                    var success = outputs.TryGetOutputFile(outputResultCacheFile, out FileArtifact cacheFileArtifact);
                    if (!success)
                    {
                        Contract.Assert(false, I($"The output cache file {outputResultCacheFile.ToString(PathTable)} should be part of the project {project.FullPath.ToString(PathTable)} outputs."));
                    }

                    projectOutputs = MSBuildProjectOutputs.CreateIsolated(outputDirectories, cacheFileArtifact);
                }

                m_processOutputsPerProject[project] = projectOutputs;

                failureDetail = string.Empty;
                return(true);
            }
        }
Example #4
0
        /// <summary>
        /// Helper to create a PipBuilder and optionally assign a tag
        /// </summary>
        internal static ProcessBuilder CreatePipBuilderWithTag(TestEnv env, string tag = null)
        {
            var exe = FileArtifact.CreateSourceFile(AbsolutePath.Create(env.Context.PathTable, @"\\dummyPath\DummyFile.exe"));

            var processBuilder = ProcessBuilder.Create(env.PathTable, env.PipDataBuilderPool.GetInstance(), new ConfigurationImpl());

            processBuilder.Executable = exe;
            processBuilder.AddInputFile(exe);
            processBuilder.AddTags(env.PathTable.StringTable, tag);

            return(processBuilder);
        }
Example #5
0
        private static EvaluationResult DumpArgs(Context context, ModuleLiteral env, EvaluationStackFrame args)
        {
            var cmdLineArgs = Args.AsArrayLiteral(args, 0);
            var pathTable   = context.FrontEndContext.PathTable;

            using (var processBuilder = ProcessBuilder.Create(pathTable, context.FrontEndContext.GetPipDataBuilder(), context.FrontEndHost.Configuration))
            {
                TransformerExecuteArgumentsProcessor.ProcessArguments(context, processBuilder, cmdLineArgs);

                var pipData = processBuilder.ArgumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.NoEscaping);
                return(EvaluationResult.Create(pipData.ToString(pathTable)));
            }
        }
Example #6
0
        private bool TryExecuteArgumentsToPipBuilder(
            RushProject project,
            QualifierId qualifierId,
            out string failureDetail,
            out Process process)
        {
            // TODO: don't do it here but in CanSchedule
            if (string.IsNullOrEmpty(project.BuildCommand))
            {
                m_processOutputsPerProject[project] = new ProcessOutputs(new Dictionary <AbsolutePath, FileArtifactWithAttributes>(), new Dictionary <AbsolutePath, StaticDirectory>());
                failureDetail = string.Empty;
                process       = default;

                return(true);
            }

            // We create a pip construction helper for each project
            var pipConstructionHelper = GetPipConstructionHelperForProject(project, qualifierId);

            using (var processBuilder = ProcessBuilder.Create(PathTable, m_context.GetPipDataBuilder()))
            {
                // Configure the process to add an assortment of settings: arguments, response file, etc.
                ConfigureProcessBuilder(processBuilder, project);

                // Process all predicted outputs and inputs, including the predicted project dependencies
                ProcessInputs(project, processBuilder);
                ProcessOutputs(project, processBuilder);

                // Try to schedule the process pip
                if (!pipConstructionHelper.TryAddProcess(processBuilder, out ProcessOutputs outputs, out process))
                {
                    failureDetail = "Failed to schedule the pip";
                    return(false);
                }

                m_processOutputsPerProject[project] = outputs;

                failureDetail = string.Empty;
                return(true);
            }
        }
        private bool TryBuildProcessAndSchedulePip(NinjaNode node, QualifierId qualifierId, out Process process)
        {
            process = null;
            if (node.Rule.Equals("phony"))
            {
                // For now, we are including phony rules ONLY as the final 'node', this is, the one that
                // corresponds to the target. TODO: Get rid of all phonies.
                // We can safely skip these, they only represent a rename in the graph.
                return(true);
            }
            using (var processBuilder = ProcessBuilder.Create(m_context.PathTable, m_context.GetPipDataBuilder()))
            {
                if (!TryConfigureProcessBuilder(processBuilder, node, qualifierId))
                {
                    // Error has been logged
                    return(false);
                }

                // Process all outputs and inputs
                AddOutputs(node, processBuilder);
                AddInputs(node, processBuilder);

                // Try to schedule the process pip
                if (!m_pipConstructionHelper.TryAddProcess(processBuilder, out ProcessOutputs outputs, out process))
                {
                    // Error has been logged
                    return(false);
                }

                // Add the computed outputs for this project, so dependencies can consume it
                m_processOutputs[node] = outputs;
                foreach (var output in outputs.GetOutputFiles())
                {
                    m_outputFileArtifacts[output.Path] = output;
                }

                return(true);
            }
        }
Example #8
0
        private bool TryExecuteArgumentsToPipBuilder(
            ProjectWithPredictions project,
            QualifierId qualifierId,
            out string failureDetail,
            out Process scheduledProcess)
        {
            // We create a pip construction helper for each project
            var pipConstructionHelper = GetPipConstructionHelperForProject(project, qualifierId);

            using (var processBuilder = ProcessBuilder.Create(PathTable, m_context.GetPipDataBuilder()))
            {
                // Configure the process to add an assortment of settings: arguments, response file, etc.
                if (!TryConfigureProcessBuilder(processBuilder, pipConstructionHelper, project, qualifierId, out AbsolutePath outputResultCacheFile, out failureDetail))
                {
                    scheduledProcess = null;
                    return(false);
                }

                // Process all predicted outputs and inputs, including the predicted project dependencies
                ProcessOutputs(project, processBuilder);
                ProcessInputs(project, processBuilder);

                // Try to schedule the process pip
                if (!pipConstructionHelper.TryAddProcess(processBuilder, out ProcessOutputs outputs, out scheduledProcess))
                {
                    failureDetail = "Failed to schedule the pip";
                    return(false);
                }

                // Add the computed outputs for this project, so dependencies can consume it
                var outputDirectories = outputs.GetOutputDirectories();

                // A valid output cache path indicates that the project is building in isolation
                MSBuildProjectOutputs projectOutputs;
                if (outputResultCacheFile == AbsolutePath.Invalid)
                {
                    projectOutputs = MSBuildProjectOutputs.CreateLegacy(outputDirectories);
                }
                else
                {
                    var success = outputs.TryGetOutputFile(outputResultCacheFile, out FileArtifact cacheFileArtifact);
                    if (!success)
                    {
                        Contract.Assert(false, I($"The output cache file {outputResultCacheFile.ToString(PathTable)} should be part of the project {project.FullPath.ToString(PathTable)} outputs."));
                    }

                    projectOutputs = MSBuildProjectOutputs.CreateIsolated(outputDirectories, cacheFileArtifact);
                }

                // If the project is not implementing the target protocol, emit corresponding warn/verbose
                if (!project.ImplementsTargetProtocol)
                {
                    if (project.ProjectReferences.Count != 0)
                    {
                        // Let's warn about this. Targets of the referenced projects may not be accurate
                        Tracing.Logger.Log.ProjectIsNotSpecifyingTheProjectReferenceProtocol(
                            m_context.LoggingContext,
                            Location.FromFile(project.FullPath.ToString(PathTable)),
                            project.FullPath.GetName(m_context.PathTable).ToString(m_context.StringTable));
                    }
                    else
                    {
                        // Just a verbose message in this case
                        Tracing.Logger.Log.LeafProjectIsNotSpecifyingTheProjectReferenceProtocol(
                            m_context.LoggingContext,
                            Location.FromFile(project.FullPath.ToString(PathTable)),
                            project.FullPath.GetName(m_context.PathTable).ToString(m_context.StringTable));
                    }
                }

                // Warn if default targets were appended to the targets to execute
                if (project.PredictedTargetsToExecute.IsDefaultTargetsAppended)
                {
                    Tracing.Logger.Log.ProjectPredictedTargetsAlsoContainDefaultTargets(
                        m_context.LoggingContext,
                        Location.FromFile(project.FullPath.ToString(PathTable)),
                        project.FullPath.GetName(m_context.PathTable).ToString(m_context.StringTable),
                        $"[{string.Join(";", project.PredictedTargetsToExecute.AppendedDefaultTargets)}]");
                }

                m_processOutputsPerProject[project] = projectOutputs;

                failureDetail = string.Empty;
                return(true);
            }
        }
Example #9
0
        private bool TryScheduleIpcPip(Context context, ObjectLiteral obj, bool allowUndefinedTargetService, bool isServiceFinalization, out FileArtifact outputFile, out PipId pipId)
        {
            // IpcClientInfo
            IIpcMoniker moniker          = Converter.ExtractRef <IIpcMoniker>(obj, m_ipcSendMoniker, allowUndefined: false);
            int?        numRetries       = Converter.ExtractNumber(obj, m_ipcSendMaxConnectRetries, allowUndefined: true);
            int?        retryDelayMillis = Converter.ExtractNumber(obj, m_ipcSendConnectRetryDelayMillis, allowUndefined: true);
            var         clientConfig     = new ClientConfig(numRetries, retryDelayMillis);
            var         ipcClientInfo    = new IpcClientInfo(moniker.ToStringId(context.StringTable), clientConfig);

            // target service pip
            PipId?servicePipId = Converter.ExtractValue <PipId>(obj, m_ipcSendTargetServicePip, allowUndefined: allowUndefinedTargetService);

            // arguments
            PipData arguments;
            ReadOnlyArray <FileArtifact>      fileDependencies;
            ReadOnlyArray <DirectoryArtifact> directoryDependencies;

            using (var ipcProcessBuilder = ProcessBuilder.Create(context.PathTable, context.FrontEndContext.GetPipDataBuilder()))
            {
                // process arguments
                ArrayLiteral argumentsArrayLiteral = Converter.ExtractArrayLiteral(obj, m_ipcSendMessageBody);
                TransformerExecuteArgumentsProcessor.ProcessArguments(context, ipcProcessBuilder, argumentsArrayLiteral);

                // input file dependencies
                var dependenciesArray = Converter.ExtractArrayLiteral(obj, m_ipcSendDependencies, allowUndefined: true);
                if (dependenciesArray != null)
                {
                    for (int i = 0; i < dependenciesArray.Length; i++)
                    {
                        ProcessImplicitDependency(ipcProcessBuilder, dependenciesArray[i], convContext: new ConversionContext(pos: i, objectCtx: dependenciesArray));
                    }
                }

                arguments             = ipcProcessBuilder.ArgumentsBuilder.ToPipData(" ", PipDataFragmentEscaping.CRuntimeArgumentRules);
                fileDependencies      = ipcProcessBuilder.GetInputFilesSoFar();
                directoryDependencies = ipcProcessBuilder.GetInputDirectoriesSoFar();
            }

            // output
            AbsolutePath output = Converter.ExtractPath(obj, m_ipcSendOutputFile, allowUndefined: true);

            if (!output.IsValid)
            {
                output = context.GetPipConstructionHelper().GetUniqueObjectDirectory(m_ipcObjectFolderName).Path.Combine(context.PathTable, m_ipcOutputFileName);
            }

            // tags
            string[] tags      = null;
            var      tagsArray = Converter.ExtractArrayLiteral(obj, m_executeTags, allowUndefined: true);

            if (tagsArray != null && tagsArray.Count > 0)
            {
                tags = new string[tagsArray.Count];
                for (int i = 0; i < tagsArray.Count; i++)
                {
                    tags[i] = Converter.ExpectString(tagsArray[i], context: new ConversionContext(pos: i, objectCtx: tagsArray));
                }
            }

            // skip materialization for files
            FileOrDirectoryArtifact[] skipMaterializationArtifacts = CollectionUtilities.EmptyArray <FileOrDirectoryArtifact>();
            ArrayLiteral skipMaterializationLiteral = Converter.ExtractArrayLiteral(obj, m_ipcSendLazilyMaterializedDependencies, allowUndefined: true);

            if (skipMaterializationLiteral != null)
            {
                skipMaterializationArtifacts = new FileOrDirectoryArtifact[skipMaterializationLiteral.Length];
                for (int i = 0; i < skipMaterializationLiteral.Length; i++)
                {
                    Converter.ExpectFileOrStaticDirectory(
                        skipMaterializationLiteral[i],
                        out var fileArtifact,
                        out var staticDirectory,
                        context: new ConversionContext(pos: i, objectCtx: skipMaterializationLiteral));

                    Contract.Assert(fileArtifact.IsValid ^ staticDirectory != null);

                    skipMaterializationArtifacts[i] = fileArtifact.IsValid
                        ? FileOrDirectoryArtifact.Create(fileArtifact)
                        : FileOrDirectoryArtifact.Create(staticDirectory.Root);
                }
            }

            // must run on master
            var mustRunOnMaster = Converter.ExtractOptionalBoolean(obj, m_ipcSendMustRunOnMaster) == true;

            outputFile = FileArtifact.CreateOutputFile(output);

            // create IPC pip and add it to the graph
            bool result = context.GetPipConstructionHelper().TryAddIpc(
                ipcClientInfo,
                arguments,
                outputFile,
                servicePipDependencies: servicePipId != null ? ReadOnlyArray <PipId> .From(new[] { servicePipId.Value }) : ReadOnlyArray <PipId> .Empty,
                fileDependencies: fileDependencies,
                directoryDependencies: directoryDependencies,
                skipMaterializationFor: ReadOnlyArray <FileOrDirectoryArtifact> .FromWithoutCopy(skipMaterializationArtifacts),
                isServiceFinalization: isServiceFinalization,
                mustRunOnMaster: mustRunOnMaster,
                tags: tags,
                out var ipcPip);

            pipId = ipcPip.PipId;

            return(result);
        }