From 2c64dad7e22336720bae38a226bc3e4d8510aadf Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Wed, 13 Apr 2022 11:45:59 +0300 Subject: [PATCH 1/8] Add an optional --terse output commandline option --- src/Microsoft.OpenApi.Hidi/Program.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.OpenApi.Hidi/Program.cs b/src/Microsoft.OpenApi.Hidi/Program.cs index 8b466913c..6d06a6986 100644 --- a/src/Microsoft.OpenApi.Hidi/Program.cs +++ b/src/Microsoft.OpenApi.Hidi/Program.cs @@ -39,6 +39,9 @@ static async Task Main(string[] args) var formatOption = new Option("--format", "File format"); formatOption.AddAlias("-f"); + var terseOutputOption = new Option("--terseOutput", "Produce terse json output"); + terseOutputOption.AddAlias("-to"); + var logLevelOption = new Option("--loglevel", () => LogLevel.Information, "The log level to use when logging messages to the main output."); logLevelOption.AddAlias("-ll"); @@ -74,6 +77,7 @@ static async Task Main(string[] args) cleanOutputOption, versionOption, formatOption, + terseOutputOption, logLevelOption, filterByOperationIdsOption, filterByTagsOption, @@ -82,8 +86,8 @@ static async Task Main(string[] args) inlineExternalOption }; - transformCommand.SetHandler ( - OpenApiService.TransformOpenApiDocument, descriptionOption, csdlOption, csdlFilterOption, outputOption, cleanOutputOption, versionOption, formatOption, logLevelOption, inlineLocalOption, inlineExternalOption, filterByOperationIdsOption, filterByTagsOption, filterByCollectionOption); + transformCommand.SetHandler ( + OpenApiService.TransformOpenApiDocument, descriptionOption, csdlOption, csdlFilterOption, outputOption, cleanOutputOption, versionOption, formatOption, terseOutputOption, logLevelOption, inlineLocalOption, inlineExternalOption, filterByOperationIdsOption, filterByTagsOption, filterByCollectionOption); rootCommand.Add(transformCommand); rootCommand.Add(validateCommand); From 2bf6b366afb4d3eb488bc2ceb6b8ac026ee63824 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Wed, 13 Apr 2022 11:46:52 +0300 Subject: [PATCH 2/8] Add a terse object to the OpenApiWriterSettings --- src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs b/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs index 458d8f4a3..05237bc47 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs @@ -69,6 +69,11 @@ public ReferenceInlineSetting ReferenceInline { /// public bool InlineExternalReferences { get; set; } = false; + /// + /// Indicates whether or not the produced document will be written in a compact or pretty fashion. + /// + public bool Terse { get; set; } = false; + internal bool ShouldInlineReference(OpenApiReference reference) { From afba9d87050ffd67722f755a0ce2d7b23362a747 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Wed, 13 Apr 2022 11:47:57 +0300 Subject: [PATCH 3/8] Pass the terseOutput option provided to the OpenApiWriter settings for serializing JSON in a terse format --- src/Microsoft.OpenApi.Hidi/OpenApiService.cs | 11 +++++++---- src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs index feb62042b..3a333b89f 100644 --- a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs +++ b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs @@ -44,6 +44,7 @@ public static async Task TransformOpenApiDocument( bool cleanoutput, string? version, OpenApiFormat? format, + bool terseOutput, LogLevel loglevel, bool inlineLocal, bool inlineExternal, @@ -188,11 +189,13 @@ CancellationToken cancellationToken using var outputStream = output?.Create(); var textWriter = outputStream != null ? new StreamWriter(outputStream) : Console.Out; - var settings = new OpenApiWriterSettings() + var settings = new OpenApiWriterSettings(); + if (terseOutput) { - InlineLocalReferences = inlineLocal, - InlineExternalReferences = inlineExternal - }; + settings.Terse = terseOutput; + } + settings.InlineLocalReferences = inlineLocal; + settings.InlineExternalReferences = inlineExternal; IOpenApiWriter writer = openApiFormat switch { diff --git a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs index 5454e8da8..7c786fccb 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs @@ -35,6 +35,7 @@ public OpenApiJsonWriter(TextWriter textWriter, OpenApiJsonWriterSettings settin /// Settings for controlling how the OpenAPI document will be written out. public OpenApiJsonWriter(TextWriter textWriter, OpenApiWriterSettings settings) : base(textWriter, settings) { + _produceTerseOutput = settings.Terse; } /// From de72343b31fb5cd9f4e959ef7f745d5c6bb1710f Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Wed, 13 Apr 2022 11:49:52 +0300 Subject: [PATCH 4/8] Update the command format to kebab case --- src/Microsoft.OpenApi.Hidi/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.Hidi/Program.cs b/src/Microsoft.OpenApi.Hidi/Program.cs index 6d06a6986..80a4c2e14 100644 --- a/src/Microsoft.OpenApi.Hidi/Program.cs +++ b/src/Microsoft.OpenApi.Hidi/Program.cs @@ -39,7 +39,7 @@ static async Task Main(string[] args) var formatOption = new Option("--format", "File format"); formatOption.AddAlias("-f"); - var terseOutputOption = new Option("--terseOutput", "Produce terse json output"); + var terseOutputOption = new Option("--terse-output", "Produce terse json output"); terseOutputOption.AddAlias("-to"); var logLevelOption = new Option("--loglevel", () => LogLevel.Information, "The log level to use when logging messages to the main output."); From 11c346692fff56d10e6ec76536452e60fa494100 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Thu, 14 Apr 2022 13:57:27 +0300 Subject: [PATCH 5/8] Add check to prevent null reference exceptions when settings are null --- src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs index 7c786fccb..41712636b 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs @@ -35,7 +35,10 @@ public OpenApiJsonWriter(TextWriter textWriter, OpenApiJsonWriterSettings settin /// Settings for controlling how the OpenAPI document will be written out. public OpenApiJsonWriter(TextWriter textWriter, OpenApiWriterSettings settings) : base(textWriter, settings) { - _produceTerseOutput = settings.Terse; + if (settings != null) + { + _produceTerseOutput = settings.Terse; + } } /// From 41c198338fecfac12eefc50c15c9670df4ce6f44 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Thu, 14 Apr 2022 13:57:47 +0300 Subject: [PATCH 6/8] Update public api interface --- test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index f589fa032..cadd68963 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1297,7 +1297,7 @@ namespace Microsoft.OpenApi.Writers public class OpenApiJsonWriterSettings : Microsoft.OpenApi.Writers.OpenApiWriterSettings { public OpenApiJsonWriterSettings() { } - public bool Terse { get; set; } + public new bool Terse { get; set; } } public static class OpenApiWriterAnyExtensions { @@ -1379,6 +1379,7 @@ namespace Microsoft.OpenApi.Writers public bool InlineLocalReferences { get; set; } [System.Obsolete("Use InlineLocalReference and InlineExternalReference settings instead")] public Microsoft.OpenApi.Writers.ReferenceInlineSetting ReferenceInline { get; set; } + public bool Terse { get; set; } } public class OpenApiYamlWriter : Microsoft.OpenApi.Writers.OpenApiWriterBase { From 540b624a8efa0c93052ac0e37307dae739b7a5d0 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Thu, 14 Apr 2022 17:52:07 +0300 Subject: [PATCH 7/8] Add a terseOutput parameter to the OpenApiJsonWriter and refactor code --- src/Microsoft.OpenApi.Hidi/OpenApiService.cs | 12 +++++------- .../OpenApiSerializableExtensions.cs | 18 ++++++------------ .../Writers/OpenApiJsonWriter.cs | 8 +++----- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs index 3a333b89f..584087ea7 100644 --- a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs +++ b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs @@ -189,17 +189,15 @@ CancellationToken cancellationToken using var outputStream = output?.Create(); var textWriter = outputStream != null ? new StreamWriter(outputStream) : Console.Out; - var settings = new OpenApiWriterSettings(); - if (terseOutput) + var settings = new OpenApiWriterSettings() { - settings.Terse = terseOutput; - } - settings.InlineLocalReferences = inlineLocal; - settings.InlineExternalReferences = inlineExternal; + InlineLocalReferences = inlineLocal, + InlineExternalReferences = inlineExternal + }; IOpenApiWriter writer = openApiFormat switch { - OpenApiFormat.Json => new OpenApiJsonWriter(textWriter, settings), + OpenApiFormat.Json => terseOutput ? new OpenApiJsonWriter(textWriter, settings, terseOutput) : new OpenApiJsonWriter(textWriter, settings, false), OpenApiFormat.Yaml => new OpenApiYamlWriter(textWriter, settings), _ => throw new ArgumentException("Unknown format"), }; diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs index 4694692ad..f60c5483b 100755 --- a/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs @@ -83,20 +83,14 @@ public static void Serialize( throw Error.ArgumentNull(nameof(stream)); } - IOpenApiWriter writer; var streamWriter = new FormattingStreamWriter(stream, CultureInfo.InvariantCulture); - switch (format) - { - case OpenApiFormat.Json: - writer = new OpenApiJsonWriter(streamWriter,settings); - break; - case OpenApiFormat.Yaml: - writer = new OpenApiYamlWriter(streamWriter, settings); - break; - default: - throw new OpenApiException(string.Format(SRResource.OpenApiFormatNotSupported, format)); - } + IOpenApiWriter writer = format switch + { + OpenApiFormat.Json => new OpenApiJsonWriter(streamWriter, settings, false), + OpenApiFormat.Yaml => new OpenApiYamlWriter(streamWriter, settings), + _ => throw new OpenApiException(string.Format(SRResource.OpenApiFormatNotSupported, format)), + }; element.Serialize(writer, specVersion); } diff --git a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs index 41712636b..10049974b 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs @@ -33,12 +33,10 @@ public OpenApiJsonWriter(TextWriter textWriter, OpenApiJsonWriterSettings settin /// /// The text writer. /// Settings for controlling how the OpenAPI document will be written out. - public OpenApiJsonWriter(TextWriter textWriter, OpenApiWriterSettings settings) : base(textWriter, settings) + /// Setting for allowing the JSON emitted to be in terse format. + public OpenApiJsonWriter(TextWriter textWriter, OpenApiWriterSettings settings, bool terseOutput = false) : base(textWriter, settings) { - if (settings != null) - { - _produceTerseOutput = settings.Terse; - } + _produceTerseOutput = terseOutput; } /// From 13e888881c627e8d512ee6e72a7af54941ade424 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Thu, 14 Apr 2022 17:55:06 +0300 Subject: [PATCH 8/8] Clean up --- src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs | 6 ------ .../PublicApi/PublicApi.approved.txt | 5 ++--- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs b/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs index 05237bc47..cf00c1339 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiWriterSettings.cs @@ -69,12 +69,6 @@ public ReferenceInlineSetting ReferenceInline { /// public bool InlineExternalReferences { get; set; } = false; - /// - /// Indicates whether or not the produced document will be written in a compact or pretty fashion. - /// - public bool Terse { get; set; } = false; - - internal bool ShouldInlineReference(OpenApiReference reference) { return (reference.IsLocal && InlineLocalReferences) diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index cadd68963..02400ddd7 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1281,7 +1281,7 @@ namespace Microsoft.OpenApi.Writers { public OpenApiJsonWriter(System.IO.TextWriter textWriter) { } public OpenApiJsonWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiJsonWriterSettings settings) { } - public OpenApiJsonWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings settings) { } + public OpenApiJsonWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings settings, bool terseOutput = false) { } protected override int BaseIndentation { get; } public override void WriteEndArray() { } public override void WriteEndObject() { } @@ -1297,7 +1297,7 @@ namespace Microsoft.OpenApi.Writers public class OpenApiJsonWriterSettings : Microsoft.OpenApi.Writers.OpenApiWriterSettings { public OpenApiJsonWriterSettings() { } - public new bool Terse { get; set; } + public bool Terse { get; set; } } public static class OpenApiWriterAnyExtensions { @@ -1379,7 +1379,6 @@ namespace Microsoft.OpenApi.Writers public bool InlineLocalReferences { get; set; } [System.Obsolete("Use InlineLocalReference and InlineExternalReference settings instead")] public Microsoft.OpenApi.Writers.ReferenceInlineSetting ReferenceInline { get; set; } - public bool Terse { get; set; } } public class OpenApiYamlWriter : Microsoft.OpenApi.Writers.OpenApiWriterBase {