Skip to content

Commit a830577

Browse files
authored
Added command-line improvements for schema exports. (#8466)
1 parent 46148d2 commit a830577

18 files changed

+252
-13
lines changed

src/HotChocolate/AspNetCore/src/AspNetCore.CommandLine/Command/ExportCommand.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.CommandLine;
22
using System.Text;
33
using HotChocolate.Execution;
4+
using HotChocolate.Execution.Configuration;
45
using Microsoft.Extensions.DependencyInjection;
56
using Microsoft.Extensions.Hosting;
67

@@ -39,13 +40,26 @@ private static async Task ExecuteAsync(
3940
string? schemaName,
4041
CancellationToken cancellationToken)
4142
{
42-
schemaName ??= ISchemaDefinition.DefaultName;
43+
var provider = host.Services.GetRequiredService<IRequestExecutorProvider>();
4344

44-
var schema = await host.Services
45-
.GetRequiredService<IRequestExecutorProvider>()
46-
.GetExecutorAsync(schemaName, cancellationToken);
45+
if (schemaName is null)
46+
{
47+
var schemaNames = provider.SchemaNames;
48+
49+
if(schemaNames.IsEmpty)
50+
{
51+
console.WriteLine("No schemas registered.");
52+
return;
53+
}
54+
55+
schemaName = schemaNames.Contains(ISchemaDefinition.DefaultName)
56+
? ISchemaDefinition.DefaultName
57+
: schemaNames[1];
58+
}
59+
60+
var executor = await provider.GetExecutorAsync(schemaName, cancellationToken);
4761

48-
var sdl = schema.Schema.ToString();
62+
var sdl = executor.Schema.ToString();
4963

5064
if (output is not null)
5165
{
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System.CommandLine;
2+
using HotChocolate.Execution;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Hosting;
5+
6+
namespace HotChocolate.AspNetCore.CommandLine;
7+
8+
/// <summary>
9+
/// The export command can be used to export the schema to a file.
10+
/// </summary>
11+
internal sealed class ListCommand : Command
12+
{
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="ExportCommand"/> class.
15+
/// </summary>
16+
public ListCommand() : base("list")
17+
{
18+
Description = "List all registered GraphQL schemas.";
19+
20+
this.SetHandler(
21+
ExecuteAsync,
22+
Bind.FromServiceProvider<IConsole>(),
23+
Bind.FromServiceProvider<IHost>(),
24+
Bind.FromServiceProvider<CancellationToken>());
25+
}
26+
27+
private static Task ExecuteAsync(
28+
IConsole console,
29+
IHost host,
30+
CancellationToken cancellationToken)
31+
{
32+
var schemaNames = host.Services.GetRequiredService<IRequestExecutorProvider>().SchemaNames;
33+
34+
if(schemaNames.IsEmpty)
35+
{
36+
console.WriteLine("No schemas registered.");
37+
return Task.CompletedTask;
38+
}
39+
40+
foreach (var name in schemaNames)
41+
{
42+
console.WriteLine(name);
43+
}
44+
45+
return Task.CompletedTask;
46+
}
47+
}

src/HotChocolate/AspNetCore/src/AspNetCore.CommandLine/Command/SchemaCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ public SchemaCommand() : base("schema")
1515
Description = "Schema management commands.";
1616

1717
AddCommand(new ExportCommand());
18+
AddCommand(new ListCommand());
1819
}
1920
}

src/HotChocolate/AspNetCore/src/AspNetCore.CommandLine/WebApplicationExtensions.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ public static void RunWithGraphQLCommands(
9292
}
9393
}
9494

95-
private static bool IsGraphQLCommand(this string[] args)
95+
/// <summary>
96+
/// Checks if the provided arguments are a GraphQL command.
97+
/// </summary>
98+
/// <param name="args">The command line arguments.</param>
99+
/// <returns>
100+
/// Returns <see langword="true"/> if the arguments are a GraphQL command; otherwise, <see langword="false"/>.
101+
/// </returns>
102+
public static bool IsGraphQLCommand(this string[] args)
96103
=> args is ["schema", ..];
97104
}

src/HotChocolate/AspNetCore/test/AspNetCore.CommandLine.Tests/SchemaExportCommandTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public async Task App_Should_PrintSchema_When_OutputNotSpecified()
4949
}
5050

5151
[Fact]
52-
public async Task App_Should_WriteSchemaToFile_When_OutputOptionIsSpecfied()
52+
public async Task App_Should_WriteSchemaToFile_When_OutputOptionIsSpecified()
5353
{
5454
// arrange
5555
var services = new ServiceCollection();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using HotChocolate.Types;
2+
using System.CommandLine.IO;
3+
using System.CommandLine.Parsing;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Hosting;
6+
using Moq;
7+
8+
namespace HotChocolate.AspNetCore.CommandLine;
9+
10+
public class SchemaListCommandTests
11+
{
12+
[Fact]
13+
public async Task App_Should_List_All_SchemaNames()
14+
{
15+
// arrange
16+
var services = new ServiceCollection();
17+
services.AddGraphQL()
18+
.AddQueryType(x => x.Name("Query").Field("foo").Resolve("bar"));
19+
20+
var hostMock = new Mock<IHost>();
21+
hostMock
22+
.Setup(x => x.Services)
23+
.Returns(services.BuildServiceProvider());
24+
25+
var host = hostMock.Object;
26+
var console = new TestConsole();
27+
var app = new App(host).Build();
28+
29+
// act
30+
await app.InvokeAsync("schema list", console);
31+
32+
// assert
33+
console.Out.ToString().MatchSnapshot();
34+
}
35+
}

src/HotChocolate/AspNetCore/test/AspNetCore.CommandLine.Tests/__snapshots__/SchemaCommandTests.App_Should_OutputCorrectHelpTest_When_HelpIsRequested.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ Options:
99

1010
Commands:
1111
export Export the graphql schema. If no output (--output) is specified the schema will be printed to the console.
12+
list List all registered GraphQL schemas.
1213

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_Default

src/HotChocolate/Core/src/Execution.Abstractions/Execution/IRequestExecutorProvider.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
1+
using System.Collections.Immutable;
2+
13
namespace HotChocolate.Execution;
24

5+
/// <summary>
6+
/// Represents a provider for GraphQL request executors.
7+
/// </summary>
38
public interface IRequestExecutorProvider
49
{
10+
/// <summary>
11+
/// Gets the names of all registered schemas.
12+
/// </summary>
13+
ImmutableArray<string> SchemaNames { get; }
14+
15+
/// <summary>
16+
/// Gets a GraphQL request executor for the given schema name.
17+
/// </summary>
18+
/// <param name="schemaName">
19+
/// The name of the schema to get an executor for.
20+
/// </param>
21+
/// <param name="cancellationToken">
22+
/// The cancellation token.
23+
/// </param>
24+
/// <returns>
25+
/// Returns a GraphQL request executor.
26+
/// </returns>
527
public ValueTask<IRequestExecutor> GetExecutorAsync(
628
string? schemaName = null,
729
CancellationToken cancellationToken = default);

0 commit comments

Comments
 (0)