diff --git a/src/Aspire.Cli/Commands/PublishCommand.cs b/src/Aspire.Cli/Commands/PublishCommand.cs index 6e03627cdf2..45bf36f6660 100644 --- a/src/Aspire.Cli/Commands/PublishCommand.cs +++ b/src/Aspire.Cli/Commands/PublishCommand.cs @@ -62,6 +62,14 @@ protected override async Task ExecuteAsync(ParseResult parseResult, Cancell return ExitCodeConstants.FailedToDotnetRunAppHost; } + var buildExitCode = await AppHostHelper.BuildAppHostAsync(_runner, effectiveAppHostProjectFile, cancellationToken); + + if (buildExitCode != 0) + { + AnsiConsole.MarkupLine($"[red bold]:thumbs_down: The project could not be built. For more information run with --debug switch.[/]"); + return ExitCodeConstants.FailedToBuildArtifacts; + } + var publisher = parseResult.GetValue("--publisher"); var outputPath = parseResult.GetValue("--output-path"); var fullyQualifiedOutputPath = Path.GetFullPath(outputPath ?? "."); @@ -81,7 +89,7 @@ protected override async Task ExecuteAsync(ParseResult parseResult, Cancell var pendingInspectRun = _runner.RunAsync( effectiveAppHostProjectFile, false, - false, + true, ["--operation", "inspect"], null, backchannelCompletionSource, diff --git a/src/Aspire.Cli/Commands/RunCommand.cs b/src/Aspire.Cli/Commands/RunCommand.cs index 69e4ffcb1f4..955a2dd8215 100644 --- a/src/Aspire.Cli/Commands/RunCommand.cs +++ b/src/Aspire.Cli/Commands/RunCommand.cs @@ -80,12 +80,13 @@ protected override async Task ExecuteAsync(ParseResult parseResult, Cancell var watch = parseResult.GetValue("--watch"); - await AnsiConsole.Status() - .Spinner(Spinner.Known.Dots3) - .SpinnerStyle(Style.Parse("purple")) - .StartAsync(":hammer_and_wrench: Building app host...", async context => { - await _runner.BuildAsync(effectiveAppHostProjectFile, cancellationToken).ConfigureAwait(false); - }); + var buildExitCode = await AppHostHelper.BuildAppHostAsync(_runner, effectiveAppHostProjectFile, cancellationToken); + + if (buildExitCode != 0) + { + AnsiConsole.MarkupLine($"[red bold]:thumbs_down: The project could not be built. For more information run with --debug switch.[/]"); + return ExitCodeConstants.FailedToBuildArtifacts; + } var backchannelCompletitionSource = new TaskCompletionSource(); diff --git a/src/Aspire.Cli/DotNetCliRunner.cs b/src/Aspire.Cli/DotNetCliRunner.cs index 0141e8214e3..7833fedf452 100644 --- a/src/Aspire.Cli/DotNetCliRunner.cs +++ b/src/Aspire.Cli/DotNetCliRunner.cs @@ -77,6 +77,49 @@ internal sealed class DotNetCliRunner(ILogger logger, IServiceP } } + public async Task<(int ExitCode, JsonDocument? Output)> GetProjectItemsAndPropertiesAsync(FileInfo projectFile, string[] items, string[] properties, CancellationToken cancellationToken) + { + using var activity = _activitySource.StartActivity(); + + string[] cliArgs = [ + "msbuild", + $"-getProperty:{string.Join(",", properties)}", + $"-getItem:{string.Join(",", items)}", + projectFile.FullName + ]; + + string? stdout = null; + string? stderr = null; + + var exitCode = await ExecuteAsync( + cliArgs, + null, + projectFile.Directory!, + null, + (_, output, error) => { + stdout = output.ReadToEnd(); + stderr = error.ReadToEnd(); + }, + cancellationToken); + + if (exitCode != 0) + { + logger.LogError( + "Failed to get items and properties from project. Exit code was: {ExitCode}. See debug logs for more details. Stderr: {Stderr}, Stdout: {Stdout}", + exitCode, + stderr, + stdout + ); + + return (exitCode, null); + } + else + { + var json = JsonDocument.Parse(stdout!); + return (exitCode, json); + } + } + public async Task RunAsync(FileInfo projectFile, bool watch, bool noBuild, string[] args, IDictionary? env, TaskCompletionSource? backchannelCompletionSource, CancellationToken cancellationToken) { using var activity = _activitySource.StartActivity(); diff --git a/src/Aspire.Cli/Utils/AppHostHelper.cs b/src/Aspire.Cli/Utils/AppHostHelper.cs index 6f9e068fec1..c6824f09609 100644 --- a/src/Aspire.Cli/Utils/AppHostHelper.cs +++ b/src/Aspire.Cli/Utils/AppHostHelper.cs @@ -62,4 +62,14 @@ internal static class AppHostHelper return appHostInformationResult; } + + internal static async Task BuildAppHostAsync(DotNetCliRunner runner, FileInfo projectFile, CancellationToken cancellationToken) + { + return await AnsiConsole.Status() + .Spinner(Spinner.Known.Dots3) + .SpinnerStyle(Style.Parse("purple")) + .StartAsync(":hammer_and_wrench: Building app host...", async context => { + return await runner.BuildAsync(projectFile, cancellationToken).ConfigureAwait(false); + }); + } } \ No newline at end of file