Esempio n. 1
0
        private async Task <ResultStatus> StartCommand(IExecuteContext executeContext, ListStore <CommandResultEntry> commandResultEntries, BuilderContext builderContext)
        {
            var logger = executeContext.Logger;

            //await Scheduler.Yield();

            ResultStatus status;

            using (commandResultEntries)
            {
                logger.Debug($"Starting command {Command}...");

                // Creating the CommandResult object
                var commandContext = new LocalCommandContext(executeContext, this, builderContext);

                // Try to execute remotely
                if (!(Command.ShouldSpawnNewProcess() &&
                      builderContext.TryExecuteRemote != null &&
                      (status = await builderContext.TryExecuteRemote(Command, builderContext, executeContext, commandContext)) != ResultStatus.NotProcessed))
                {
                    Command.PreCommand(commandContext);
                    if (!Command.BasePreCommandCalled)
                    {
                        throw new InvalidOperationException("base.PreCommand not called in command " + Command);
                    }

                    try
                    {
                        // Merge results from prerequisites
                        // TODO: This will prevent us from overwriting this asset with different content as it will result in a write conflict
                        // At some point we _might_ want to get rid of WaitBuildStep/ListBuildStep system and write a fully stateless input/output-based system; probably need further discussions
                        var fileProvider = MicrothreadLocalDatabases.DatabaseFileProvider;
                        if (fileProvider != null)
                        {
                            var assetIndexMap = fileProvider.ContentIndexMap;
                            foreach (var prerequisiteStep in PrerequisiteSteps)
                            {
                                foreach (var output in prerequisiteStep.OutputObjectIds)
                                {
                                    assetIndexMap[output.Key.Path] = output.Value;
                                }
                            }
                        }

                        status = await Command.DoCommand(commandContext);
                    }
                    catch (Exception ex)
                    {
                        executeContext.Logger.Error("Exception in command " + this + ": " + ex);
                        status = ResultStatus.Failed;
                    }

                    Command.PostCommand(commandContext, status);
                    if (!Command.BasePostCommandCalled)
                    {
                        throw new InvalidOperationException("base.PostCommand not called in command " + Command);
                    }
                }

                // Ensure the command set at least the result status
                if (status == ResultStatus.NotProcessed)
                {
                    throw new InvalidDataException("The command " + Command + " returned ResultStatus.NotProcessed after completion.");
                }

                // Registering the result to the build cache
                RegisterCommandResult(commandResultEntries, commandContext.ResultEntry, status);
            }

            return(status);
        }