Example #1
0
        private string FormatResult(IList <PlatformResult> platforms)
        {
            var result = new StringBuilder();

            foreach (PlatformResult platform in platforms)
            {
                var defs = new DefinitionListFormatter();
                defs.AddDefinition("Platform", platform.Name);

                defs.AddDefinition(
                    "Versions",
                    (platform.Versions != null && platform.Versions.Any()) ?
                    string.Join(Environment.NewLine, platform.Versions) : "N/A");

                if (platform.Properties != null && platform.Properties.Any())
                {
                    defs.AddDefinition(
                        "Properties",
                        string.Join(
                            Environment.NewLine,
                            platform.Properties.Select(prop => $"{prop.Key} - {prop.Value}")));
                }

                result.AppendLine(defs.ToString());
            }

            return(result.ToString());
        }
Example #2
0
        private void PrintTableResult(IEnumerable <PlatformDetectorResult> detectedPlatformResults, IConsole console)
        {
            var defs = new DefinitionListFormatter();

            if (detectedPlatformResults == null || !detectedPlatformResults.Any())
            {
                defs.AddDefinition("Platform", "Not Detected");
                defs.AddDefinition("PlatformVersion", "Not Detected");
                console.WriteLine(defs.ToString());
                return;
            }

            foreach (var detectedPlatformResult in detectedPlatformResults)
            {
                // This is to filter out the indexed properties from properties variable.
                var propertyInfos = detectedPlatformResult
                                    .GetType()
                                    .GetProperties()
                                    .Where(p => p.GetIndexParameters().Length == 0);

                // Get all properties from a detected platform result and add them to DefinitionListFormatter.
                foreach (var propertyInfo in propertyInfos)
                {
                    var propertyValue = propertyInfo.GetValue(detectedPlatformResult, null);
                    defs.AddDefinition(propertyInfo.Name,
                                       propertyValue == null ? "Not Detected" : propertyValue.ToString());
                }
            }

            console.WriteLine(defs.ToString());
        }
Example #3
0
        protected static string GetBeginningCommandOutputLog()
        {
            var output = new StringBuilder();

            output.AppendLine("Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx");
            output.AppendLine("You can report issues at https://github.com/Microsoft/Oryx/issues");
            var buildInfo          = new DefinitionListFormatter();
            var oryxVersion        = Program.GetVersion();
            var oryxCommitId       = Program.GetMetadataValue(Program.GitCommit);
            var oryxReleaseTagName = Program.GetMetadataValue(Program.ReleaseTagName);

            buildInfo.AddDefinition(
                "Oryx Version",
                $"{oryxVersion}, " +
                $"Commit: {oryxCommitId}, " +
                $"ReleaseTagName: {oryxReleaseTagName}");
            output.AppendLine();
            output.Append(buildInfo.ToString());
            return(output.ToString());
        }
Example #4
0
        // To enable unit testing
        internal int Execute(
            IServiceProvider serviceProvider,
            IConsole console,
            DataReceivedEventHandler stdOutHandler,
            DataReceivedEventHandler stdErrHandler)
        {
            var logger = serviceProvider.GetRequiredService <ILogger <BuildCommand> >();

            // This will be an App Service app name if Oryx was invoked by Kudu
            var appName = Environment.GetEnvironmentVariable(
                LoggingConstants.AppServiceAppNameEnvironmentVariableName) ?? ".oryx";
            var buildOpId = logger.StartOperation(appName);

            console.WriteLine("Build orchestrated by Microsoft Oryx, https://github.com/Microsoft/Oryx");
            console.WriteLine("You can report issues at https://github.com/Microsoft/Oryx/issues");
            console.WriteLine();

            var buildInfo = new DefinitionListFormatter();

            buildInfo.AddDefinition("Oryx Version", $"{Program.GetVersion()}, Commit: {Program.GetCommit()}");
            buildInfo.AddDefinition("Build Operation ID", buildOpId);

            var sourceRepo = serviceProvider.GetRequiredService <ISourceRepoProvider>().GetSourceRepo();
            var commitId   = GetSourceRepoCommitId(
                serviceProvider.GetRequiredService <IEnvironment>(),
                sourceRepo,
                logger);

            if (!string.IsNullOrWhiteSpace(commitId))
            {
                buildInfo.AddDefinition("Repository Commit", commitId);
            }

            console.WriteLine(buildInfo.ToString());

            // Try writing the ID to a file in the source directory
            try
            {
                using (logger.LogTimedEvent("WriteBuildIdFile"))
                    using (var idFileWriter = new StreamWriter(
                               Path.Combine(sourceRepo.RootPath, Common.FilePaths.BuildIdFileName)))
                    {
                        idFileWriter.Write(buildOpId);
                    }
            }
            catch (Exception exc)
            {
                logger.LogError(exc, "Exception caught while trying to write build ID file");
            }

            var environmentSettingsProvider = serviceProvider.GetRequiredService <IEnvironmentSettingsProvider>();

            if (!environmentSettingsProvider.TryGetAndLoadSettings(out var environmentSettings))
            {
                return(ProcessConstants.ExitFailure);
            }

            // Generate build script
            string scriptContent;

            using (var stopwatch = logger.LogTimedEvent("GenerateBuildScript"))
            {
                var scriptGenerator = new BuildScriptGenerator(console, serviceProvider);
                if (!scriptGenerator.TryGenerateScript(out scriptContent))
                {
                    stopwatch.AddProperty("failed", "true");
                    return(ProcessConstants.ExitFailure);
                }
            }

            // Get the path where the generated script should be written into.
            var tempDirectoryProvider = serviceProvider.GetRequiredService <ITempDirectoryProvider>();
            var buildScriptPath       = Path.Combine(tempDirectoryProvider.GetTempDirectory(), "build.sh");

            // Write build script to selected path
            File.WriteAllText(buildScriptPath, scriptContent);
            logger.LogTrace("Build script written to file");

            var buildEventProps = new Dictionary <string, string>()
            {
                { "oryxVersion", Program.GetVersion() },
                { "oryxCommitId", Program.GetCommit() },
                {
                    "oryxCommandLine",
                    string.Join(
                        ' ',
                        serviceProvider.GetRequiredService <IEnvironment>().GetCommandLineArgs())
                },
                { nameof(commitId), commitId },
                { "scriptPath", buildScriptPath },
                { "envVars", string.Join(",", GetEnvVarNames(serviceProvider.GetRequiredService <IEnvironment>())) },
            };

            var buildScriptOutput = new StringBuilder();
            var stdOutEventLogger = new TextSpanEventLogger(logger, _measurableStdOutSpans);

            DataReceivedEventHandler stdOutBaseHandler = (sender, args) =>
            {
                string line = args.Data;
                if (line == null)
                {
                    return;
                }

                console.WriteLine(line);
                buildScriptOutput.AppendLine(line);
                stdOutEventLogger.CheckString(line);
            };

            DataReceivedEventHandler stdErrBaseHandler = (sender, args) =>
            {
                string line = args.Data;
                if (line == null)
                {
                    return;
                }

                console.Error.WriteLine(args.Data);
                buildScriptOutput.AppendLine(args.Data);
            };

            // Try make the pre-build & post-build scripts executable
            ProcessHelper.TrySetExecutableMode(environmentSettings.PreBuildScriptPath);
            ProcessHelper.TrySetExecutableMode(environmentSettings.PostBuildScriptPath);

            // Run the generated script
            var options = serviceProvider.GetRequiredService <IOptions <BuildScriptGeneratorOptions> >().Value;
            int exitCode;

            using (var timedEvent = logger.LogTimedEvent("RunBuildScript", buildEventProps))
            {
                exitCode = serviceProvider.GetRequiredService <IScriptExecutor>().ExecuteScript(
                    buildScriptPath,
                    new[]
                {
                    sourceRepo.RootPath,
                    options.DestinationDir ?? string.Empty,
                    options.IntermediateDir ?? string.Empty
                },
                    workingDirectory: sourceRepo.RootPath,
                    stdOutHandler == null ? stdOutBaseHandler : stdOutBaseHandler + stdOutHandler,
                    stdErrHandler == null ? stdErrBaseHandler : stdErrBaseHandler + stdErrHandler);
            }

            logger.LogDebug("Build script content:\n" + scriptContent);
            logger.LogDebug("Build script output:\n" + buildScriptOutput.ToString());

            if (exitCode != ProcessConstants.ExitSuccess)
            {
                logger.LogError("Build script exited with {exitCode}", exitCode);
                return(exitCode);
            }

            return(ProcessConstants.ExitSuccess);
        }
Example #5
0
        // To enable unit testing
        internal int Execute(
            IServiceProvider serviceProvider,
            IConsole console,
            DataReceivedEventHandler stdOutHandler,
            DataReceivedEventHandler stdErrHandler)
        {
            var logger           = serviceProvider.GetRequiredService <ILogger <BuildCommand> >();
            var buildOperationId = logger.StartOperation(
                BuildOperationName(serviceProvider.GetRequiredService <IEnvironment>()));

            var options = serviceProvider.GetRequiredService <IOptions <BuildScriptGeneratorOptions> >().Value;

            console.WriteLine("Build orchestrated by Microsoft Oryx, https://github.com/Microsoft/Oryx");
            console.WriteLine("You can report issues at https://github.com/Microsoft/Oryx/issues");
            console.WriteLine();

            var buildInfo = new DefinitionListFormatter();

            buildInfo.AddDefinition("Oryx Version", $"{Program.GetVersion()}, Commit: {Program.GetCommit()}");
            buildInfo.AddDefinition("Build Operation ID", buildOperationId);

            var sourceRepo = serviceProvider.GetRequiredService <ISourceRepoProvider>().GetSourceRepo();
            var commitId   = GetSourceRepoCommitId(
                serviceProvider.GetRequiredService <IEnvironment>(),
                sourceRepo,
                logger);

            if (!string.IsNullOrWhiteSpace(commitId))
            {
                buildInfo.AddDefinition("Repository Commit", commitId);
            }

            console.WriteLine(buildInfo.ToString());

            var environmentSettingsProvider = serviceProvider.GetRequiredService <IEnvironmentSettingsProvider>();

            if (!environmentSettingsProvider.TryGetAndLoadSettings(out var environmentSettings))
            {
                return(ProcessConstants.ExitFailure);
            }

            // Generate build script
            string scriptContent;

            using (var stopwatch = logger.LogTimedEvent("GenerateBuildScript"))
            {
                var checkerMessages = new List <ICheckerMessage>();
                var scriptGenerator = new BuildScriptGenerator(
                    serviceProvider, console, checkerMessages, buildOperationId);

                var generated = scriptGenerator.TryGenerateScript(out scriptContent);
                stopwatch.AddProperty("generateSucceeded", generated.ToString());

                if (checkerMessages.Count > 0)
                {
                    var messageFormatter = new DefinitionListFormatter();
                    checkerMessages.ForEach(msg => messageFormatter.AddDefinition(msg.Level.ToString(), msg.Content));
                    console.WriteLine(messageFormatter.ToString());
                }
                else
                {
                    logger.LogDebug("No checker messages emitted");
                }

                if (!generated)
                {
                    return(ProcessConstants.ExitFailure);
                }
            }

            // Get the path where the generated script should be written into.
            var tempDirectoryProvider = serviceProvider.GetRequiredService <ITempDirectoryProvider>();
            var buildScriptPath       = Path.Combine(tempDirectoryProvider.GetTempDirectory(), "build.sh");

            // Write build script to selected path
            File.WriteAllText(buildScriptPath, scriptContent);
            logger.LogTrace("Build script written to file");

            var buildEventProps = new Dictionary <string, string>()
            {
                { "oryxVersion", Program.GetVersion() },
                { "oryxCommitId", Program.GetCommit() },
                {
                    "oryxCommandLine",
                    string.Join(
                        ' ',
                        serviceProvider.GetRequiredService <IEnvironment>().GetCommandLineArgs())
                },
                { nameof(commitId), commitId },
                { "scriptPath", buildScriptPath },
                { "envVars", string.Join(",", GetEnvVarNames(serviceProvider.GetRequiredService <IEnvironment>())) },
            };

            var buildScriptOutput = new StringBuilder();
            var stdOutEventLogger = new TextSpanEventLogger(logger, _measurableStdOutSpans);

            DataReceivedEventHandler stdOutBaseHandler = (sender, args) =>
            {
                string line = args.Data;
                if (line == null)
                {
                    return;
                }

                console.WriteLine(line);
                buildScriptOutput.AppendLine(line);
                stdOutEventLogger.CheckString(line);
            };

            DataReceivedEventHandler stdErrBaseHandler = (sender, args) =>
            {
                string line = args.Data;
                if (line == null)
                {
                    return;
                }

                console.Error.WriteLine(args.Data);
                buildScriptOutput.AppendLine(args.Data);
            };

            // Try make the pre-build & post-build scripts executable
            ProcessHelper.TrySetExecutableMode(environmentSettings.PreBuildScriptPath);
            ProcessHelper.TrySetExecutableMode(environmentSettings.PostBuildScriptPath);

            // Run the generated script
            int exitCode;

            using (var timedEvent = logger.LogTimedEvent("RunBuildScript", buildEventProps))
            {
                exitCode = serviceProvider.GetRequiredService <IScriptExecutor>().ExecuteScript(
                    buildScriptPath,
                    new[]
                {
                    sourceRepo.RootPath,
                    options.DestinationDir ?? string.Empty,
                    options.IntermediateDir ?? string.Empty
                },
                    workingDirectory: sourceRepo.RootPath,
                    stdOutHandler == null ? stdOutBaseHandler : stdOutBaseHandler + stdOutHandler,
                    stdErrHandler == null ? stdErrBaseHandler : stdErrBaseHandler + stdErrHandler);

                timedEvent.AddProperty("exitCode", exitCode.ToString());
            }

            logger.LogDebug("Build script content:\n" + scriptContent);
            logger.LogLongMessage(LogLevel.Debug, "Build script output", buildScriptOutput.ToString());

            if (exitCode != ProcessConstants.ExitSuccess)
            {
                logger.LogError("Build script exited with {exitCode}", exitCode);
                return(exitCode);
            }

            return(ProcessConstants.ExitSuccess);
        }