Skip to content

Commit

Permalink
feat(shorebird_cli): add --dry-run and --force to `shorebird patc…
Browse files Browse the repository at this point in the history
…h` (#207)
  • Loading branch information
felangel authored Mar 31, 2023
1 parent 405fe79 commit 24e038f
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 19 deletions.
50 changes: 40 additions & 10 deletions packages/shorebird_cli/lib/src/commands/patch_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ class PatchCommand extends ShorebirdCommand
'stable': 'The stable channel which is consumed by production apps.'
},
defaultsTo: 'stable',
)
..addFlag(
'force',
abbr: 'f',
help: 'Patch without confirmation if there are no errors.',
negatable: false,
)
..addFlag(
'dry-run',
abbr: 'n',
negatable: false,
help: 'Validate but do not upload the patch.',
);
}

Expand Down Expand Up @@ -94,6 +106,14 @@ class PatchCommand extends ShorebirdCommand
return ExitCode.software.code;
}

final force = results['force'] == true;
final dryRun = results['dry-run'] == true;

if (force && dryRun) {
logger.err('Cannot use both --force and --dry-run.');
return ExitCode.usage.code;
}

final buildProgress = logger.progress('Building patch');
try {
await buildRelease();
Expand Down Expand Up @@ -133,7 +153,7 @@ class PatchCommand extends ShorebirdCommand
final version = pubspecYaml.version!;
final versionString = '${version.major}.${version.minor}.${version.patch}';

late final List<App> apps;
final List<App> apps;
final fetchAppsProgress = logger.progress('Fetching apps');
try {
apps = (await codePushClient.getApps())
Expand All @@ -160,6 +180,13 @@ Did you forget to run "shorebird init"?''',
final pubspecVersionString =
'''${pubspecVersion.major}.${pubspecVersion.minor}.${pubspecVersion.patch}''';

if (dryRun) {
logger
..info('No issues detected.')
..info('The server may enforce additional checks.');
return ExitCode.success.code;
}

if (releaseVersionArg == null) logger.info('');

final releaseVersion = releaseVersionArg ??
Expand All @@ -185,14 +212,17 @@ ${styleBold.wrap(lightGreen.wrap('🚀 Ready to publish a new patch!'))}
''',
);

final confirm = logger.confirm('Would you like to continue?');
final needsConfirmation = !force;
if (needsConfirmation) {
final confirm = logger.confirm('Would you like to continue?');

if (!confirm) {
logger.info('Aborting.');
return ExitCode.success.code;
if (!confirm) {
logger.info('Aborting.');
return ExitCode.success.code;
}
}

late final List<Release> releases;
final List<Release> releases;
final fetchReleasesProgress = logger.progress('Fetching releases');
try {
releases = await codePushClient.getReleases(
Expand Down Expand Up @@ -220,7 +250,7 @@ Please create a release using "shorebird release" and try again.
return ExitCode.software.code;
}

late final ReleaseArtifact releaseArtifact;
final ReleaseArtifact releaseArtifact;
final fetchReleaseArtifactProgress = logger.progress(
'Fetching release artifact',
);
Expand All @@ -236,7 +266,7 @@ Please create a release using "shorebird release" and try again.
return ExitCode.software.code;
}

late final String releaseArtifactPath;
final String releaseArtifactPath;
final downloadReleaseArtifactProgress = logger.progress(
'Downloading release artifact',
);
Expand All @@ -250,7 +280,7 @@ Please create a release using "shorebird release" and try again.
return ExitCode.software.code;
}

late final String diffPath;
final String diffPath;
final createDiffProgress = logger.progress('Creating diff');
try {
diffPath = await _createDiff(
Expand All @@ -263,7 +293,7 @@ Please create a release using "shorebird release" and try again.
return ExitCode.software.code;
}

late final Patch patch;
final Patch patch;
final createPatchProgress = logger.progress('Creating patch');
try {
patch = await codePushClient.createPatch(releaseId: release.id);
Expand Down
88 changes: 79 additions & 9 deletions packages/shorebird_cli/test/src/commands/patch_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ flutter:
when(() => argResults['arch']).thenReturn(arch);
when(() => argResults['platform']).thenReturn(platform);
when(() => argResults['channel']).thenReturn(channelName);
when(() => argResults['dry-run']).thenReturn(false);
when(() => argResults['force']).thenReturn(false);
when(() => auth.currentSession).thenReturn(session);
when(() => logger.progress(any())).thenReturn(progress);
when(
Expand Down Expand Up @@ -253,6 +255,23 @@ flutter:
expect(exitCode, equals(ExitCode.software.code));
});

test(
'exits with usage code when '
'both --dry-run and --force are specified', () async {
when(() => argResults['dry-run']).thenReturn(true);
when(() => argResults['force']).thenReturn(true);
when(() => auth.currentSession).thenReturn(session);
final tempDir = setUpTempDir();
Directory(
p.join(command.shorebirdEnginePath, 'engine'),
).createSync(recursive: true);
final exitCode = await IOOverrides.runZoned(
command.run,
getCurrentDirectory: () => tempDir,
);
expect(exitCode, equals(ExitCode.usage.code));
});

test('throws software error when artifact is not found (default).',
() async {
final tempDir = setUpTempDir();
Expand Down Expand Up @@ -433,9 +452,6 @@ Please create a release using "shorebird release" and try again.

test('throws error when release artifact cannot be retrieved.', () async {
const error = 'something went wrong';
when(
() => codePushClient.getReleases(appId: any(named: 'appId')),
).thenAnswer((_) async => [release]);
when(
() => codePushClient.getReleaseArtifact(
releaseId: any(named: 'releaseId'),
Expand Down Expand Up @@ -469,9 +485,6 @@ Please create a release using "shorebird release" and try again.
});

test('throws error when release artifact does not exist.', () async {
when(
() => codePushClient.getReleases(appId: any(named: 'appId')),
).thenAnswer((_) async => [release]);
when(() => httpClient.send(any())).thenAnswer(
(_) async => http.StreamedResponse(
const Stream.empty(),
Expand Down Expand Up @@ -510,9 +523,6 @@ Please create a release using "shorebird release" and try again.

test('throws error when creating diff fails', () async {
const error = 'oops something went wrong';
when(
() => codePushClient.getReleases(appId: any(named: 'appId')),
).thenAnswer((_) async => [release]);
when(() => patchProcessResult.exitCode).thenReturn(1);
when(() => patchProcessResult.stderr).thenReturn(error);
final tempDir = setUpTempDir();
Expand Down Expand Up @@ -542,6 +552,66 @@ Please create a release using "shorebird release" and try again.
expect(exitCode, ExitCode.software.code);
});

test('does not create patch on --dry-run', () async {
when(() => argResults['dry-run']).thenReturn(true);
final tempDir = setUpTempDir();
Directory(
p.join(command.shorebirdEnginePath, 'engine'),
).createSync(recursive: true);
final artifactPath = p.join(
tempDir.path,
'build',
'app',
'intermediates',
'stripped_native_libs',
'release',
'out',
'lib',
'arm64-v8a',
'libapp.so',
);
File(artifactPath).createSync(recursive: true);
final exitCode = await IOOverrides.runZoned(
command.run,
getCurrentDirectory: () => tempDir,
);
expect(exitCode, equals(ExitCode.success.code));
verifyNever(
() => codePushClient.createPatch(releaseId: any(named: 'releaseId')),
);
verify(() => logger.info('No issues detected.')).called(1);
});

test('does not prompt on --force', () async {
when(() => argResults['force']).thenReturn(true);
final tempDir = setUpTempDir();
Directory(
p.join(command.shorebirdEnginePath, 'engine'),
).createSync(recursive: true);
final artifactPath = p.join(
tempDir.path,
'build',
'app',
'intermediates',
'stripped_native_libs',
'release',
'out',
'lib',
'arm64-v8a',
'libapp.so',
);
File(artifactPath).createSync(recursive: true);
final exitCode = await IOOverrides.runZoned(
command.run,
getCurrentDirectory: () => tempDir,
);
expect(exitCode, equals(ExitCode.success.code));
verifyNever(() => logger.confirm(any()));
verify(
() => codePushClient.createPatch(releaseId: any(named: 'releaseId')),
).called(1);
});

test('throws error when creating patch fails.', () async {
const error = 'something went wrong';
when(
Expand Down

0 comments on commit 24e038f

Please sign in to comment.