Skip to content

Commit 1a0a26c

Browse files
Add --legacy-v1-archive option
1 parent a2808af commit 1a0a26c

9 files changed

Lines changed: 230 additions & 1 deletion

File tree

src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionComposeCommand.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public FusionComposeCommand() : base("compose")
1616

1717
Options.Add(Opt<OptionalSourceSchemaFileListOption>.Instance);
1818
Options.Add(Opt<OptionalFusionArchiveFileOption>.Instance);
19+
Options.Add(Opt<OptionalLegacyFusionArchiveFileOption>.Instance);
1920
Options.Add(Opt<FusionEnvironmentOption>.Instance);
2021
Options.Add(Opt<EnableGlobalObjectIdentificationOption>.Instance);
2122
Options.Add(Opt<IncludeSatisfiabilityPathsOption>.Instance);
@@ -57,6 +58,8 @@ private static async Task<int> ExecuteAsync(
5758
Opt<IncludeSatisfiabilityPathsOption>.Instance);
5859
var watchMode = parseResult.GetValue(Opt<WatchModeOption>.Instance);
5960
var tagsToExclude = parseResult.GetValue(Opt<OptionalExcludeTagListOption>.Instance);
61+
var legacyArchiveFile =
62+
parseResult.GetValue(Opt<OptionalLegacyFusionArchiveFileOption>.Instance);
6063
archiveFile ??= workingDirectory;
6164

6265
if (fileSystem.DirectoryExists(archiveFile))
@@ -68,6 +71,19 @@ private static async Task<int> ExecuteAsync(
6871
archiveFile = Path.Combine(workingDirectory, archiveFile);
6972
}
7073

74+
if (legacyArchiveFile is not null)
75+
{
76+
if (!Path.IsPathRooted(legacyArchiveFile))
77+
{
78+
legacyArchiveFile = Path.Combine(workingDirectory, legacyArchiveFile);
79+
}
80+
81+
if (!fileSystem.FileExists(legacyArchiveFile))
82+
{
83+
throw new ExitException(Messages.LegacyArchiveFileDoesNotExist(legacyArchiveFile));
84+
}
85+
}
86+
7187
if (sourceSchemaFiles.Count == 0)
7288
{
7389
sourceSchemaFiles.AddRange(

src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionPublishCommand.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public FusionPublishCommand() : base("publish")
3838
Options.Add(Opt<OptionalSourceSchemaIdentifierListOption>.Instance);
3939
Options.Add(Opt<OptionalSourceSchemaFileListOption>.Instance);
4040
Options.Add(Opt<OptionalFusionArchiveFileOption>.Instance);
41+
Options.Add(Opt<OptionalLegacyFusionArchiveFileOption>.Instance);
4142
Options.Add(Opt<OptionalForceOption>.Instance);
4243
Options.Add(Opt<OptionalWaitForApprovalOption>.Instance);
4344
Options.Add(Opt<WorkingDirectoryOption>.Instance);
@@ -90,6 +91,8 @@ private static async Task<int> ExecuteAsync(
9091
parseResult.GetValue(Opt<OptionalSourceSchemaIdentifierListOption>.Instance) ?? [];
9192
var archiveFile =
9293
parseResult.GetValue(Opt<OptionalFusionArchiveFileOption>.Instance);
94+
var legacyArchiveFile =
95+
parseResult.GetValue(Opt<OptionalLegacyFusionArchiveFileOption>.Instance);
9396
var force = parseResult.GetValue(Opt<OptionalForceOption>.Instance);
9497
var waitForApproval = parseResult.GetValue(Opt<OptionalWaitForApprovalOption>.Instance);
9598
var stageName = parseResult.GetRequiredValue(Opt<StageNameOption>.Instance);
@@ -121,9 +124,29 @@ archiveFile is not null
121124

122125
if (archiveFile is not null)
123126
{
127+
if (legacyArchiveFile is not null)
128+
{
129+
throw new ExitException(
130+
$"The options '{FusionArchiveFileOption.OptionName}' and '{OptionalLegacyFusionArchiveFileOption.OptionName}' are mutually exclusive.");
131+
}
132+
124133
return await PublishFusionConfigurationWithArchiveAsync();
125134
}
126-
else if (sourceSchemaFiles.Count > 0)
135+
136+
if (legacyArchiveFile is not null)
137+
{
138+
if (!Path.IsPathRooted(legacyArchiveFile))
139+
{
140+
legacyArchiveFile = Path.Combine(workingDirectory, legacyArchiveFile);
141+
}
142+
143+
if (!fileSystem.FileExists(legacyArchiveFile))
144+
{
145+
throw new ExitException(Messages.LegacyArchiveFileDoesNotExist(legacyArchiveFile));
146+
}
147+
}
148+
149+
if (sourceSchemaFiles.Count > 0)
127150
{
128151
return await PublishFusionConfigurationWithSourceSchemaFilesAsync();
129152
}

src/Nitro/CommandLine/src/CommandLine/Commands/Fusion/FusionValidateCommand.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public FusionValidateCommand() : base("validate")
2727
Options.Add(Opt<ApiIdOption>.Instance);
2828
Options.Add(Opt<StageNameOption>.Instance);
2929
Options.Add(Opt<OptionalFusionArchiveFileOption>.Instance);
30+
Options.Add(Opt<OptionalLegacyFusionArchiveFileOption>.Instance);
3031
Options.Add(Opt<OptionalSourceSchemaFileListOption>.Instance);
3132
this.AddGlobalNitroOptions();
3233

@@ -58,6 +59,7 @@ private static async Task<int> ExecuteAsync(
5859
var stageName = parseResult.GetRequiredValue(Opt<StageNameOption>.Instance);
5960
var apiId = parseResult.GetRequiredValue(Opt<ApiIdOption>.Instance);
6061
var archiveFile = parseResult.GetValue(Opt<OptionalFusionArchiveFileOption>.Instance);
62+
var legacyArchiveFile = parseResult.GetValue(Opt<OptionalLegacyFusionArchiveFileOption>.Instance);
6163
var sourceSchemaFiles =
6264
parseResult.GetValue(Opt<OptionalSourceSchemaFileListOption>.Instance) ?? [];
6365

@@ -80,10 +82,29 @@ archiveFile is not null
8082

8183
if (archiveFile is not null)
8284
{
85+
if (legacyArchiveFile is not null)
86+
{
87+
throw new ExitException(
88+
$"The options '{FusionArchiveFileOption.OptionName}' and '{OptionalLegacyFusionArchiveFileOption.OptionName}' are mutually exclusive.");
89+
}
90+
8391
return await ValidateWithArchive();
8492
}
8593
else
8694
{
95+
if (legacyArchiveFile is not null)
96+
{
97+
if (!Path.IsPathRooted(legacyArchiveFile))
98+
{
99+
legacyArchiveFile = Path.Combine(fileSystem.GetCurrentDirectory(), legacyArchiveFile);
100+
}
101+
102+
if (!fileSystem.FileExists(legacyArchiveFile))
103+
{
104+
throw new ExitException(Messages.LegacyArchiveFileDoesNotExist(legacyArchiveFile));
105+
}
106+
}
107+
87108
return await ValidateWithSourceSchemaFiles();
88109
}
89110

src/Nitro/CommandLine/src/CommandLine/Messages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public static string UnexpectedMutationError(IError error)
2121

2222
public static string ArchiveFileDoesNotExist(string path) => $"Archive file '{path}' does not exist.";
2323

24+
public static string LegacyArchiveFileDoesNotExist(string path) => $"Legacy archive file '{path}' does not exist.";
25+
2426
public static string OperationsFileDoesNotExist(string path) => $"Operations file '{path}' does not exist.";
2527

2628
public static string ExtensionFileDoesNotExist(string path) => $"Extension file '{path}' does not exist.";
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace ChilliCream.Nitro.CommandLine;
2+
3+
internal class OptionalLegacyFusionArchiveFileOption : Option<string>
4+
{
5+
public const string OptionName = "--legacy-v1-archive";
6+
7+
public OptionalLegacyFusionArchiveFileOption() : base(OptionName)
8+
{
9+
Description = "The path to a Fusion v1 archive file. "
10+
+ "This option is only intended to be used during the migration from Fusion v1 to Fusion v2+.";
11+
Required = false;
12+
this.LegalFilePathsOnly();
13+
}
14+
}

src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionCommandTestBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace ChilliCream.Nitro.CommandLine.Tests.Commands.Fusion;
1515
public abstract class FusionCommandTestBase(NitroCommandFixture fixture) : SchemasCommandTestBase(fixture)
1616
{
1717
protected const string ArchiveFile = "fusion.far";
18+
protected const string LegacyArchiveFile = "fusion-v1.fgp";
1819
protected const string SourceSchemaFile = "products/schema.graphqls";
1920
protected const string SourceSchemaSettingsFile = "products/schema-settings.json";
2021
protected const string SourceSchema = "products";

src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionComposeCommandTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ nitro fusion compose [options]
4141
Options:
4242
-f, --source-schema-file <source-schema-file> One or more paths to a source schema file (.graphqls) or directory containing a source schema file
4343
-a, --archive, --configuration <archive> The path to a Fusion archive file (the '--configuration' alias is deprecated) [env: NITRO_FUSION_CONFIG_FILE]
44+
--legacy-v1-archive <legacy-v1-archive> The path to a Fusion v1 archive file. This option is only intended to be used during the migration from Fusion v1 to Fusion v2+.
4445
-e, --env, --environment <environment> The name of the environment used for value substitution in the schema-settings.json files
4546
--enable-global-object-identification Add the 'Query.node' field for global object identification
4647
--include-satisfiability-paths Include paths in satisfiability error messages
@@ -315,6 +316,31 @@ public async Task Compose_ValidExample1_FromSpecified_ToFileInNewDirectory()
315316
Assert.True(File.Exists(archiveFileName));
316317
}
317318

319+
[Fact]
320+
public async Task Compose_WithLegacyArchive_FileDoesNotExist_ReturnsError()
321+
{
322+
// arrange
323+
var archiveFileName = CreateTempFile();
324+
325+
// act
326+
var result = await ExecuteCommandAsync(
327+
"fusion",
328+
"compose",
329+
"--source-schema-file",
330+
Path.Combine(s_resourcesDir, "valid-example-1/source-schema-1.graphqls"),
331+
"--archive",
332+
archiveFileName,
333+
"--legacy-v1-archive",
334+
LegacyArchiveFile);
335+
336+
// assert
337+
result.StdErr.MatchInlineSnapshot(
338+
"""
339+
Legacy archive file '/some/working/directory/fusion-v1.fgp' does not exist.
340+
""");
341+
Assert.Equal(1, result.ExitCode);
342+
}
343+
318344
[Fact]
319345
public async Task Compose_FromNonExistentFiles()
320346
{

src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionPublishCommandTests.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ nitro fusion publish [command] [options]
2727
-s, --source-schema <source-schema> One or more source schemas that should be included in the composition. Source schemas can either be just a name ('example') or a name and a version ('example@1.0.0'). If no version is specified the value of the '--tag' option is taken as the source schema version.
2828
-f, --source-schema-file <source-schema-file> One or more paths to a source schema file (.graphqls) or directory containing a source schema file
2929
-a, --archive, --configuration <archive> The path to a Fusion archive file (the '--configuration' alias is deprecated) [env: NITRO_FUSION_CONFIG_FILE]
30+
--legacy-v1-archive <legacy-v1-archive> The path to a Fusion v1 archive file. This option is only intended to be used during the migration from Fusion v1 to Fusion v2+.
3031
--force Skip confirmation prompts for deletes and overwrites
3132
--wait-for-approval Wait for the deployment to be approved before completing [env: NITRO_WAIT_FOR_APPROVAL]
3233
-w, --working-directory <working-directory> Set the working directory for the command
@@ -172,6 +173,70 @@ public async Task Archive_And_SourceSchemaFile_And_SourceSchema_ReturnsError(Int
172173
Assert.Equal(1, result.ExitCode);
173174
}
174175

176+
[Theory]
177+
[InlineData(InteractionMode.Interactive)]
178+
[InlineData(InteractionMode.NonInteractive)]
179+
[InlineData(InteractionMode.JsonOutput)]
180+
public async Task Archive_And_LegacyArchive_ReturnsError(InteractionMode mode)
181+
{
182+
// arrange
183+
SetupInteractionMode(mode);
184+
185+
// act
186+
var result = await ExecuteCommandAsync(
187+
"fusion",
188+
"publish",
189+
"--api-id",
190+
ApiId,
191+
"--stage",
192+
Stage,
193+
"--tag",
194+
Tag,
195+
"--archive",
196+
ArchiveFile,
197+
"--legacy-v1-archive",
198+
LegacyArchiveFile);
199+
200+
// assert
201+
result.StdErr.MatchInlineSnapshot(
202+
"""
203+
The options '--archive' and '--legacy-v1-archive' are mutually exclusive.
204+
""");
205+
Assert.Equal(1, result.ExitCode);
206+
}
207+
208+
[Theory]
209+
[InlineData(InteractionMode.Interactive)]
210+
[InlineData(InteractionMode.NonInteractive)]
211+
[InlineData(InteractionMode.JsonOutput)]
212+
public async Task WithLegacyArchive_FileDoesNotExist_ReturnsError(InteractionMode mode)
213+
{
214+
// arrange
215+
SetupInteractionMode(mode);
216+
217+
// act
218+
var result = await ExecuteCommandAsync(
219+
"fusion",
220+
"publish",
221+
"--api-id",
222+
ApiId,
223+
"--stage",
224+
Stage,
225+
"--tag",
226+
Tag,
227+
"--source-schema",
228+
SourceSchema,
229+
"--legacy-v1-archive",
230+
LegacyArchiveFile);
231+
232+
// assert
233+
result.StdErr.MatchInlineSnapshot(
234+
"""
235+
Legacy archive file '/some/working/directory/fusion-v1.fgp' does not exist.
236+
""");
237+
Assert.Equal(1, result.ExitCode);
238+
}
239+
175240
[Theory]
176241
[InlineData(InteractionMode.Interactive)]
177242
[InlineData(InteractionMode.NonInteractive)]

src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Fusion/FusionValidateCommandTests.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ nitro fusion validate [options]
2424
--api-id <api-id> (REQUIRED) The ID of the API [env: NITRO_API_ID]
2525
--stage <stage> (REQUIRED) The name of the stage [env: NITRO_STAGE]
2626
-a, --archive, --configuration <archive> The path to a Fusion archive file (the '--configuration' alias is deprecated) [env: NITRO_FUSION_CONFIG_FILE]
27+
--legacy-v1-archive <legacy-v1-archive> The path to a Fusion v1 archive file. This option is only intended to be used during the migration from Fusion v1 to Fusion v2+.
2728
-f, --source-schema-file <source-schema-file> One or more paths to a source schema file (.graphqls) or directory containing a source schema file
2829
--cloud-url <cloud-url> The URL of the Nitro backend (only needed for self-hosted or dedicated deployments) [env: NITRO_CLOUD_URL] [default: api.chillicream.com]
2930
--api-key <api-key> The API key used for authentication [env: NITRO_API_KEY]
@@ -150,6 +151,66 @@ Missing one of the required options '--source-schema-file' or '--archive'.
150151
Assert.Equal(1, result.ExitCode);
151152
}
152153

154+
[Theory]
155+
[InlineData(InteractionMode.Interactive)]
156+
[InlineData(InteractionMode.NonInteractive)]
157+
[InlineData(InteractionMode.JsonOutput)]
158+
public async Task Archive_And_LegacyArchive_ReturnsError(InteractionMode mode)
159+
{
160+
// arrange
161+
SetupInteractionMode(mode);
162+
163+
// act
164+
var result = await ExecuteCommandAsync(
165+
"fusion",
166+
"validate",
167+
"--api-id",
168+
ApiId,
169+
"--stage",
170+
Stage,
171+
"--archive",
172+
ArchiveFile,
173+
"--legacy-v1-archive",
174+
LegacyArchiveFile);
175+
176+
// assert
177+
result.StdErr.MatchInlineSnapshot(
178+
"""
179+
The options '--archive' and '--legacy-v1-archive' are mutually exclusive.
180+
""");
181+
Assert.Equal(1, result.ExitCode);
182+
}
183+
184+
[Theory]
185+
[InlineData(InteractionMode.Interactive)]
186+
[InlineData(InteractionMode.NonInteractive)]
187+
[InlineData(InteractionMode.JsonOutput)]
188+
public async Task WithLegacyArchive_FileDoesNotExist_ReturnsError(InteractionMode mode)
189+
{
190+
// arrange
191+
SetupInteractionMode(mode);
192+
193+
// act
194+
var result = await ExecuteCommandAsync(
195+
"fusion",
196+
"validate",
197+
"--api-id",
198+
ApiId,
199+
"--stage",
200+
Stage,
201+
"--source-schema-file",
202+
SourceSchemaFile,
203+
"--legacy-v1-archive",
204+
LegacyArchiveFile);
205+
206+
// assert
207+
result.StdErr.MatchInlineSnapshot(
208+
"""
209+
Legacy archive file '/some/working/directory/fusion-v1.fgp' does not exist.
210+
""");
211+
Assert.Equal(1, result.ExitCode);
212+
}
213+
153214
#endregion
154215

155216
#region Archive

0 commit comments

Comments
 (0)