Skip to content

Commit 95e598b

Browse files
authored
Merge pull request #1113 from microsoft/dm/show
Adds support for generating Mermaid diagrams from APIs
2 parents 09b5c9f + a8a693d commit 95e598b

File tree

13 files changed

+865
-209
lines changed

13 files changed

+865
-209
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using System;
5+
using System.CommandLine;
6+
using System.CommandLine.Invocation;
7+
using System.IO;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
using Microsoft.Extensions.Logging;
11+
12+
namespace Microsoft.OpenApi.Hidi.Handlers
13+
{
14+
internal class ShowCommandHandler : ICommandHandler
15+
{
16+
public Option<string> DescriptionOption { get; set; }
17+
public Option<FileInfo> OutputOption { get; set; }
18+
public Option<LogLevel> LogLevelOption { get; set; }
19+
public Option<string> CsdlOption { get; set; }
20+
public Option<string> CsdlFilterOption { get; set; }
21+
22+
23+
public int Invoke(InvocationContext context)
24+
{
25+
return InvokeAsync(context).GetAwaiter().GetResult();
26+
}
27+
public async Task<int> InvokeAsync(InvocationContext context)
28+
{
29+
string openapi = context.ParseResult.GetValueForOption(DescriptionOption);
30+
FileInfo output = context.ParseResult.GetValueForOption(OutputOption);
31+
LogLevel logLevel = context.ParseResult.GetValueForOption(LogLevelOption);
32+
string csdlFilter = context.ParseResult.GetValueForOption(CsdlFilterOption);
33+
string csdl = context.ParseResult.GetValueForOption(CsdlOption);
34+
CancellationToken cancellationToken = (CancellationToken)context.BindingContext.GetService(typeof(CancellationToken));
35+
36+
using var loggerFactory = Logger.ConfigureLogger(logLevel);
37+
var logger = loggerFactory.CreateLogger<OpenApiService>();
38+
try
39+
{
40+
await OpenApiService.ShowOpenApiDocument(openapi, csdl, csdlFilter, output, logger, cancellationToken);
41+
42+
return 0;
43+
}
44+
catch (Exception ex)
45+
{
46+
#if DEBUG
47+
logger.LogCritical(ex, ex.Message);
48+
throw; // so debug tools go straight to the source of the exception when attached
49+
#else
50+
logger.LogCritical( ex.Message);
51+
return 1;
52+
#endif
53+
}
54+
}
55+
}
56+
}

src/Microsoft.OpenApi.Hidi/Handlers/TransformCommandHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public async Task<int> InvokeAsync(InvocationContext context)
5757
var logger = loggerFactory.CreateLogger<OpenApiService>();
5858
try
5959
{
60-
await OpenApiService.TransformOpenApiDocument(openapi, csdl, csdlFilter, output, cleanOutput, version, format, terseOutput, settingsFile, logLevel, inlineLocal, inlineExternal, filterbyoperationids, filterbytags, filterbycollection, cancellationToken);
60+
await OpenApiService.TransformOpenApiDocument(openapi, csdl, csdlFilter, output, cleanOutput, version, format, terseOutput, settingsFile, inlineLocal, inlineExternal, filterbyoperationids, filterbytags, filterbycollection, logger, cancellationToken);
6161

6262
return 0;
6363
}

src/Microsoft.OpenApi.Hidi/Handlers/ValidateCommandHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public async Task<int> InvokeAsync(InvocationContext context)
3030
var logger = loggerFactory.CreateLogger<OpenApiService>();
3131
try
3232
{
33-
await OpenApiService.ValidateOpenApiDocument(openapi, logLevel, cancellationToken);
33+
await OpenApiService.ValidateOpenApiDocument(openapi, logger, cancellationToken);
3434
return 0;
3535
}
3636
catch (Exception ex)

src/Microsoft.OpenApi.Hidi/OpenApiService.cs

Lines changed: 301 additions & 184 deletions
Large diffs are not rendered by default.

src/Microsoft.OpenApi.Hidi/Program.cs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,17 @@ namespace Microsoft.OpenApi.Hidi
1616
static class Program
1717
{
1818
static async Task Main(string[] args)
19-
{
20-
var rootCommand = new RootCommand() {};
19+
{
20+
var rootCommand = CreateRootCommand();
21+
22+
// Parse the incoming args and invoke the handler
23+
await rootCommand.InvokeAsync(args);
24+
25+
}
26+
27+
internal static RootCommand CreateRootCommand()
28+
{
29+
var rootCommand = new RootCommand() { };
2130

2231
// command option parameters and aliases
2332
var descriptionOption = new Option<string>("--openapi", "Input OpenAPI description file path or URL");
@@ -46,7 +55,7 @@ static async Task Main(string[] args)
4655

4756
var settingsFileOption = new Option<string>("--settings-path", "The configuration file with CSDL conversion settings.");
4857
settingsFileOption.AddAlias("--sp");
49-
58+
5059
var logLevelOption = new Option<LogLevel>("--log-level", () => LogLevel.Information, "The log level to use when logging messages to the main output.");
5160
logLevelOption.AddAlias("--ll");
5261

@@ -71,7 +80,7 @@ static async Task Main(string[] args)
7180
logLevelOption
7281
};
7382

74-
validateCommand.Handler = new ValidateCommandHandler
83+
validateCommand.Handler = new ValidateCommandHandler
7584
{
7685
DescriptionOption = descriptionOption,
7786
LogLevelOption = logLevelOption
@@ -88,7 +97,7 @@ static async Task Main(string[] args)
8897
formatOption,
8998
terseOutputOption,
9099
settingsFileOption,
91-
logLevelOption,
100+
logLevelOption,
92101
filterByOperationIdsOption,
93102
filterByTagsOption,
94103
filterByCollectionOption,
@@ -115,14 +124,29 @@ static async Task Main(string[] args)
115124
InlineExternalOption = inlineExternalOption
116125
};
117126

127+
var showCommand = new Command("show")
128+
{
129+
descriptionOption,
130+
csdlOption,
131+
csdlFilterOption,
132+
logLevelOption,
133+
outputOption,
134+
cleanOutputOption
135+
};
136+
137+
showCommand.Handler = new ShowCommandHandler
138+
{
139+
DescriptionOption = descriptionOption,
140+
CsdlOption = csdlOption,
141+
CsdlFilterOption = csdlFilterOption,
142+
OutputOption = outputOption,
143+
LogLevelOption = logLevelOption
144+
};
145+
146+
rootCommand.Add(showCommand);
118147
rootCommand.Add(transformCommand);
119148
rootCommand.Add(validateCommand);
120-
121-
// Parse the incoming args and invoke the handler
122-
await rootCommand.InvokeAsync(args);
123-
124-
//// Wait for logger to write messages to the console before exiting
125-
await Task.Delay(10);
126-
}
149+
return rootCommand;
150+
}
127151
}
128152
}

src/Microsoft.OpenApi.Hidi/readme.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
1-
# Overview
1+
# Overview
22

33
Hidi is a command line tool that makes it easy to work with and transform OpenAPI documents. The tool enables you validate and apply transformations to and from different file formats using various commands to do different actions on the files.
44

55
## Capabilities
6+
67
Hidi has these key capabilities that enable you to build different scenarios off the tool
78

89
• Validation of OpenAPI files
910
• Conversion of OpenAPI files into different file formats: convert files from JSON to YAML, YAML to JSON
1011
• Slice or filter OpenAPI documents to smaller subsets using operationIDs and tags
12+
• Generate a Mermaid diagram of the API from an OpenAPI document
1113

12-
13-
## Installation
14+
## Installation
1415

1516
Install [Microsoft.OpenApi.Hidi](https://www.nuget.org/packages/Microsoft.OpenApi.Hidi/1.0.0-preview4) package from NuGet by running the following command:
1617

17-
### .NET CLI(Global)
18+
### .NET CLI(Global)
19+
1820
1. dotnet tool install --global Microsoft.OpenApi.Hidi --prerelease
1921

2022

21-
### .NET CLI(local)
23+
### .NET CLI(local)
2224

2325
1. dotnet new tool-manifest #if you are setting up the OpenAPI.NET repo
2426
2. dotnet tool install --local Microsoft.OpenApi.Hidi --prerelease
@@ -27,14 +29,17 @@ Install [Microsoft.OpenApi.Hidi](https://www.nuget.org/packages/Microsoft.OpenAp
2729

2830

2931
## How to use Hidi
32+
3033
Once you've installed the package locally, you can invoke the Hidi by running: hidi [command].
3134
You can access the list of command options we have by running hidi -h
3235
The tool avails the following commands:
3336

3437
• Validate
3538
• Transform
39+
• Show
3640
37-
### Validate
41+
### Validate
42+
3843
This command option accepts an OpenAPI document as an input parameter, visits multiple OpenAPI elements within the document and returns statistics count report on the following elements:
3944

4045
• Path Items
@@ -54,9 +59,10 @@ It accepts the following command:
5459

5560
**Example:** `hidi.exe validate --openapi C:\OpenApidocs\Mail.yml --loglevel trace`
5661

57-
Run validate -h to see the options available.
58-
59-
### Transform
62+
Run validate -h to see the options available.
63+
64+
### Transform
65+
6066
Used to convert file formats from JSON to YAML and vice versa and performs slicing of OpenAPI documents.
6167

6268
This command accepts the following parameters:
@@ -90,3 +96,11 @@ This command accepts the following parameters:
9096
hidi transform -cs dataverse.csdl --csdlFilter "appointments,opportunities" -o appointmentsAndOpportunities.yaml -ll trace
9197
9298
Run transform -h to see all the available usage options.
99+
100+
### Show
101+
102+
This command accepts an OpenAPI document as an input parameter and generates a Markdown file that contains a diagram of the API using Mermaid syntax.
103+
104+
**Examples:**
105+
106+
1. hidi show -d files\People.yml -o People.md -ll trace

0 commit comments

Comments
 (0)