-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathProgram.cs
94 lines (84 loc) · 4.9 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using System;
using System.Reflection;
using System.Diagnostics;
using System.IO;
using System.Runtime.Loader;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Swagger;
namespace Swashbuckle.AspNetCore.Cli
{
class Program
{
static int Main(string[] args)
{
// Helper to simplify command line parsing etc.
var runner = new CommandRunner("dotnet swagger", "Swashbuckle (Swagger) Command Line Tools", Console.Out);
// NOTE: The "dotnet swagger 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 swagger tofile ...
runner.SubCommand("tofile", "retrieves Swagger from a startup assembly, and writes to file ", c =>
{
c.Argument("startupassembly", "relative path to the application's startup assembly");
c.Argument("swaggerdoc", "name of the swagger doc you want to retrieve, as configured in your startup class");
c.Argument("output", "relative path where the Swagger will be output");
c.Option("--host", "a specific host to include in the Swagger output");
c.Option("--basepath", "a specific basePath to inlcude in the Swagger output");
c.OnRun((namedArgs) =>
{
var depsFile = namedArgs["startupassembly"].Replace(".dll", ".deps.json");
var runtimeConfig = namedArgs["startupassembly"].Replace(".dll", ".runtimeconfig.json");
var subProcess = Process.Start("dotnet", string.Format(
"exec --depsfile {0} --runtimeconfig {1} {2} _{3}", // note the underscore
depsFile,
runtimeConfig,
typeof(Program).GetTypeInfo().Assembly.Location,
string.Join(" ", args)
));
subProcess.WaitForExit();
return subProcess.ExitCode;
});
});
// > dotnet swagger _tofile ... (* should only be invoked via "dotnet exec")
runner.SubCommand("_tofile", "retrieves Swagger from a startup assembly, and writes to file ", c =>
{
c.Argument("startupassembly", "relative path to the application's startup assembly");
c.Argument("swaggerdoc", "name of the swagger doc you want to retrieve, as configured in your startup class");
c.Argument("output", "relative path where the Swagger will be output");
c.Option("--host", "a specific host to include in the Swagger output");
c.Option("--basepath", "a specific basePath to inlcude in the Swagger output");
c.OnRun((namedArgs) =>
{
// 1) Configure host with provided startupassembly
var startupAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(
$"{Directory.GetCurrentDirectory()}\\{namedArgs["startupassembly"]}");
var host = WebHost.CreateDefaultBuilder()
.UseStartup(startupAssembly.FullName)
.Build();
// 2) Retrieve Swagger via configured provider
var swaggerProvider = (ISwaggerProvider)host.Services.GetService(typeof(ISwaggerProvider));
var swagger = swaggerProvider.GetSwagger(
namedArgs["swaggerdoc"],
namedArgs.ContainsKey("--host") ? namedArgs["--host"] : null,
namedArgs.ContainsKey("--basepath") ? namedArgs["--basepath"] : null,
null);
// 3) Write to specified output location
var outputPath = $"{Directory.GetCurrentDirectory()}\\{namedArgs["output"]}";
var mvcOptionsAccessor = (IOptions<MvcJsonOptions>)host.Services.GetService(typeof(IOptions<MvcJsonOptions>));
var serializer = SwaggerSerializerFactory.Create(mvcOptionsAccessor);
using (var streamWriter = File.CreateText(outputPath))
{
serializer.Serialize(streamWriter, swagger);
Console.WriteLine($"Swagger JSON succesfully written to {outputPath}");
}
return 0;
});
});
return runner.Run(args);
}
}
}