Skip to content

Commit 96b9a9c

Browse files
authored
Introduce Fusion Composition Settings File (#6345)
1 parent 7746450 commit 96b9a9c

File tree

7 files changed

+222
-12
lines changed

7 files changed

+222
-12
lines changed

src/HotChocolate/Fusion/src/Abstractions/FusionGraphPackage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public Task<JsonDocument> GetFusionGraphSettingsAsync(
196196
"""
197197
{
198198
"fusionTypePrefix" : null,
199-
"fusionTypeSelf": true
199+
"fusionTypeSelf": false
200200
}
201201
"""));
202202
}
@@ -220,7 +220,7 @@ public Task SetFusionGraphSettingsAsync(
220220
throw new FusionGraphPackageException(FusionGraphPackage_CannotWrite);
221221
}
222222

223-
if (_package.RelationshipExists(FusionId))
223+
if (_package.RelationshipExists(FusionSettingsId))
224224
{
225225
var relationship = _package.GetRelationship(FusionSettingsId);
226226
_package.DeletePart(relationship.TargetUri);

src/HotChocolate/Fusion/src/CommandLine/Commands/ComposeCommand.cs

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using System.CommandLine;
22
using System.Text.Json;
3+
using System.Text.Json.Serialization;
34
using HotChocolate.Fusion.CommandLine.Helpers;
45
using HotChocolate.Fusion.CommandLine.Options;
56
using HotChocolate.Fusion.Composition;
67
using HotChocolate.Fusion.Composition.Features;
78
using HotChocolate.Language;
89
using HotChocolate.Skimmed.Serialization;
910
using HotChocolate.Utilities;
11+
using static System.Text.Json.JsonSerializerDefaults;
1012
using static HotChocolate.Fusion.CommandLine.Helpers.PackageHelper;
1113

1214
namespace HotChocolate.Fusion.CommandLine.Commands;
@@ -28,10 +30,14 @@ public ComposeCommand() : base("compose")
2830
fusionPackageSettingsFile.AddAlias("--settings");
2931

3032
var workingDirectory = new WorkingDirectoryOption();
33+
34+
var enableNodes = new Option<bool?>("--enable-nodes");
35+
enableNodes.Arity = ArgumentArity.Zero;
3136

3237
AddOption(fusionPackageFile);
3338
AddOption(subgraphPackageFile);
3439
AddOption(workingDirectory);
40+
AddOption(enableNodes);
3541

3642
this.SetHandler(
3743
ExecuteAsync,
@@ -40,6 +46,7 @@ public ComposeCommand() : base("compose")
4046
subgraphPackageFile,
4147
fusionPackageSettingsFile,
4248
workingDirectory,
49+
enableNodes,
4350
Bind.FromServiceProvider<CancellationToken>());
4451
}
4552

@@ -49,6 +56,7 @@ private static async Task ExecuteAsync(
4956
List<FileInfo>? subgraphPackageFiles,
5057
FileInfo? settingsFile,
5158
DirectoryInfo workingDirectory,
59+
bool? enableNodes,
5260
CancellationToken cancellationToken)
5361
{
5462
// create directory for package file.
@@ -66,7 +74,7 @@ private static async Task ExecuteAsync(
6674

6775
if (settingsFile is null)
6876
{
69-
var settingsFileName = packageFile.Name + "-settings.json";
77+
var settingsFileName = System.IO.Path.GetFileNameWithoutExtension(packageFile.FullName) + "-settings.json";
7078

7179
if (packageFile.DirectoryName is not null)
7280
{
@@ -156,6 +164,11 @@ private static async Task ExecuteAsync(
156164
return;
157165
}
158166

167+
if(enableNodes.HasValue && enableNodes.Value)
168+
{
169+
settings.NodeField.Enabled = true;
170+
}
171+
159172
var features = CreateFeatures(settings);
160173

161174
var composer = new FusionGraphComposer(
@@ -175,8 +188,10 @@ private static async Task ExecuteAsync(
175188
var typeNames = FusionTypeNames.From(fusionGraphDoc);
176189
var rewriter = new Metadata.FusionGraphConfigurationToSchemaRewriter();
177190
var schemaDoc = (DocumentNode) rewriter.Rewrite(fusionGraphDoc, new(typeNames))!;
191+
using var updateSettingsJson = JsonSerializer.SerializeToDocument(settings, new JsonSerializerOptions(Web));
178192

179193
await package.SetFusionGraphAsync(fusionGraphDoc, cancellationToken);
194+
await package.SetFusionGraphSettingsAsync(updateSettingsJson, cancellationToken);
180195
await package.SetSchemaAsync(schemaDoc, cancellationToken);
181196

182197
foreach (var config in configs.Values)
@@ -206,7 +221,7 @@ private static FusionFeatureCollection CreateFeatures(
206221
{
207222
features.Add(
208223
FusionFeatures.TagDirective(
209-
settings.TagDirective.Exclude,
224+
settings.TagDirective.Exclude,
210225
settings.TagDirective.MakePublic));
211226
}
212227

@@ -248,26 +263,64 @@ public void Write(LogEntry e)
248263

249264
private class PackageSettings
250265
{
266+
private Feature? _reEncodeIds;
267+
private Feature? _nodeField;
268+
private TagDirective? _tagDirective;
269+
270+
[JsonPropertyName("fusionTypePrefix")]
271+
[JsonPropertyOrder(10)]
251272
public string? FusionTypePrefix { get; set; }
252273

274+
[JsonPropertyName("fusionTypeSelf")]
275+
[JsonPropertyOrder(11)]
253276
public bool FusionTypeSelf { get; set; }
254277

255-
public Feature NodeField { get; set; } = new();
278+
[JsonPropertyName("nodeField")]
279+
[JsonPropertyOrder(12)]
280+
public Feature NodeField
281+
{
282+
get => _nodeField ??= new();
283+
set => _nodeField = value;
284+
}
256285

257-
public Feature ReEncodeIds { get; set; } = new();
286+
[JsonPropertyName("reEncodeIds")]
287+
[JsonPropertyOrder(13)]
288+
public Feature ReEncodeIds
289+
{
290+
get => _reEncodeIds ??= new();
291+
set => _reEncodeIds = value;
292+
}
258293

259-
public TagDirective TagDirective { get; set; } = new();
294+
[JsonPropertyName("tagDirective")]
295+
[JsonPropertyOrder(14)]
296+
public TagDirective TagDirective
297+
{
298+
get => _tagDirective ??= new();
299+
set => _tagDirective = value;
300+
}
260301
}
261302

262303
private class Feature
263304
{
264-
public bool Enabled { get; set; } = false;
305+
[JsonPropertyName("enabled")]
306+
[JsonPropertyOrder(10)]
307+
public bool Enabled { get; set; }
265308
}
266309

267310
private sealed class TagDirective : Feature
268311
{
269-
public bool MakePublic { get; set; } = false;
312+
private string[]? _exclude;
270313

271-
public string[] Exclude { get; set; } = Array.Empty<string>();
314+
[JsonPropertyName("makePublic")]
315+
[JsonPropertyOrder(100)]
316+
public bool MakePublic { get; set; }
317+
318+
[JsonPropertyName("exclude")]
319+
[JsonPropertyOrder(101)]
320+
public string[] Exclude
321+
{
322+
get => _exclude ?? Array.Empty<string>();
323+
set => _exclude = value;
324+
}
272325
}
273326
}

src/HotChocolate/Fusion/src/CommandLine/Commands/RootCommand.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,3 @@ public RootCommand() : base("fusion")
1919
AddCommand(new SubgraphCommand());
2020
}
2121
}
22-
23-
// fusion compose --package --subgraph --subgraph

src/HotChocolate/Fusion/test/CommandLine.Tests/ComposeCommandTests.cs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using HotChocolate.Fusion.Composition;
88
using HotChocolate.Fusion.Shared;
99
using static HotChocolate.Fusion.Shared.DemoProjectSchemaExtensions;
10+
using Path = HotChocolate.Path;
1011

1112
namespace CommandLine.Tests;
1213

@@ -115,4 +116,115 @@ await app.InvokeAsync(
115116

116117
snapshot.MatchSnapshot();
117118
}
119+
120+
[Fact]
121+
public async Task Ensure_Default_Settings_Are_Included()
122+
{
123+
// arrange
124+
using var demoProject = await DemoProject.CreateAsync();
125+
var accountConfig = demoProject.Accounts.ToConfiguration(AccountsExtensionSdl);
126+
var account = CreateFiles(accountConfig);
127+
var subgraphPackageFile = CreateTempFile();
128+
129+
await PackageHelper.CreateSubgraphPackageAsync(
130+
subgraphPackageFile,
131+
new SubgraphFiles(
132+
account.SchemaFile,
133+
account.TransportConfigFile,
134+
account.ExtensionFiles));
135+
136+
var packageFile = CreateTempFile(Extensions.FusionPackage);
137+
138+
// act
139+
var app = App.CreateBuilder().Build();
140+
await app.InvokeAsync(new[] { "compose", "-p", packageFile, "-s", subgraphPackageFile });
141+
142+
// assert
143+
Assert.True(File.Exists(packageFile));
144+
145+
await using var package = FusionGraphPackage.Open(packageFile, FileAccess.Read);
146+
147+
using var settings = await package.GetFusionGraphSettingsAsync();
148+
settings.RootElement.ToString().MatchSnapshot(extension: ".json");
149+
}
150+
151+
[Fact]
152+
public async Task Ensure_Legacy_Node_Switch_Is_Recognized()
153+
{
154+
// arrange
155+
using var demoProject = await DemoProject.CreateAsync();
156+
var accountConfig = demoProject.Accounts.ToConfiguration(AccountsExtensionSdl);
157+
var account = CreateFiles(accountConfig);
158+
var subgraphPackageFile = CreateTempFile();
159+
160+
await PackageHelper.CreateSubgraphPackageAsync(
161+
subgraphPackageFile,
162+
new SubgraphFiles(
163+
account.SchemaFile,
164+
account.TransportConfigFile,
165+
account.ExtensionFiles));
166+
167+
var packageFile = CreateTempFile(Extensions.FusionPackage);
168+
169+
// act
170+
var app = App.CreateBuilder().Build();
171+
await app.InvokeAsync(new[] { "compose", "-p", packageFile, "-s", subgraphPackageFile, "--enable-nodes" });
172+
173+
// assert
174+
Assert.True(File.Exists(packageFile));
175+
176+
await using var package = FusionGraphPackage.Open(packageFile, FileAccess.Read);
177+
178+
using var settings = await package.GetFusionGraphSettingsAsync();
179+
settings.RootElement.ToString().MatchSnapshot(extension: ".json");
180+
}
181+
182+
[Fact]
183+
public async Task Ensure_Settings_Are_Included()
184+
{
185+
// arrange
186+
using var demoProject = await DemoProject.CreateAsync();
187+
var accountConfig = demoProject.Accounts.ToConfiguration(AccountsExtensionSdl);
188+
var account = CreateFiles(accountConfig);
189+
var subgraphPackageFile = CreateTempFile();
190+
191+
await PackageHelper.CreateSubgraphPackageAsync(
192+
subgraphPackageFile,
193+
new SubgraphFiles(
194+
account.SchemaFile,
195+
account.TransportConfigFile,
196+
account.ExtensionFiles));
197+
198+
var packageFile = CreateTempFile(Extensions.FusionPackage);
199+
var settingsFile = System.IO.Path.Combine(
200+
System.IO.Path.GetDirectoryName(packageFile)!,
201+
$"{System.IO.Path.GetFileNameWithoutExtension(packageFile)}-settings.json");
202+
203+
await File.WriteAllTextAsync(
204+
settingsFile,
205+
"""
206+
{
207+
"fusionTypePrefix": null,
208+
"fusionTypeSelf": false,
209+
"nodeField": { "enabled": true },
210+
"tagDirective": {
211+
"enabled": true,
212+
"makePublic": true,
213+
"exclude": ["internal"]
214+
}
215+
}
216+
""");
217+
218+
// act
219+
var app = App.CreateBuilder().Build();
220+
await app.InvokeAsync(new[] { "compose", "-p", packageFile, "-s", subgraphPackageFile });
221+
222+
// assert
223+
Assert.True(File.Exists(packageFile));
224+
225+
await using var package = FusionGraphPackage.Open(packageFile, FileAccess.Read);
226+
227+
using var settings = await package.GetFusionGraphSettingsAsync();
228+
settings.RootElement.ToString().MatchSnapshot(extension: ".json");
229+
}
118230
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"fusionTypePrefix": null,
3+
"fusionTypeSelf": false,
4+
"nodeField": {
5+
"enabled": false
6+
},
7+
"reEncodeIds": {
8+
"enabled": false
9+
},
10+
"tagDirective": {
11+
"enabled": false,
12+
"makePublic": false,
13+
"exclude": []
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"fusionTypePrefix": null,
3+
"fusionTypeSelf": false,
4+
"nodeField": {
5+
"enabled": true
6+
},
7+
"reEncodeIds": {
8+
"enabled": false
9+
},
10+
"tagDirective": {
11+
"enabled": false,
12+
"makePublic": false,
13+
"exclude": []
14+
}
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"fusionTypePrefix": null,
3+
"fusionTypeSelf": false,
4+
"nodeField": {
5+
"enabled": true
6+
},
7+
"reEncodeIds": {
8+
"enabled": false
9+
},
10+
"tagDirective": {
11+
"enabled": true,
12+
"makePublic": true,
13+
"exclude": [
14+
"internal"
15+
]
16+
}
17+
}

0 commit comments

Comments
 (0)