From 1ebb77c984c194947d0c9c00738e9570bb59d3bd Mon Sep 17 00:00:00 2001 From: Senn Geerts Date: Sun, 7 Jul 2024 11:39:54 +0200 Subject: [PATCH 1/2] #196 renamed tool to make up a more logical name, fixed empty parameter handling --- .../AsyncAPI.Saunter.Generator.Cli.csproj | 5 ++-- .../Commands/Tofile.cs | 2 +- .../Commands/TofileInternal.cs | 19 +++++++-------- src/AsyncAPI.Saunter.Generator.Cli/Program.cs | 6 ++--- src/AsyncAPI.Saunter.Generator.Cli/readme.md | 23 +++++++++++++------ ...syncAPI.Saunter.Generator.Cli.Tests.csproj | 6 ----- .../DotnetCliToolTests.cs | 2 +- .../PackAndInstallLocalTests.cs | 10 ++++---- .../asyncapi.cmd | 2 -- 9 files changed, 37 insertions(+), 38 deletions(-) delete mode 100755 test/AsyncAPI.Saunter.Generator.Cli.Tests/asyncapi.cmd diff --git a/src/AsyncAPI.Saunter.Generator.Cli/AsyncAPI.Saunter.Generator.Cli.csproj b/src/AsyncAPI.Saunter.Generator.Cli/AsyncAPI.Saunter.Generator.Cli.csproj index 0400c5ab..472cc32e 100644 --- a/src/AsyncAPI.Saunter.Generator.Cli/AsyncAPI.Saunter.Generator.Cli.csproj +++ b/src/AsyncAPI.Saunter.Generator.Cli/AsyncAPI.Saunter.Generator.Cli.csproj @@ -2,7 +2,7 @@ Exe - net8.0;net6.0 + net6.0;net8.0 enable 12 AsyncAPI.Saunter.Generator.Cli @@ -11,7 +11,7 @@ AsyncAPI Initiative true AsyncAPI.Saunter.Generator.Cli - AsyncAPI.NET + dotnet-asyncapi asyncapi;aspnetcore;openapi;documentation;amqp;generator;cli;tool readme.md logo.png @@ -23,6 +23,7 @@ false true snupkg + 1.0.1 diff --git a/src/AsyncAPI.Saunter.Generator.Cli/Commands/Tofile.cs b/src/AsyncAPI.Saunter.Generator.Cli/Commands/Tofile.cs index 9faa30c9..a447ce43 100644 --- a/src/AsyncAPI.Saunter.Generator.Cli/Commands/Tofile.cs +++ b/src/AsyncAPI.Saunter.Generator.Cli/Commands/Tofile.cs @@ -41,6 +41,6 @@ internal static Func, int> Run(string[] args) => nam private static string EscapePath(string path) { - return path.Contains(' ') ? "\"" + path + "\"" : path; + return (path.Contains(' ') || string.IsNullOrWhiteSpace(path)) ? "\"" + path + "\"" : path; } } diff --git a/src/AsyncAPI.Saunter.Generator.Cli/Commands/TofileInternal.cs b/src/AsyncAPI.Saunter.Generator.Cli/Commands/TofileInternal.cs index a3477c7a..5889e5d2 100644 --- a/src/AsyncAPI.Saunter.Generator.Cli/Commands/TofileInternal.cs +++ b/src/AsyncAPI.Saunter.Generator.Cli/Commands/TofileInternal.cs @@ -18,6 +18,7 @@ using Saunter.AsyncApiSchema.v2; using static Program; using AsyncApiDocument = Saunter.AsyncApiSchema.v2.AsyncApiDocument; +using System.IO; namespace AsyncApi.Saunter.Generator.Cli.Commands; @@ -31,7 +32,7 @@ internal static int Run(IDictionary namedArgs) var startupAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(Directory.GetCurrentDirectory(), namedArgs[StartupAssemblyArgument])); // 2) Build a service container that's based on the startup assembly - var envVars = namedArgs.TryGetValue(EnvOption, out var x) ? x.Split(',').Select(x => x.Trim()) : Array.Empty(); + var envVars = (namedArgs.TryGetValue(EnvOption, out var x) && !string.IsNullOrWhiteSpace(x)) ? x.Split(',').Select(x => x.Trim()) : Array.Empty(); foreach (var envVar in envVars.Select(x => x.Split('=').Select(x => x.Trim()).ToList())) { if (envVar.Count == 2) @@ -50,9 +51,9 @@ internal static int Run(IDictionary namedArgs) var asyncapiOptions = serviceProvider.GetService>().Value; var documentSerializer = serviceProvider.GetRequiredService(); - var documentNames = namedArgs.TryGetValue(DocOption, out var doc) ? [doc] : asyncapiOptions.NamedApis.Keys; - var fileTemplate = namedArgs.TryGetValue(FileNameOption, out var template) ? template : "{document}_asyncapi.{extension}"; - if (documentNames.Count == 0) + var documentNames = (namedArgs.TryGetValue(DocOption, out var doc) && !string.IsNullOrWhiteSpace(doc)) ? [doc] : asyncapiOptions.NamedApis.Keys; + var fileTemplate = (namedArgs.TryGetValue(FileNameOption, out var template) && !string.IsNullOrWhiteSpace(template)) ? template : "{document}_asyncapi.{extension}"; + if (documentNames.Count == 0) { if (asyncapiOptions.AssemblyMarkerTypes.Any()) { @@ -86,20 +87,16 @@ internal static int Run(IDictionary namedArgs) } // 4) Serialize to specified output location or stdout - var outputPath = namedArgs.TryGetValue(OutputOption, out var arg1) ? Path.Combine(Directory.GetCurrentDirectory(), arg1) : null; + var outputPath = (namedArgs.TryGetValue(OutputOption, out var path) && !string.IsNullOrWhiteSpace(path)) ? Path.Combine(Directory.GetCurrentDirectory(), path) : null; if (!string.IsNullOrEmpty(outputPath)) { - var directoryPath = Path.GetDirectoryName(outputPath); - if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath)) - { - Directory.CreateDirectory(directoryPath); - } + Directory.CreateDirectory(outputPath); } var exportJson = true; var exportYml = false; var exportYaml = false; - if (namedArgs.TryGetValue(FormatOption, out var format)) + if (namedArgs.TryGetValue(FormatOption, out var format) && !string.IsNullOrWhiteSpace(format)) { var splitted = format.Split(',').Select(x => x.Trim()).ToList(); exportJson = splitted.Any(x => x.Equals("json", StringComparison.OrdinalIgnoreCase)); diff --git a/src/AsyncAPI.Saunter.Generator.Cli/Program.cs b/src/AsyncAPI.Saunter.Generator.Cli/Program.cs index 4d174c60..b9facd2b 100644 --- a/src/AsyncAPI.Saunter.Generator.Cli/Program.cs +++ b/src/AsyncAPI.Saunter.Generator.Cli/Program.cs @@ -5,14 +5,14 @@ DependencyResolver.Init(); // Helper to simplify command line parsing etc. -var runner = new CommandRunner("dotnet asyncapi.net", "AsyncAPI Command Line Tools", Console.Out); +var runner = new CommandRunner("dotnet asyncapi", "AsyncAPI Command Line Tools", Console.Out); // NOTE: The "dotnet asyncapi tofile" command does not serve the request directly. Instead, it invokes a corresponding // command (called _tofile) via "dotnet exec" so that the runtime configuration (*.runtimeconfig & *.deps.json) of the // provided startupassembly can be used instead of the tool's. This is neccessary to successfully load the // startupassembly and it's transitive dependencies. See https://github.com/dotnet/coreclr/issues/13277 for more. -// > dotnet asyncapi.net tofile ... +// > dotnet asyncapi tofile ... runner.SubCommand("tofile", "retrieves AsyncAPI from a startup assembly, and writes to file ", c => { c.Argument(StartupAssemblyArgument, "relative path to the application's startup assembly"); @@ -24,7 +24,7 @@ c.OnRun(Tofile.Run(args)); }); -// > dotnet asyncapi.net _tofile ... (* should only be invoked via "dotnet exec") +// > dotnet asyncapi _tofile ... (* should only be invoked via "dotnet exec") runner.SubCommand("_tofile", "", c => { c.Argument(StartupAssemblyArgument, ""); diff --git a/src/AsyncAPI.Saunter.Generator.Cli/readme.md b/src/AsyncAPI.Saunter.Generator.Cli/readme.md index 11d3c9b4..74d5c81b 100644 --- a/src/AsyncAPI.Saunter.Generator.Cli/readme.md +++ b/src/AsyncAPI.Saunter.Generator.Cli/readme.md @@ -1,15 +1,24 @@ # AsyncApi Generator.Cli Tool -A dotnet tool to generate AsyncAPI specification files based of dotnet DLL (The application itself). +A dotnet tool to generate AsyncAPI specification files based of a dotnet DLL (The application itself). ## Tool usage ``` -dotnet asyncapi.net tofile --output [output-path] --format [json,yml,yaml] --doc [asyncapi-document-name] [startup-assembly] +dotnet asyncapi tofile --output [output-path] --format [json,yml,yaml] --doc [asyncapi-document-name] [startup-assembly] ``` startup-assembly: the file path to the entrypoint dotnet DLL that hosts AsyncAPI document(s). ## Tool options ---doc: The name of the AsyncAPI document as defined in the startup class by the ```.ConfigureNamedAsyncApi()```-method. If not specified, all documents will be exported. ---output: relative path where the AsyncAPI will be output [defaults to stdout] ---filename: the template for the outputted file names. Default: "{document}_asyncapi.{extension}" ---format: the output formats to generate, can be a combination of json, yml and/or yaml. File extension is appended to the output path. ---env: define environment variable(s) for the application +- _--doc_: The name of the AsyncAPI document as defined in the startup class by the ```.ConfigureNamedAsyncApi()```-method. If only ```.AddAsyncApiSchemaGeneration()``` is used, the document is unnamed and will always be exported. If not specified, all documents will be exported. +- _--output_: relative path where the AsyncAPI will be output [defaults to stdout] +- _--filename_: the template for the outputted file names. Default: "{document}_asyncapi.{extension}" +- _--format_: the output formats to generate, can be a combination of json, yml and/or yaml. File extension is appended to the output path. +- _--env_: define environment variable(s) for the application + +## Install the Generator.Cli dotnet Tool +``` +dotnet tool install --global AsyncAPI.Saunter.Generator.Cli +``` +After installing the tool globally, it is available using commands: ```dotnet asyncapi``` or ```dotnet-asyncapi``` + +Want to learn more about .NET tools? Or want to install it local using a manifest? +(Check out this Microsoft page on how to manage .NET tools)[https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools] \ No newline at end of file diff --git a/test/AsyncAPI.Saunter.Generator.Cli.Tests/AsyncAPI.Saunter.Generator.Cli.Tests.csproj b/test/AsyncAPI.Saunter.Generator.Cli.Tests/AsyncAPI.Saunter.Generator.Cli.Tests.csproj index 3a1e115b..355fdd59 100644 --- a/test/AsyncAPI.Saunter.Generator.Cli.Tests/AsyncAPI.Saunter.Generator.Cli.Tests.csproj +++ b/test/AsyncAPI.Saunter.Generator.Cli.Tests/AsyncAPI.Saunter.Generator.Cli.Tests.csproj @@ -24,10 +24,4 @@ - - - PreserveNewest - - - diff --git a/test/AsyncAPI.Saunter.Generator.Cli.Tests/DotnetCliToolTests.cs b/test/AsyncAPI.Saunter.Generator.Cli.Tests/DotnetCliToolTests.cs index 3d6c7324..97258c87 100644 --- a/test/AsyncAPI.Saunter.Generator.Cli.Tests/DotnetCliToolTests.cs +++ b/test/AsyncAPI.Saunter.Generator.Cli.Tests/DotnetCliToolTests.cs @@ -35,7 +35,7 @@ public void DefaultCallPrintsCommandInfo() var stdOut = RunTool("", 1); stdOut.ShouldBe(""" - Usage: dotnet asyncapi.net tofile [options] [startupassembly] + Usage: dotnet asyncapi tofile [options] [startupassembly] startupassembly: relative path to the application's startup assembly diff --git a/test/AsyncAPI.Saunter.Generator.Cli.Tests/PackAndInstallLocalTests.cs b/test/AsyncAPI.Saunter.Generator.Cli.Tests/PackAndInstallLocalTests.cs index 34930f30..79d9844d 100644 --- a/test/AsyncAPI.Saunter.Generator.Cli.Tests/PackAndInstallLocalTests.cs +++ b/test/AsyncAPI.Saunter.Generator.Cli.Tests/PackAndInstallLocalTests.cs @@ -38,19 +38,19 @@ public void Pack_Install_Run_Uninstall_Test() stdOut.ShouldContain("Successfully created package"); stdOut = this.Run("dotnet", "tool install --global --add-source ./bin/Release AsyncAPI.Saunter.Generator.Cli", "../../../../../src/AsyncAPI.Saunter.Generator.Cli"); - stdOut.ShouldBeOneOf("You can invoke the tool using the following command: AsyncAPI.NET\r\nTool 'asyncapi.saunter.generator.cli' (version '1.0.0') was successfully installed.", - "Tool 'asyncapi.saunter.generator.cli' was reinstalled with the stable version (version '1.0.0')."); + stdOut.ShouldBeOneOf("You can invoke the tool using the following command: dotnet-asyncapi\r\nTool 'asyncapi.saunter.generator.cli' (version '1.0.1') was successfully installed.", + "Tool 'asyncapi.saunter.generator.cli' was reinstalled with the stable version (version '1.0.1')."); stdOut = this.Run("dotnet", "tool list -g asyncapi.saunter.generator.cli", ""); - stdOut.ShouldContain("AsyncAPI.NET"); + stdOut.ShouldContain("dotnet-asyncapi"); - stdOut = this.Run("asyncapi.cmd", "", "", 1); + stdOut = this.Run("dotnet", "asyncapi", "", 1); stdOut.ShouldContain("tofile: retrieves AsyncAPI from a startup assembly, and writes to file"); stdOut = this.Run("dotnet", "tool uninstall -g asyncapi.saunter.generator.cli", ""); stdOut.ShouldContain(" was successfully uninstalled."); stdOut = this.Run("dotnet", "tool list -g asyncapi.saunter.generator.cli", "", 1); - stdOut.ShouldNotContain("AsyncAPI.NET"); + stdOut.ShouldNotContain("dotnet-asyncapi"); } } diff --git a/test/AsyncAPI.Saunter.Generator.Cli.Tests/asyncapi.cmd b/test/AsyncAPI.Saunter.Generator.Cli.Tests/asyncapi.cmd deleted file mode 100755 index 1f61f620..00000000 --- a/test/AsyncAPI.Saunter.Generator.Cli.Tests/asyncapi.cmd +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -AsyncAPI.NET \ No newline at end of file From ba1e8566cd3f2c2690d503dda90fa6baa36987c2 Mon Sep 17 00:00:00 2001 From: Senn Geerts Date: Sun, 7 Jul 2024 11:48:39 +0200 Subject: [PATCH 2/2] #196 fix readme error --- src/AsyncAPI.Saunter.Generator.Cli/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncAPI.Saunter.Generator.Cli/readme.md b/src/AsyncAPI.Saunter.Generator.Cli/readme.md index 74d5c81b..8eb9a503 100644 --- a/src/AsyncAPI.Saunter.Generator.Cli/readme.md +++ b/src/AsyncAPI.Saunter.Generator.Cli/readme.md @@ -21,4 +21,4 @@ dotnet tool install --global AsyncAPI.Saunter.Generator.Cli After installing the tool globally, it is available using commands: ```dotnet asyncapi``` or ```dotnet-asyncapi``` Want to learn more about .NET tools? Or want to install it local using a manifest? -(Check out this Microsoft page on how to manage .NET tools)[https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools] \ No newline at end of file +[Check out this Microsoft page on how to manage .NET tools](https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools) \ No newline at end of file