Skip to content

Commit cfc53fd

Browse files
[Nitro CLI] Add fusion run command (#8681)
1 parent 9595102 commit cfc53fd

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

src/Nitro/CommandLine/src/CommandLine.Cloud/Commands/Fusion/FusionCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public FusionCommand() : base("fusion")
88

99
AddCommand(new FusionDownloadCommand());
1010
AddCommand(new FusionPublishCommand());
11+
AddCommand(new FusionRunCommand());
1112
AddCommand(new FusionSettingsCommand());
1213
AddCommand(new FusionValidateCommand());
1314
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using System.Diagnostics;
2+
using System.Net;
3+
using System.Net.Sockets;
4+
using System.Runtime.InteropServices;
5+
using Microsoft.AspNetCore.Builder;
6+
using Microsoft.AspNetCore.Hosting;
7+
using Microsoft.Extensions.Hosting;
8+
9+
namespace ChilliCream.Nitro.CommandLine.Cloud.Commands.Fusion;
10+
11+
public class FusionRunCommand : Command
12+
{
13+
public FusionRunCommand() : base("run")
14+
{
15+
base.Description = "Starts a Fusion gateway with the specified configuration";
16+
17+
var archiveOption = new Option<FileInfo>("--fusion-archive")
18+
{
19+
Description = "The path to the Fusion configuration file",
20+
IsRequired = true
21+
};
22+
archiveOption.AddAlias("--far");
23+
archiveOption.AddAlias("-f");
24+
archiveOption.LegalFilePathsOnly();
25+
26+
AddOption(archiveOption);
27+
28+
this.SetHandler(async context =>
29+
{
30+
var archiveFile = context.ParseResult.GetValueForOption(archiveOption)!;
31+
32+
var console = context.BindingContext.GetRequiredService<IAnsiConsole>();
33+
34+
await ExecuteAsync(archiveFile, console, context.GetCancellationToken());
35+
});
36+
}
37+
38+
private static async Task ExecuteAsync(
39+
FileInfo archiveFile,
40+
IAnsiConsole console,
41+
CancellationToken cancellationToken)
42+
{
43+
if (!archiveFile.Exists)
44+
{
45+
throw new ExitException($"Archive file '{archiveFile.FullName}' does not exist.");
46+
}
47+
48+
var port = GetRandomUnusedPort();
49+
50+
var host = new WebHostBuilder()
51+
.UseKestrel()
52+
.UseUrls(new UriBuilder("http", "localhost", port).ToString())
53+
.ConfigureServices(services =>
54+
{
55+
services.AddRouting()
56+
.AddGraphQLGatewayServer()
57+
.AddFileSystemConfiguration(archiveFile.FullName);
58+
})
59+
.Configure(app =>
60+
{
61+
app.UseRouting();
62+
app.UseEndpoints(e => e.MapGraphQL());
63+
})
64+
.Build();
65+
66+
var lifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
67+
68+
lifetime.ApplicationStarted.Register(() =>
69+
{
70+
var graphqlUrl = $"http://localhost:{port}/graphql";
71+
72+
console.Success($"Starting server at {graphqlUrl}");
73+
74+
try
75+
{
76+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
77+
{
78+
Process.Start(new ProcessStartInfo(graphqlUrl) { UseShellExecute = true });
79+
}
80+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
81+
{
82+
Process.Start("xdg-open", graphqlUrl);
83+
}
84+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
85+
{
86+
Process.Start("open", graphqlUrl);
87+
}
88+
else
89+
{
90+
throw new NotSupportedException("Unsupported OS platform");
91+
}
92+
}
93+
catch
94+
{
95+
// If we can't open in the default browser, we don't do anything.
96+
}
97+
});
98+
99+
await host.RunAsync(cancellationToken);
100+
}
101+
102+
private static int GetRandomUnusedPort()
103+
{
104+
var listener = new TcpListener(IPAddress.Loopback, 0);
105+
listener.Start();
106+
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
107+
listener.Stop();
108+
return port;
109+
}
110+
}

src/Nitro/CommandLine/src/CommandLine.Cloud/Nitro.CommandLine.Cloud.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,6 @@
146146
<ProjectReference Include="..\..\..\..\StrawberryShake\Client\src\Transport.Http\StrawberryShake.Transport.Http.csproj" />
147147
<ProjectReference Include="..\..\..\..\HotChocolate\Fusion-vnext\src\Fusion.Packaging\HotChocolate.Fusion.Packaging.csproj" />
148148
<ProjectReference Include="..\CommandLine.Fusion\Nitro.CommandLine.Fusion.csproj" />
149+
<ProjectReference Include="..\..\..\..\HotChocolate\Fusion-vnext\src\Fusion.AspNetCore\HotChocolate.Fusion.AspNetCore.csproj" />
149150
</ItemGroup>
150151
</Project>

0 commit comments

Comments
 (0)