Skip to content

Commit

Permalink
asyncapi#196 Test for dotnet cli tool, added support for default asyn…
Browse files Browse the repository at this point in the history
…capi document
  • Loading branch information
Senn Geerts authored and Senn Geerts committed Jul 6, 2024
1 parent 569a30a commit 0419101
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 14 deletions.
17 changes: 16 additions & 1 deletion Saunter.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.IntegrationTests.Re
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Saunter.Tests.MarkerTypeTests", "test\Saunter.Tests.MarkerTypeTests\Saunter.Tests.MarkerTypeTests.csproj", "{02284473-6DE7-4EE0-8433-2AC295045549}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncAPI.Saunter.Generator.Cli", "src\AsyncAPI.Saunter.Generator.Cli\AsyncAPI.Saunter.Generator.Cli.csproj", "{6C102D4D-3DA4-4763-B75E-C15E33E7E94A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsyncAPI.Saunter.Generator.Cli", "src\AsyncAPI.Saunter.Generator.Cli\AsyncAPI.Saunter.Generator.Cli.csproj", "{6C102D4D-3DA4-4763-B75E-C15E33E7E94A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsyncAPI.Saunter.Generator.Cli.Tests", "test\AsyncAPI.Saunter.Generator.Cli.Tests\AsyncAPI.Saunter.Generator.Cli.Tests.csproj", "{18AD0249-0436-4A26-9972-B97BA6905A54}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -113,6 +115,18 @@ Global
{6C102D4D-3DA4-4763-B75E-C15E33E7E94A}.Release|x64.Build.0 = Release|Any CPU
{6C102D4D-3DA4-4763-B75E-C15E33E7E94A}.Release|x86.ActiveCfg = Release|Any CPU
{6C102D4D-3DA4-4763-B75E-C15E33E7E94A}.Release|x86.Build.0 = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Debug|x64.ActiveCfg = Debug|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Debug|x64.Build.0 = Debug|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Debug|x86.ActiveCfg = Debug|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Debug|x86.Build.0 = Debug|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|Any CPU.Build.0 = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|x64.ActiveCfg = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|x64.Build.0 = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|x86.ActiveCfg = Release|Any CPU
{18AD0249-0436-4A26-9972-B97BA6905A54}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -124,6 +138,7 @@ Global
{7CD09B89-130A-41AF-ADAE-2166C4ED695B} = {6491E321-2D02-44AB-9116-D722FE169595}
{02284473-6DE7-4EE0-8433-2AC295045549} = {6491E321-2D02-44AB-9116-D722FE169595}
{6C102D4D-3DA4-4763-B75E-C15E33E7E94A} = {28D4C365-FDED-49AE-A97D-36202E24A55A}
{18AD0249-0436-4A26-9972-B97BA6905A54} = {6491E321-2D02-44AB-9116-D722FE169595}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2F85D9DA-DBCF-4F13-8C42-5719F1469B2E}
Expand Down
37 changes: 29 additions & 8 deletions src/AsyncAPI.Saunter.Generator.Cli/Commands/TofileInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore;
using Microsoft.Extensions.Hosting;
using Saunter.AsyncApiSchema.v2;
using static Program;
using AsyncApiDocument = Saunter.AsyncApiSchema.v2.AsyncApiDocument;

namespace AsyncApi.Saunter.Generator.Cli.Commands;

internal class TofileInternal
{
private const string defaultDocumentName = null;

internal static int Run(IDictionary<string, string> namedArgs)
{
// 1) Configure host with provided startupassembly
Expand All @@ -43,24 +47,41 @@ internal static int Run(IDictionary<string, string> namedArgs)

// 3) Retrieve AsyncAPI via configured provider
var documentProvider = serviceProvider.GetService<IAsyncApiDocumentProvider>();
var asyncapiOptions = serviceProvider.GetService<IOptions<AsyncApiOptions>>();
var asyncapiOptions = serviceProvider.GetService<IOptions<AsyncApiOptions>>().Value;
var documentSerializer = serviceProvider.GetRequiredService<IAsyncApiDocumentSerializer>();

var documentNames = namedArgs.TryGetValue(DocOption, out var doc) ? [doc] : asyncapiOptions.Value.NamedApis.Keys;
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)
{
if (asyncapiOptions.AssemblyMarkerTypes.Any())
{
documentNames = [defaultDocumentName];
}
else
{
throw new ArgumentOutOfRangeException(DocOption, $"No AsyncAPI documents found: {DocOption} = '{doc}'. Known document(s): {string.Join(", ", asyncapiOptions.NamedApis.Keys)}.");
}
}

foreach (var documentName in documentNames)
{
if (!asyncapiOptions.Value.NamedApis.TryGetValue(documentName, out var prototype))
AsyncApiDocument prototype;
if (documentName == defaultDocumentName)
{
prototype = asyncapiOptions.AsyncApi;
}
else if (!asyncapiOptions.NamedApis.TryGetValue(documentName, out prototype))
{
throw new ArgumentOutOfRangeException(DocOption, documentName, $"Requested AsyncAPI document not found: '{documentName}'. Known document(s): {string.Join(", ", asyncapiOptions.Value.NamedApis.Keys)}.");
throw new ArgumentOutOfRangeException(DocOption, documentName, $"Requested AsyncAPI document not found: '{documentName}'. Known document(s): {string.Join(", ", asyncapiOptions.NamedApis.Keys)}.");
}

var asyncApiSchema = documentProvider.GetDocument(asyncapiOptions.Value, prototype);
var asyncApiSchemaJson = documentSerializer.Serialize(asyncApiSchema);
var schema = documentProvider.GetDocument(asyncapiOptions, prototype);
var asyncApiSchemaJson = documentSerializer.Serialize(schema);
var asyncApiDocument = new AsyncApiStringReader().Read(asyncApiSchemaJson, out var diagnostic);
if (diagnostic.Errors.Any())
{
Console.Error.WriteLine($"AsyncAPI Schema '{documentName}' is not valid ({diagnostic.Errors.Count} Error(s), {diagnostic.Warnings.Count} Warning(s)):" +
Console.Error.WriteLine($"AsyncAPI Schema '{documentName ?? "default"}' is not valid ({diagnostic.Errors.Count} Error(s), {diagnostic.Warnings.Count} Warning(s)):" +
$"{Environment.NewLine}{string.Join(Environment.NewLine, diagnostic.Errors.Select(x => $"- {x}"))}");
}

Expand Down Expand Up @@ -123,7 +144,7 @@ private static string AddFileExtension(string outputPath, string fileTemplate, s
return outputPath;
}

return Path.Combine(outputPath, fileTemplate.Replace("{document}", documentName).Replace("{extension}", extension));
return Path.Combine(outputPath, fileTemplate.Replace("{document}", documentName == defaultDocumentName ? "" : documentName).Replace("{extension}", extension).TrimStart('_'));
}

private static IServiceProvider GetServiceProvider(Assembly startupAssembly)
Expand Down
10 changes: 5 additions & 5 deletions src/AsyncAPI.Saunter.Generator.Cli/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ dotnet asyncapi.net tofile --output [output-path] --format [json,yml,yaml] --doc
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 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
<PackageReference Include="Shouldly" Version="4.2.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\AsyncAPI.Saunter.Generator.Cli\AsyncAPI.Saunter.Generator.Cli.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>
Loading

0 comments on commit 0419101

Please sign in to comment.