From 82c45e42efce1453ab69130ab84eed6dc45b8652 Mon Sep 17 00:00:00 2001 From: Lambish Date: Wed, 24 Jul 2024 12:48:37 +0200 Subject: [PATCH 1/6] Add option to specify custom OpenAPI output file name --- .../src/Commands/GetDocumentCommand.cs | 3 + .../src/Commands/GetDocumentCommandContext.cs | 5 ++ .../src/Commands/GetDocumentCommandWorker.cs | 18 ++++-- .../GetDocumentInsider/src/Resources.resx | 57 ++++++++++--------- 4 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs index efc2caa0cfb8..7c2ba04ef9a6 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs @@ -19,6 +19,7 @@ internal sealed class GetDocumentCommand : ProjectCommandBase private CommandOption _output; private CommandOption _openApiVersion; private CommandOption _documentName; + private CommandOption _outputFileName; public GetDocumentCommand(IConsole console) : base(console) { @@ -32,6 +33,7 @@ public override void Configure(CommandLineApplication command) _output = command.Option("--output ", Resources.OutputDescription); _openApiVersion = command.Option("--openapi-version ", Resources.OpenApiVersionDescription); _documentName = command.Option("--document-name ", Resources.DocumentNameDescription); + _outputFileName = command.Option("--output-file-name ", Resources.OutputFileNameDescription); } protected override void Validate() @@ -142,6 +144,7 @@ protected override int Execute() DocumentName = _documentName.Value(), ProjectName = ProjectName.Value(), Reporter = Reporter, + OutputFileName = _outputFileName.Value() }; return new GetDocumentCommandWorker(context).Process(); diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs index 558298a00a48..305835b8bd18 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs @@ -30,5 +30,10 @@ public class GetDocumentCommandContext // Generates all documents if not provided. public string DocumentName { get; set; } + //Custom name for the output file + //otherwise if document name == v1 = ProjectName.json + //else = ProjectName_documentName.json + public string OutputFileName { get; set; } + public IReporter Reporter { get; set; } } diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs index ce7c5a81f188..0fa8e9fc9d96 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs @@ -279,7 +279,8 @@ private bool GetDocuments(IServiceProvider services) _context.OutputDirectory, generateMethod, service, - generateWithVersionMethod); + generateWithVersionMethod, + _context.OutputFileName); if (filePath == null) { return false; @@ -308,7 +309,8 @@ private string GetDocument( string outputDirectory, MethodInfo generateMethod, object service, - MethodInfo? generateWithVersionMethod) + MethodInfo? generateWithVersionMethod, + string outputFileName) { _reporter.WriteInformation(Resources.FormatGeneratingDocument(documentName)); @@ -352,7 +354,7 @@ private string GetDocument( return null; } - var filePath = GetDocumentPath(documentName, projectName, outputDirectory); + var filePath = GetDocumentPath(documentName, projectName, outputDirectory, outputFileName); _reporter.WriteInformation(Resources.FormatWritingDocument(documentName, filePath)); try { @@ -371,10 +373,16 @@ private string GetDocument( return filePath; } - private static string GetDocumentPath(string documentName, string projectName, string outputDirectory) + private static string GetDocumentPath(string documentName, string projectName, string outputDirectory, string outputFileName) { string path; - if (string.Equals(DefaultDocumentName, documentName, StringComparison.Ordinal)) + + + if (!string.IsNullOrWhiteSpace(outputFileName)) + { + path = outputFileName + JsonExtension; + } + else if (string.Equals(DefaultDocumentName, documentName, StringComparison.Ordinal)) { // Leave default document name out of the filename. path = projectName + JsonExtension; diff --git a/src/Tools/GetDocumentInsider/src/Resources.resx b/src/Tools/GetDocumentInsider/src/Resources.resx index c45f510dce7b..f185b80edb6e 100644 --- a/src/Tools/GetDocumentInsider/src/Resources.resx +++ b/src/Tools/GetDocumentInsider/src/Resources.resx @@ -1,17 +1,17 @@  - @@ -209,4 +209,7 @@ Using discovered `GenerateAsync` overload with version parameter. + + Custom name for the output file, otherwise if document name == v1 = ProjectName.json else = ProjectName_documentName.json + From 5970e874510171a797a51a4b890c0ae4e54f53ad Mon Sep 17 00:00:00 2001 From: Lambish Date: Wed, 24 Jul 2024 23:41:11 +0200 Subject: [PATCH 2/6] Changed behavior to replace project name instead like recommended --- .../src/Commands/GetDocumentCommand.cs | 6 +++--- .../src/Commands/GetDocumentCommandContext.cs | 8 ++++---- .../src/Commands/GetDocumentCommandWorker.cs | 17 +++++++++-------- src/Tools/GetDocumentInsider/src/Resources.resx | 6 +++--- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs index 7c2ba04ef9a6..2d02194fd465 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs @@ -19,7 +19,7 @@ internal sealed class GetDocumentCommand : ProjectCommandBase private CommandOption _output; private CommandOption _openApiVersion; private CommandOption _documentName; - private CommandOption _outputFileName; + private CommandOption _projectNameOverride; public GetDocumentCommand(IConsole console) : base(console) { @@ -33,7 +33,7 @@ public override void Configure(CommandLineApplication command) _output = command.Option("--output ", Resources.OutputDescription); _openApiVersion = command.Option("--openapi-version ", Resources.OpenApiVersionDescription); _documentName = command.Option("--document-name ", Resources.DocumentNameDescription); - _outputFileName = command.Option("--output-file-name ", Resources.OutputFileNameDescription); + _projectNameOverride = command.Option("--projectName-override ", Resources.ProjectNameOverrideDescription); } protected override void Validate() @@ -144,7 +144,7 @@ protected override int Execute() DocumentName = _documentName.Value(), ProjectName = ProjectName.Value(), Reporter = Reporter, - OutputFileName = _outputFileName.Value() + ProjectNameOverride = _projectNameOverride.Value() }; return new GetDocumentCommandWorker(context).Process(); diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs index 305835b8bd18..906eeb87b832 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs @@ -30,10 +30,10 @@ public class GetDocumentCommandContext // Generates all documents if not provided. public string DocumentName { get; set; } - //Custom name for the output file - //otherwise if document name == v1 = ProjectName.json - //else = ProjectName_documentName.json - public string OutputFileName { get; set; } + //Override the default projectName + //By default if document name == v1 => output = projectName.json + //else projectName_documentName.json + public string ProjectNameOverride { get; set; } public IReporter Reporter { get; set; } } diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs index 0fa8e9fc9d96..b21679566763 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs @@ -280,7 +280,7 @@ private bool GetDocuments(IServiceProvider services) generateMethod, service, generateWithVersionMethod, - _context.OutputFileName); + _context.ProjectNameOverride); if (filePath == null) { return false; @@ -310,7 +310,7 @@ private string GetDocument( MethodInfo generateMethod, object service, MethodInfo? generateWithVersionMethod, - string outputFileName) + string projectNameOverride) { _reporter.WriteInformation(Resources.FormatGeneratingDocument(documentName)); @@ -354,7 +354,7 @@ private string GetDocument( return null; } - var filePath = GetDocumentPath(documentName, projectName, outputDirectory, outputFileName); + var filePath = GetDocumentPath(documentName, projectName, outputDirectory, projectNameOverride); _reporter.WriteInformation(Resources.FormatWritingDocument(documentName, filePath)); try { @@ -373,16 +373,17 @@ private string GetDocument( return filePath; } - private static string GetDocumentPath(string documentName, string projectName, string outputDirectory, string outputFileName) + private static string GetDocumentPath(string documentName, string projectName, string outputDirectory, string projectNameOverride) { string path; - - if (!string.IsNullOrWhiteSpace(outputFileName)) + //Override the default projectName with the one provided + if (!string.IsNullOrWhiteSpace(projectNameOverride)) { - path = outputFileName + JsonExtension; + projectName = projectNameOverride; } - else if (string.Equals(DefaultDocumentName, documentName, StringComparison.Ordinal)) + + if (string.Equals(DefaultDocumentName, documentName, StringComparison.Ordinal)) { // Leave default document name out of the filename. path = projectName + JsonExtension; diff --git a/src/Tools/GetDocumentInsider/src/Resources.resx b/src/Tools/GetDocumentInsider/src/Resources.resx index f185b80edb6e..062f4ebd4658 100644 --- a/src/Tools/GetDocumentInsider/src/Resources.resx +++ b/src/Tools/GetDocumentInsider/src/Resources.resx @@ -209,7 +209,7 @@ Using discovered `GenerateAsync` overload with version parameter. - - Custom name for the output file, otherwise if document name == v1 = ProjectName.json else = ProjectName_documentName.json + + Custom projectName that replace the default one, used to generate OpenAPI JSON - + \ No newline at end of file From 359e01b1dc37c38d7927a05e148e76ab2f88cc2a Mon Sep 17 00:00:00 2001 From: Lambish Date: Thu, 25 Jul 2024 00:06:27 +0200 Subject: [PATCH 3/6] Updated dotnet-getdocument options to show GetDocument.Insider commands in it with help command --- src/Tools/GetDocumentInsider/src/Resources.resx | 2 +- .../dotnet-getdocument/src/ProjectOptions.cs | 6 ++++++ src/Tools/dotnet-getdocument/src/Resources.resx | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Tools/GetDocumentInsider/src/Resources.resx b/src/Tools/GetDocumentInsider/src/Resources.resx index 062f4ebd4658..2cb2cb057f34 100644 --- a/src/Tools/GetDocumentInsider/src/Resources.resx +++ b/src/Tools/GetDocumentInsider/src/Resources.resx @@ -210,6 +210,6 @@ Using discovered `GenerateAsync` overload with version parameter. - Custom projectName that replace the default one, used to generate OpenAPI JSON + Custom projectName that replace the default one, used to generate OpenAPI JSON file \ No newline at end of file diff --git a/src/Tools/dotnet-getdocument/src/ProjectOptions.cs b/src/Tools/dotnet-getdocument/src/ProjectOptions.cs index f2b55eec5eb2..bb417445b9bf 100644 --- a/src/Tools/dotnet-getdocument/src/ProjectOptions.cs +++ b/src/Tools/dotnet-getdocument/src/ProjectOptions.cs @@ -27,6 +27,12 @@ public void Configure(CommandLineApplication command) Platform = command.Option("--platform ", Resources.PlatformDescription); ProjectName = command.Option("--project ", Resources.ProjectDescription); RuntimeFrameworkVersion = command.Option("--runtime ", Resources.RuntimeDescription); + command.Option("--prefix-output", Resources.PrefixDescription); + command.Option("--file-list ", Resources.FileListDescription); + command.Option("--output ", Resources.OutputDescription); + command.Option("--openapi-version ", Resources.OpenApiVersionDescription); + command.Option("--document-name ", Resources.DocumentNameDescription); + command.Option("--projectName-override ", Resources.ProjectNameOverrideDescription); } public void Validate() diff --git a/src/Tools/dotnet-getdocument/src/Resources.resx b/src/Tools/dotnet-getdocument/src/Resources.resx index 3f0b6440ad1f..34694f0ed1e9 100644 --- a/src/Tools/dotnet-getdocument/src/Resources.resx +++ b/src/Tools/dotnet-getdocument/src/Resources.resx @@ -162,4 +162,19 @@ Suppresses all output except warnings and errors. + + The path where the list of document files should be written. Required. + + + The directory where the document files should be written. Required. + + + The OpenAPI spec version to use when generating the document. Optional. + + + The name of the OpenAPI document to generate. Optional. + + + Custom projectName that replace the default one, used to generate OpenAPI JSON file + \ No newline at end of file From f2debd010f0c4936f246d02079836e1ef952e248 Mon Sep 17 00:00:00 2001 From: Lambish Date: Sun, 4 Aug 2024 13:47:20 +0200 Subject: [PATCH 4/6] Update command name, add file name validation and add tests --- .../src/Commands/GetDocumentCommand.cs | 6 +- .../src/Commands/GetDocumentCommandContext.cs | 11 ++- .../src/Commands/GetDocumentCommandWorker.cs | 28 ++++--- .../GetDocumentInsider/src/Resources.resx | 11 ++- .../tests/GetDocumentTests.cs | 82 +++++++++++++++++++ .../dotnet-getdocument/src/ProjectOptions.cs | 2 +- .../dotnet-getdocument/src/Resources.resx | 4 +- 7 files changed, 117 insertions(+), 27 deletions(-) diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs index 2d02194fd465..776cc68a56a6 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommand.cs @@ -19,7 +19,7 @@ internal sealed class GetDocumentCommand : ProjectCommandBase private CommandOption _output; private CommandOption _openApiVersion; private CommandOption _documentName; - private CommandOption _projectNameOverride; + private CommandOption _fileName; public GetDocumentCommand(IConsole console) : base(console) { @@ -33,7 +33,7 @@ public override void Configure(CommandLineApplication command) _output = command.Option("--output ", Resources.OutputDescription); _openApiVersion = command.Option("--openapi-version ", Resources.OpenApiVersionDescription); _documentName = command.Option("--document-name ", Resources.DocumentNameDescription); - _projectNameOverride = command.Option("--projectName-override ", Resources.ProjectNameOverrideDescription); + _fileName = command.Option("--file-name-override ", Resources.FileNameDescription); } protected override void Validate() @@ -144,7 +144,7 @@ protected override int Execute() DocumentName = _documentName.Value(), ProjectName = ProjectName.Value(), Reporter = Reporter, - ProjectNameOverride = _projectNameOverride.Value() + FileName = _fileName.Value() }; return new GetDocumentCommandWorker(context).Process(); diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs index 906eeb87b832..2ec4f44457fe 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandContext.cs @@ -30,10 +30,13 @@ public class GetDocumentCommandContext // Generates all documents if not provided. public string DocumentName { get; set; } - //Override the default projectName - //By default if document name == v1 => output = projectName.json - //else projectName_documentName.json - public string ProjectNameOverride { get; set; } + /// + /// The name of the generated OpenAPI document. + /// When the default document (v1) is generated, this maps + /// to {FileName}.json. For custom file names, this maps to + /// {FileName}_{DocumentName}.json. + /// + public string FileName { get; set; } public IReporter Reporter { get; set; } } diff --git a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs index b21679566763..2979644dcdc0 100644 --- a/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs +++ b/src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs @@ -2,12 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; @@ -267,6 +267,12 @@ private bool GetDocuments(IServiceProvider services) return false; } + if (!string.IsNullOrWhiteSpace(_context.FileName) && !Regex.IsMatch(_context.FileName, "^([A-Za-z0-9-_]+)$")) + { + _reporter.WriteError(Resources.FileNameFormatInvalid); + return false; + } + // Write out the documents. var found = false; Directory.CreateDirectory(_context.OutputDirectory); @@ -280,7 +286,7 @@ private bool GetDocuments(IServiceProvider services) generateMethod, service, generateWithVersionMethod, - _context.ProjectNameOverride); + _context.FileName); if (filePath == null) { return false; @@ -310,7 +316,7 @@ private string GetDocument( MethodInfo generateMethod, object service, MethodInfo? generateWithVersionMethod, - string projectNameOverride) + string fileName) { _reporter.WriteInformation(Resources.FormatGeneratingDocument(documentName)); @@ -354,7 +360,9 @@ private string GetDocument( return null; } - var filePath = GetDocumentPath(documentName, projectName, outputDirectory, projectNameOverride); + fileName = !string.IsNullOrWhiteSpace(fileName) ? fileName : projectName; + + var filePath = GetDocumentPath(documentName, fileName, outputDirectory); _reporter.WriteInformation(Resources.FormatWritingDocument(documentName, filePath)); try { @@ -373,20 +381,14 @@ private string GetDocument( return filePath; } - private static string GetDocumentPath(string documentName, string projectName, string outputDirectory, string projectNameOverride) + private static string GetDocumentPath(string documentName, string fileName, string outputDirectory) { string path; - //Override the default projectName with the one provided - if (!string.IsNullOrWhiteSpace(projectNameOverride)) - { - projectName = projectNameOverride; - } - if (string.Equals(DefaultDocumentName, documentName, StringComparison.Ordinal)) { // Leave default document name out of the filename. - path = projectName + JsonExtension; + path = fileName + JsonExtension; } else { @@ -401,7 +403,7 @@ private static string GetDocumentPath(string documentName, string projectName, s sanitizedDocumentName = sanitizedDocumentName.Replace(InvalidFilenameString, DotString); } - path = $"{projectName}_{documentName}{JsonExtension}"; + path = $"{fileName}_{documentName}{JsonExtension}"; } if (!string.IsNullOrEmpty(outputDirectory)) diff --git a/src/Tools/GetDocumentInsider/src/Resources.resx b/src/Tools/GetDocumentInsider/src/Resources.resx index 2cb2cb057f34..aad2cabce3bb 100644 --- a/src/Tools/GetDocumentInsider/src/Resources.resx +++ b/src/Tools/GetDocumentInsider/src/Resources.resx @@ -1,4 +1,4 @@ - +