From 498931370fded6309f2073e5ddb2797c158c8c59 Mon Sep 17 00:00:00 2001 From: Glen Date: Fri, 30 Jan 2026 10:42:21 +0200 Subject: [PATCH 1/3] Write errors to stdout for now --- .../Extensions/AnsiConsoleExtensions.cs | 11 ----- .../CommandLineBuilderExtensions.cs | 4 +- .../Commands/Clients/PublishClientCommand.cs | 2 +- .../Commands/Clients/ValidateClientCommand.cs | 2 +- .../Commands/Fusion/FusionComposeCommand.cs | 10 ++--- .../Commands/Fusion/FusionPublishCommand.cs | 4 +- .../Commands/Fusion/FusionPublishHelpers.cs | 6 +-- .../Commands/Fusion/FusionValidateCommand.cs | 2 +- ...sionConfigurationPublishValidateCommand.cs | 2 +- .../Commands/Schemas/PublishSchemaCommand.cs | 2 +- .../Commands/Schemas/ValidateSchemaCommand.cs | 2 +- .../src/CommandLine/Helpers/ConsoleHelpers.cs | 40 +++++++++---------- .../Fusion/FusionComposeCommandTests.cs | 4 +- 13 files changed, 39 insertions(+), 52 deletions(-) delete mode 100644 src/Nitro/CommandLine/src/CommandLine.Core/Extensions/AnsiConsoleExtensions.cs diff --git a/src/Nitro/CommandLine/src/CommandLine.Core/Extensions/AnsiConsoleExtensions.cs b/src/Nitro/CommandLine/src/CommandLine.Core/Extensions/AnsiConsoleExtensions.cs deleted file mode 100644 index eab0513e0f8..00000000000 --- a/src/Nitro/CommandLine/src/CommandLine.Core/Extensions/AnsiConsoleExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace ChilliCream.Nitro.CommandLine; - -internal static class AnsiConsoleExtensions -{ - extension(IAnsiConsole ansiConsole) - { - public TextWriter Out => Console.Out; - - public TextWriter Error => Console.Error; - } -} diff --git a/src/Nitro/CommandLine/src/CommandLine.Core/Extensions/CommandLineBuilderExtensions.cs b/src/Nitro/CommandLine/src/CommandLine.Core/Extensions/CommandLineBuilderExtensions.cs index 441253ec7fd..e047527766e 100644 --- a/src/Nitro/CommandLine/src/CommandLine.Core/Extensions/CommandLineBuilderExtensions.cs +++ b/src/Nitro/CommandLine/src/CommandLine.Core/Extensions/CommandLineBuilderExtensions.cs @@ -71,7 +71,7 @@ private static async Task ExceptionMiddleware( { context.ExitCode = ExitCodes.Error; - await context.BindingContext.GetRequiredService().Error.WriteLineAsync(message); + context.BindingContext.GetRequiredService().MarkupLine(message); } catch (Exception ex) when (ex is OperationCanceledException or TaskCanceledException) { @@ -79,7 +79,7 @@ private static async Task ExceptionMiddleware( catch (Exception exception) { context.ExitCode = ExitCodes.Error; - await context.BindingContext.GetRequiredService().Error.WriteLineAsync(exception.Message); + context.BindingContext.GetRequiredService().WriteLine(exception.Message); throw; } } diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/PublishClientCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/PublishClientCommand.cs index 1a52f99abc4..ed894c6e7b4 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/PublishClientCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/PublishClientCommand.cs @@ -110,7 +110,7 @@ async Task PublishClient(StatusContext? ctx) break; case IClientVersionPublishFailed { Errors: var clientErrors }: - console.Error.WriteLine("Client publish failed"); + console.WriteLine("Client publish failed"); console.PrintErrorsAndExit(clientErrors); stopSignal.OnNext(Unit.Default); break; diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/ValidateClientCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/ValidateClientCommand.cs index 56a9dad8b67..53992ee4fc5 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/ValidateClientCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Clients/ValidateClientCommand.cs @@ -94,7 +94,7 @@ async Task ValidateClient(StatusContext? ctx) switch (x.Data?.OnClientVersionValidationUpdate) { case IClientVersionValidationFailed { Errors: var schemaErrors }: - console.Error.WriteLine("The client is invalid:"); + console.WriteLine("The client is invalid:"); console.PrintErrorsAndExit(schemaErrors); stopSignal.OnNext(Unit.Default); break; diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionComposeCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionComposeCommand.cs index bbe929aef66..c0e7fb3fcfa 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionComposeCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionComposeCommand.cs @@ -223,7 +223,7 @@ await ComposeAsync( } else { - console.Error.WriteLine($"❌ The path `{sourceSchemaPath}` does not exist."); + console.WriteLine($"❌ The path `{sourceSchemaPath}` does not exist."); return 1; } } @@ -369,7 +369,7 @@ await ComposeAsync( } catch (Exception ex) when (ex is not OperationCanceledException) { - console.Error.WriteLine($"❌ Error during recomposition: {ex.Message}"); + console.WriteLine($"❌ Error during recomposition: {ex.Message}"); } finally { @@ -416,7 +416,7 @@ private static async Task ComposeAsync( compositionSettings, cancellationToken); - var writer = result.IsSuccess ? console.Out : console.Error; + var writer = console.Out; WriteCompositionLog( compositionLog, @@ -432,7 +432,7 @@ private static async Task ComposeAsync( { foreach (var error in result.Errors) { - console.Error.WriteLine(error.Message); + console.WriteLine(error.Message); } return 1; @@ -446,7 +446,7 @@ private static async Task ComposeAsync( } catch (Exception e) { - console.Error.WriteLine(e.Message); + console.WriteLine(e.Message); return 1; } } diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishCommand.cs index 8804f3f7e58..b7bad6ca1e5 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishCommand.cs @@ -308,7 +308,7 @@ await FusionPublishHelpers.UploadFusionArchiveAsync( } catch (Exception exception) { - console.Error.WriteLine(exception.Message); + console.WriteLine(exception.Message); if (!string.IsNullOrEmpty(requestId)) { @@ -445,7 +445,7 @@ await FusionPublishHelpers.ReleaseDeploymentSlot( } catch (Exception exception) { - console.Error.WriteLine(exception.Message); + console.WriteLine(exception.Message); if (!string.IsNullOrEmpty(requestId)) { diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishHelpers.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishHelpers.cs index 5077155acbc..bacf54621ee 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishHelpers.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishHelpers.cs @@ -342,18 +342,16 @@ public static async Task ComposeAsync( compositionSettings, cancellationToken); - var writer = new AnsiStreamWriter(result.IsSuccess ? console.Out : console.Error); - FusionComposeCommand.WriteCompositionLog( compositionLog, - writer, + new AnsiStreamWriter(Console.Out), false); if (result.IsFailure) { foreach (var error in result.Errors) { - console.Error.WriteLine(error.Message); + console.WriteLine(error.Message); } return false; diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionValidateCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionValidateCommand.cs index 22b1c72d3af..c87abaaef39 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionValidateCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionValidateCommand.cs @@ -204,7 +204,7 @@ async Task ValidateSchemaAsync(StatusContext? ctx, Stream schemaStream) switch (x.Data?.OnSchemaVersionValidationUpdate) { case ISchemaVersionValidationFailed { Errors: var schemaErrors }: - console.Error.WriteLine("The schema is invalid:"); + console.WriteLine("The schema is invalid:"); console.PrintErrorsAndExit(schemaErrors); stopSignal.OnNext(Unit.Default); break; diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/PublishCommand/FusionConfigurationPublishValidateCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/PublishCommand/FusionConfigurationPublishValidateCommand.cs index e4b0cdb808e..87b2cf060b9 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/PublishCommand/FusionConfigurationPublishValidateCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/PublishCommand/FusionConfigurationPublishValidateCommand.cs @@ -94,7 +94,7 @@ async Task ValidateAsync(StatusContext? ctx) return ExitCodes.Success; } - console.Error.WriteLine("The validation failed:"); + console.WriteLine("The validation failed:"); if (failed is not null) { console.PrintErrorsAndExit(failed.Errors); diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/PublishSchemaCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/PublishSchemaCommand.cs index 82a7625acf9..49d420d93b3 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/PublishSchemaCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/PublishSchemaCommand.cs @@ -111,7 +111,7 @@ async Task PublishSchema(StatusContext? ctx) break; case ISchemaVersionPublishFailed { Errors: var schemaErrors }: - console.Error.WriteLine("Schema publish failed"); + console.WriteLine("Schema publish failed"); console.PrintErrorsAndExit(schemaErrors); stopSignal.OnNext(Unit.Default); break; diff --git a/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/ValidateSchemaCommand.cs b/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/ValidateSchemaCommand.cs index 8c4a058aff9..f22626f2561 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/ValidateSchemaCommand.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Commands/Schemas/ValidateSchemaCommand.cs @@ -94,7 +94,7 @@ async Task ValidateSchema(StatusContext? ctx) switch (x.Data?.OnSchemaVersionValidationUpdate) { case ISchemaVersionValidationFailed { Errors: var schemaErrors }: - console.Error.WriteLine("The schema is invalid:"); + console.WriteLine("The schema is invalid:"); console.PrintErrorsAndExit(schemaErrors); stopSignal.OnNext(Unit.Default); break; diff --git a/src/Nitro/CommandLine/src/CommandLine/Helpers/ConsoleHelpers.cs b/src/Nitro/CommandLine/src/CommandLine/Helpers/ConsoleHelpers.cs index d3c27fcc401..92d05e4ebfc 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Helpers/ConsoleHelpers.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Helpers/ConsoleHelpers.cs @@ -12,7 +12,7 @@ public static void EnsureNoErrors( if (result.Errors is { Count: > 0 }) { var firstError = result.Errors[0]; - console.Error.WriteLine($"{firstError.Message} ({firstError.Code})"); + console.WriteLine($"{firstError.Message} ({firstError.Code})"); throw new ExitException(); } @@ -23,7 +23,7 @@ public static T EnsureData(this IAnsiConsole console, IOperationResult res { if (result.Data is null) { - console.Error.WriteLine($"{Errors.BA00001Message} ({Errors.BA00001})"); + console.WriteLine($"{Errors.BA00001Message} ({Errors.BA00001})"); throw new ExitException(); } @@ -91,8 +91,8 @@ private static void PrintError( this IAnsiConsole console, IStagesHavePublishedDependenciesError error) { - console.Error.WriteLine(error.Message); - console.Error.WriteLine(); + console.WriteLine(error.Message); + console.WriteLine(); foreach (var stage in error.Stages) { @@ -121,7 +121,7 @@ private static void PrintError(this IAnsiConsole console, IPersistedQueryValidat console.WarningLine( $"There were errors on client {error.Client?.Name.AsHighlight()} [dim](ID: {error.Client?.Id})[/]"); - console.Error.WriteLine(error.Message); + console.WriteLine(error.Message); var node = new Tree(""); foreach (var query in error.Queries) @@ -153,10 +153,10 @@ private static void PrintError( this IAnsiConsole console, IInvalidGraphQLSchemaError error) { - console.Error.ErrorLine( + console.ErrorLine( "The schema you are trying to publish is invalid. Please fix the following errors:"); - console.Error.WriteLine(error.Message); + console.WriteLine(error.Message); var node = new Tree(""); foreach (var query in error.Errors) @@ -173,19 +173,19 @@ private static void PrintMutationError(this IAnsiConsole ansiConsole, object err switch (error) { case IOperationsAreNotAllowedError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IConcurrentOperationError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IUnexpectedProcessingError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IProcessingTimeoutError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case ISchemaVersionChangeViolationError err: @@ -193,7 +193,7 @@ private static void PrintMutationError(this IAnsiConsole ansiConsole, object err break; case ISchemaVersionSyntaxError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IPersistedQueryValidationError err: @@ -205,23 +205,23 @@ private static void PrintMutationError(this IAnsiConsole ansiConsole, object err break; case IApiNotFoundError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IMockSchemaNonUniqueNameError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IMockSchemaNotFoundError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IStageNotFoundError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case ISubgraphInvalidError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; case IInvalidGraphQLSchemaError err: @@ -233,7 +233,7 @@ private static void PrintMutationError(this IAnsiConsole ansiConsole, object err break; case IInvalidFusionSourceSchemaArchiveError err: - ansiConsole.Error.WriteLine( + ansiConsole.WriteLine( "The server received an invalid archive. " + "This indicates a bug in the tooling. " + "Please notify ChilliCream." @@ -241,11 +241,11 @@ private static void PrintMutationError(this IAnsiConsole ansiConsole, object err break; case IError err: - ansiConsole.Error.WriteLine(err.Message); + ansiConsole.WriteLine(err.Message); break; default: - ansiConsole.Error.WriteLine("Unexpected Error"); + ansiConsole.WriteLine("Unexpected Error"); break; } } diff --git a/src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionComposeCommandTests.cs b/src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionComposeCommandTests.cs index 146c2139838..e9ac063030c 100644 --- a/src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionComposeCommandTests.cs +++ b/src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionComposeCommandTests.cs @@ -321,7 +321,7 @@ public async Task Compose_FromNonExistentFiles() Assert.Equal(1, exitCode); Assert.Matches( "^❌ Source schema file '[^']*non-existent-1.graphqls' does not exist.$", - testConsole.Error.ToString()!.ReplaceLineEndings("\n")); + testConsole.Out.ToString()!.ReplaceLineEndings("\n")); } [Fact] @@ -370,7 +370,7 @@ public async Task Compose_InvalidExample2_FromWorkingDirectory_ToStdOutWithWarni // assert Assert.Equal(1, exitCode); - testConsole.Error.ToString()!.ReplaceLineEndings("\n").MatchSnapshot(); + testConsole.Out.ToString()!.ReplaceLineEndings("\n").MatchSnapshot(); } [Fact] From b28b40b5d7d287f8a45fd3504272c48d9cfdf209 Mon Sep 17 00:00:00 2001 From: Glen Date: Fri, 30 Jan 2026 10:42:52 +0200 Subject: [PATCH 2/3] Write raw JSON (no syntax highlighting) --- .../CommandLine/src/CommandLine/Results/JsonResultFormatter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nitro/CommandLine/src/CommandLine/Results/JsonResultFormatter.cs b/src/Nitro/CommandLine/src/CommandLine/Results/JsonResultFormatter.cs index 0a68ed95109..8b80ce1e475 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Results/JsonResultFormatter.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Results/JsonResultFormatter.cs @@ -23,6 +23,6 @@ private void FormatObjectResult(ObjectResult objectResult) var serializedObj = JsonSerializer.Serialize(obj, obj.GetType(), JsonSourceGenerationContext.Default); - console.Write(new JsonText(serializedObj)); + console.Write(serializedObj); } } From e149bd9c8d0cfc9518897af8014013e1c5c93f6d Mon Sep 17 00:00:00 2001 From: Glen Date: Fri, 30 Jan 2026 11:30:08 +0200 Subject: [PATCH 3/3] Fixed use of NITRO_OUTPUT_FORMAT --- .../CommandLine/Results/ResultCommandLineBuilderExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nitro/CommandLine/src/CommandLine/Results/ResultCommandLineBuilderExtensions.cs b/src/Nitro/CommandLine/src/CommandLine/Results/ResultCommandLineBuilderExtensions.cs index 9a4d5328818..4eda86ad92a 100644 --- a/src/Nitro/CommandLine/src/CommandLine/Results/ResultCommandLineBuilderExtensions.cs +++ b/src/Nitro/CommandLine/src/CommandLine/Results/ResultCommandLineBuilderExtensions.cs @@ -20,7 +20,8 @@ private static async Task Middleware( { var resultHolder = context.BindingContext.GetRequiredService(); var formatters = context.BindingContext.GetServices(); - var format = context.ParseResult.GetValueForOption(Opt.Instance); + var format = + context.ParseResult.FindResultFor(Opt.Instance)?.GetValueOrDefault(); var isInteractive = format is null; var extendedConsole = context.BindingContext.GetRequiredService() as IExtendedConsole ??