feat(shorebird_cli): remove direct exit calls (#2230)

This commit is contained in:
Erick
2024-06-13 11:13:16 -03:00
committed by GitHub
parent 8b21c261cb
commit ab0262bebd
39 changed files with 137 additions and 222 deletions
@@ -1,8 +1,8 @@
import 'dart:io';
import 'dart:isolate';
import 'package:archive/archive_io.dart';
import 'package:path/path.dart' as p;
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
/// A wrapper around a directory that can be zipped.
extension DirectoryArchive on Directory {
@@ -2,6 +2,7 @@
// cspell:words endtemplate pubspec sideloadable bryanoltman archs sideload
// cspell:words xcarchive codesigned xcframework
import 'dart:io';
import 'dart:isolate';
import 'package:archive/archive_io.dart';
@@ -117,7 +118,7 @@ Could not find app with id: "$appId".
This app may not exist or you may not have permission to view it.''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return app;
@@ -182,7 +183,7 @@ Please bump your version number and try again.
You can manage this release in the ${link(uri: uri, message: 'Shorebird Console')}''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -204,7 +205,7 @@ Patches can only be published for existing releases.
Please create a release using "shorebird release" and try again.
''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return release;
@@ -779,6 +780,6 @@ aar artifact already exists, continuing...''',
progress.fail(message ?? '$error');
}
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:crypto/crypto.dart';
import 'package:io/io.dart';
@@ -55,12 +57,12 @@ class AarPatcher extends Patcher {
checkShorebirdInitialized: true,
);
} on PreconditionFailedException catch (e) {
exit(e.exitCode.code);
throw ProcessExit(e.exitCode.code);
}
if (shorebirdEnv.androidPackageName == null) {
logger.err('Could not find androidPackage in pubspec.yaml.');
exit(ExitCode.config.code);
throw ProcessExit(ExitCode.config.code);
}
}
@@ -78,7 +80,7 @@ class AarPatcher extends Patcher {
buildProgress.complete();
} on ArtifactBuildException catch (error) {
buildProgress.fail('Failed to build: ${error.message}');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return File(
@@ -115,7 +117,7 @@ class AarPatcher extends Patcher {
releaseArtifactPaths[releaseArtifact.key] = releaseArtifactFile.path;
} catch (error) {
downloadReleaseArtifactProgress.fail('$error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -153,7 +155,7 @@ class AarPatcher extends Patcher {
);
} catch (error) {
createDiffProgress.fail('$error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
createDiffProgress.complete();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:io/io.dart';
import 'package:path/path.dart' as p;
@@ -52,7 +54,7 @@ class AndroidPatcher extends Patcher {
validators: doctor.androidCommandValidators,
);
} on PreconditionFailedException catch (e) {
exit(e.exitCode.code);
throw ProcessExit(e.exitCode.code);
}
}
@@ -73,7 +75,7 @@ class AndroidPatcher extends Patcher {
buildProgress.complete();
} on ArtifactBuildException catch (error) {
buildProgress.fail(error.message);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final patchArchsBuildDir = ArtifactManager.androidArchsDirectory(
@@ -95,7 +97,7 @@ Looked in:
- build/app/intermediates/stripped_native_libs/release/out/lib
- build/app/intermediates/stripped_native_libs/{flavor}Release/out/lib''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return aabFile;
}
@@ -125,7 +127,7 @@ Looked in:
releaseArtifactPaths[releaseArtifact.key] = releaseArtifactFile.path;
} catch (error) {
downloadReleaseArtifactProgress.fail('$error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -137,7 +139,7 @@ Looked in:
);
if (patchArchsBuildDir == null) {
logger.err('Could not find patch artifacts');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final patchArtifactBundles = <Arch, PatchArtifactBundle>{};
@@ -177,7 +179,7 @@ Looked in:
);
} catch (error) {
createDiffProgress.fail('$error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
createDiffProgress.complete();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:meta/meta.dart';
@@ -68,7 +70,7 @@ class IosFrameworkPatcher extends Patcher {
supportedOperatingSystems: {Platform.macOS},
);
} on PreconditionFailedException catch (e) {
exit(e.exitCode.code);
throw ProcessExit(e.exitCode.code);
}
}
@@ -76,7 +78,7 @@ class IosFrameworkPatcher extends Patcher {
Future<void> assertArgsAreValid() async {
if (!argResults.wasParsed('release-version')) {
logger.err('Missing required argument: --release-version');
exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
}
@@ -94,7 +96,7 @@ class IosFrameworkPatcher extends Patcher {
);
} on ArtifactBuildException catch (error) {
buildProgress.fail(error.message);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
try {
await artifactBuilder.buildElfAotSnapshot(
@@ -107,7 +109,7 @@ class IosFrameworkPatcher extends Patcher {
);
} catch (error) {
buildProgress.fail('$error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
buildProgress.complete();
@@ -184,7 +186,7 @@ class IosFrameworkPatcher extends Patcher {
patchBaseProgress.complete();
} catch (error) {
patchBaseProgress.fail('$error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
patchFile = File(
@@ -239,7 +241,7 @@ class IosFrameworkPatcher extends Patcher {
}) async {
if (!aotSnapshot.existsSync()) {
logger.err('Unable to find patch AOT file at ${aotSnapshot.path}');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final analyzeSnapshot = File(
@@ -250,7 +252,7 @@ class IosFrameworkPatcher extends Patcher {
if (!analyzeSnapshot.existsSync()) {
logger.err('Unable to find analyze_snapshot at ${analyzeSnapshot.path}');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final genSnapshot = shorebirdArtifacts.getArtifactPath(
@@ -270,7 +272,7 @@ class IosFrameworkPatcher extends Patcher {
);
} catch (error) {
linkProgress.fail('Failed to link AOT files: $error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
linkProgress.complete();
@@ -1,6 +1,7 @@
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:mason_logger/mason_logger.dart';
@@ -76,7 +77,7 @@ class IosPatcher extends Patcher {
supportedOperatingSystems: {Platform.macOS},
);
} on PreconditionFailedException catch (error) {
exit(error.exitCode.code);
throw ProcessExit(error.exitCode.code);
}
}
@@ -87,7 +88,7 @@ class IosPatcher extends Patcher {
exportOptionsPlist = ios.exportOptionsPlistFromArgs(argResults);
} catch (error) {
logger.err('$error');
return exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
try {
@@ -104,7 +105,7 @@ class IosPatcher extends Patcher {
iOS patches are not supported with Flutter versions older than $minimumSupportedIosFlutterVersion.
For more information see: $supportedVersionsLink''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final buildProgress = logger.progress(
@@ -147,7 +148,7 @@ For more information see: $supportedVersionsLink''',
buildProgress.complete();
} catch (_) {
return exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return artifactManager.getXcarchiveDirectory()!.zipToTempFile();
@@ -162,7 +163,7 @@ For more information see: $supportedVersionsLink''',
// Verify that we have built a patch .xcarchive
if (artifactManager.getXcarchiveDirectory()?.path == null) {
logger.err('Unable to find .xcarchive directory');
return exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final unzipProgress = logger.progress('Extracting release artifact');
@@ -179,7 +180,7 @@ For more information see: $supportedVersionsLink''',
);
if (appDirectory == null) {
logger.err('Unable to find release artifact .app directory');
return exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final releaseArtifactFile = File(
p.join(
@@ -196,7 +197,7 @@ For more information see: $supportedVersionsLink''',
releaseArtifact: releaseArtifactFile,
kernelFile: File(_appDillCopyPath),
);
if (exitCode != ExitCode.success.code) return exit(exitCode);
if (exitCode != ExitCode.success.code) throw ProcessExit(exitCode);
if (linkPercentage != null &&
linkPercentage < Patcher.minLinkPercentage) {
logger.warn(Patcher.lowLinkPercentageWarning(linkPercentage));
@@ -224,7 +225,7 @@ For more information see: $supportedVersionsLink''',
patchBaseProgress.complete();
} catch (error) {
patchBaseProgress.fail('$error');
return exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
patchFile = File(
@@ -263,13 +264,13 @@ For more information see: $supportedVersionsLink''',
final archivePath = artifactManager.getXcarchiveDirectory()?.path;
if (archivePath == null) {
logger.err('Unable to find .xcarchive directory');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final plistFile = File(p.join(archivePath, 'Info.plist'));
if (!plistFile.existsSync()) {
logger.err('No Info.plist file found at ${plistFile.path}.');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final plist = Plist(file: plistFile);
@@ -279,7 +280,7 @@ For more information see: $supportedVersionsLink''',
logger.err(
'Failed to determine release version from ${plistFile.path}: $error',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -1,5 +1,7 @@
// ignore_for_file: public_member_api_docs
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:meta/meta.dart';
@@ -239,7 +241,7 @@ NOTE: this is ${styleBold.wrap('not')} recommended. Asset changes cannot be incl
try {
await shorebirdFlutter.installRevision(revision: release.flutterRevision);
} catch (_) {
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final releaseArtifact = await downloadPrimaryReleaseArtifact(
@@ -276,7 +278,7 @@ NOTE: this is ${styleBold.wrap('not')} recommended. Asset changes cannot be incl
logger
..info('No issues detected.')
..info('The server may enforce additional checks.');
exit(ExitCode.success.code);
throw ProcessExit(ExitCode.success.code);
}
await confirmCreatePatch(
@@ -322,7 +324,7 @@ NOTE: this is ${styleBold.wrap('not')} recommended. Asset changes cannot be incl
logger.err('''
Release ${release.version} is in an incomplete state. It's possible that the original release was terminated or failed to complete.
Please re-run the release command for this version or create a new release.''');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -340,10 +342,10 @@ Please re-run the release command for this version or create a new release.''');
allowNativeChanges: allowNativeDiffs,
);
} on UserCancelledException {
exit(ExitCode.success.code);
throw ProcessExit(ExitCode.success.code);
} on UnpatchableChangeException {
logger.info('Exiting.');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -387,7 +389,7 @@ ${summary.join('\n')}
if (!confirm) {
logger.info('Aborting.');
exit(ExitCode.success.code);
throw ProcessExit(ExitCode.success.code);
}
}
}
@@ -411,7 +413,7 @@ ${summary.join('\n')}
await artifactManager.downloadFile(Uri.parse(artifact.url));
} catch (e) {
downloadProgress.fail(e.toString());
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
downloadProgress.complete();
@@ -3,6 +3,7 @@
// cspell:words bundletool
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:archive/archive_io.dart';
@@ -20,7 +21,6 @@ import 'package:shorebird_cli/src/platform.dart';
import 'package:shorebird_cli/src/shorebird_command.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
import 'package:yaml/yaml.dart';
import 'package:yaml_edit/yaml_edit.dart';
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:io/io.dart';
import 'package:mason_logger/mason_logger.dart';
@@ -55,12 +57,12 @@ class AarReleaser extends Releaser {
checkShorebirdInitialized: true,
);
} on PreconditionFailedException catch (e) {
exit(e.exitCode.code);
throw ProcessExit(e.exitCode.code);
}
if (shorebirdEnv.androidPackageName == null) {
logger.err('Could not find androidPackage in pubspec.yaml.');
exit(ExitCode.config.code);
throw ProcessExit(ExitCode.config.code);
}
}
@@ -68,7 +70,7 @@ class AarReleaser extends Releaser {
Future<void> assertArgsAreValid() async {
if (!argResults.wasParsed('release-version')) {
logger.err('Missing required argument: --release-version');
exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
}
@@ -86,7 +88,7 @@ class AarReleaser extends Releaser {
);
} catch (e) {
logger.err('Failed to build aar: $e');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
buildAppBundleProgress.complete(
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:mason_logger/mason_logger.dart';
import 'package:shorebird_cli/src/artifact_builder.dart';
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
@@ -54,7 +56,7 @@ class AndroidReleaser extends Releaser {
validators: doctor.androidCommandValidators,
);
} on PreconditionFailedException catch (e) {
exit(e.exitCode.code);
throw ProcessExit(e.exitCode.code);
}
}
@@ -73,7 +75,7 @@ Split APKs are each given a different release version than what is specified in
See ${link(uri: Uri.parse('https://github.com/flutter/flutter/issues/39817'))} for more information about this issue.
Please comment and upvote ${link(uri: Uri.parse('https://github.com/shorebirdtech/shorebird/issues/1141'))} if you would like shorebird to support this.''',
);
exit(ExitCode.unavailable.code);
throw ProcessExit(ExitCode.unavailable.code);
}
}
@@ -105,7 +107,7 @@ Please comment and upvote ${link(uri: Uri.parse('https://github.com/shorebirdtec
);
} on ArtifactBuildException catch (e) {
buildAppBundleProgress.fail(e.message);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
buildAppBundleProgress.complete();
@@ -123,7 +125,7 @@ Please comment and upvote ${link(uri: Uri.parse('https://github.com/shorebirdtec
);
} on ArtifactBuildException catch (e) {
buildApkProgress.fail(e.message);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
buildApkProgress.complete();
}
@@ -147,7 +149,7 @@ Please comment and upvote ${link(uri: Uri.parse('https://github.com/shorebirdtec
releaseVersionProgress.complete('Release version: $releaseVersion');
} catch (error) {
releaseVersionProgress.fail('$error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return releaseVersion;
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:io/io.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:path/path.dart' as p;
@@ -45,7 +47,7 @@ class IosFrameworkReleaser extends Releaser {
Future<void> assertArgsAreValid() async {
if (!argResults.wasParsed('release-version')) {
logger.err('Missing required argument: --release-version');
exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
}
@@ -59,7 +61,7 @@ class IosFrameworkReleaser extends Releaser {
validators: doctor.iosCommandValidators,
);
} on PreconditionFailedException catch (e) {
exit(e.exitCode.code);
throw ProcessExit(e.exitCode.code);
}
}
@@ -75,7 +77,7 @@ class IosFrameworkReleaser extends Releaser {
await artifactBuilder.buildIosFramework(args: argResults.forwardedArgs);
} catch (error) {
buildProgress.fail('Failed to build iOS framework: $error');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
buildProgress.complete();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:mason_logger/mason_logger.dart';
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
@@ -48,7 +50,7 @@ class IosReleaser extends Releaser {
..info(
'''We hope to support obfuscation in the future. We are tracking this work at ${link(uri: Uri.parse('https://github.com/shorebirdtech/shorebird/issues/1619'))}.''',
);
exit(ExitCode.unavailable.code);
throw ProcessExit(ExitCode.unavailable.code);
}
}
@@ -62,7 +64,7 @@ class IosReleaser extends Releaser {
supportedOperatingSystems: {Platform.macOS},
);
} on PreconditionFailedException catch (e) {
exit(e.exitCode.code);
throw ProcessExit(e.exitCode.code);
}
final flutterVersionArg = argResults['flutter-version'] as String?;
@@ -74,7 +76,7 @@ class IosReleaser extends Releaser {
iOS releases are not supported with Flutter versions older than $minimumSupportedIosFlutterVersion.
For more information see: $supportedVersionsLink''',
);
exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
}
}
@@ -96,7 +98,7 @@ For more information see: $supportedVersionsLink''',
exportOptionsPlist = ios.exportOptionsPlistFromArgs(argResults);
} catch (error) {
logger.err('$error');
exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
final flutterVersionString = await shorebirdFlutter.getVersionAndRevision();
@@ -115,13 +117,13 @@ For more information see: $supportedVersionsLink''',
buildProgress.complete();
} on ArtifactBuildException catch (error) {
buildProgress.fail(error.message);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final xcarchiveDirectory = artifactManager.getXcarchiveDirectory();
if (xcarchiveDirectory == null) {
logger.err('Unable to find .xcarchive directory');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final appDirectory = artifactManager.getIosAppDirectory(
@@ -130,7 +132,7 @@ For more information see: $supportedVersionsLink''',
if (appDirectory == null) {
logger.err('Unable to find .app directory');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return xcarchiveDirectory;
@@ -143,7 +145,7 @@ For more information see: $supportedVersionsLink''',
final plistFile = File(p.join(releaseArtifactRoot.path, 'Info.plist'));
if (!plistFile.existsSync()) {
logger.err('No Info.plist file found at ${plistFile.path}');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
try {
@@ -152,7 +154,7 @@ For more information see: $supportedVersionsLink''',
logger.err(
'''Failed to determine release version from ${plistFile.path}: $error''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
@@ -182,7 +184,7 @@ For more information see: $supportedVersionsLink''',
final ipa = artifactManager.getIpa();
if (ipa == null) {
logger.err('Could not find ipa file');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final relativeIpaPath = p.relative(ipa.path);
@@ -216,7 +216,7 @@ of the iOS app that is using this module.''',
try {
await shorebirdFlutter.installRevision(revision: targetFlutterRevision);
} catch (_) {
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
final releaseFlutterShorebirdEnv = shorebirdEnv.copyWith(
@@ -243,7 +243,7 @@ of the iOS app that is using this module.''',
logger
..info('No issues detected.')
..info('The server may enforce additional checks.');
exit(ExitCode.success.code);
throw ProcessExit(ExitCode.success.code);
}
// Ask the user to proceed (this is skipped when running via CI).
@@ -299,7 +299,7 @@ of the iOS app that is using this module.''',
Unable to determine revision for Flutter version: $flutterVersionArg.
$error''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
if (revision == null) {
@@ -315,7 +315,7 @@ Version $flutterVersionArg not found. Please $openIssueLink to request a new ver
Use `shorebird flutter versions list` to list available versions.
''',
);
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
return revision;
@@ -363,7 +363,7 @@ To resolve this issue, you can:
* Re-run the release command with "${lightCyan.wrap('--flutter-version=${existingRelease.flutterRevision}')}".
* Delete the existing release and re-run the release command with the desired Flutter version.
* Bump the release version and re-run the release command with the desired Flutter version.''');
exit(ExitCode.software.code);
throw ProcessExit(ExitCode.software.code);
}
}
}
@@ -402,7 +402,7 @@ ${summary.join('\n')}
if (!confirm) {
logger.info('Aborting.');
exit(ExitCode.success.code);
throw ProcessExit(ExitCode.success.code);
}
}
}
@@ -1,6 +1,7 @@
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:io/io.dart';
@@ -12,7 +13,6 @@ import 'package:shorebird_cli/src/executables/devicectl/nserror.dart';
import 'package:shorebird_cli/src/executables/idevicesyslog.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
typedef BundleId = String;
@@ -1,4 +1,6 @@
// ignore_for_file: public_member_api_docs
import 'dart:io';
import 'package:args/args.dart';
import 'package:collection/collection.dart';
import 'package:mason_logger/mason_logger.dart';
@@ -7,7 +9,7 @@ import 'package:shorebird_cli/src/common_arguments.dart';
import 'package:shorebird_cli/src/extensions/file.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/release_type.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/src/base/io.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
extension OptionFinder on ArgResults {
/// Detects flags even when passed to underlying commands via a `--`
@@ -72,7 +74,7 @@ extension CodeSign on ArgResults {
assertAbsentOrValidPrivateKey();
} else {
logger.err('Both public and private keys must be provided.');
exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
}
@@ -1,6 +1,8 @@
import 'dart:io';
import 'package:mason_logger/mason_logger.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/src/base/io.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
/// Extension methods for validating [File]s.
extension FileValidations on File {
@@ -10,7 +12,7 @@ extension FileValidations on File {
logger.err(
'No file found at $path',
);
exit(ExitCode.usage.code);
throw ProcessExit(ExitCode.usage.code);
}
}
}
@@ -1,2 +1 @@
export 'src/base/io.dart';
export 'src/base/process.dart';
@@ -1,90 +0,0 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// This file serves as the single point of entry into the `dart:io` APIs
/// within Flutter tools.
///
/// In order to make Flutter tools more testable, we use the `FileSystem` APIs
/// in `package:file` rather than using the `dart:io` file APIs directly (see
/// `file_system.dart`). Doing so allows us to swap out local file system
/// access with mockable (or in-memory) file systems, making our tests hermetic
/// vis-a-vis file system access.
///
/// We also use `package:platform` to provide an abstraction away from the
/// static methods in the `dart:io` `Platform` class (see `platform.dart`). As
/// such, do not export Platform from this file!
///
/// To ensure that all file system and platform API access within Flutter tools
/// goes through the proper APIs, we forbid direct imports of `dart:io` (via a
/// test), forcing all callers to instead import this file, which exports the
/// blessed subset of `dart:io` that is legal to use in Flutter tools.
///
/// Because of the nature of this file, it is important that **platform and file
/// APIs not be exported from `dart:io` in this file**! Moreover, be careful
/// about any additional exports that you add to this file, as doing so will
/// increase the API surface that we have to test in Flutter tools, and the APIs
/// in `dart:io` can sometimes be hard to use in tests.
library;
// We allow `print()` in this file as a fallback for writing to the terminal via
// regular stdout/stderr/stdio paths. Everything else in the flutter_tools
// library should route terminal I/O through the [Stdio] class defined below.
// ignore_for_file: avoid_print
import 'dart:async';
import 'dart:io' as io show exit;
import 'package:meta/meta.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/src/base/process.dart';
export 'dart:io' hide exit;
/// Exits the process with the given [exitCode].
typedef ExitFunction = Never Function(int exitCode);
const ExitFunction _defaultExitFunction = io.exit;
ExitFunction _exitFunction = _defaultExitFunction;
/// Exits the process.
///
/// Throws [AssertionError] if assertions are enabled and the dart:io exit
/// is still active when called. This may indicate exit was called in
/// a test without being configured correctly.
///
/// This is analogous to the `exit` function in `dart:io`, except that this
/// function may be set to a testing-friendly value by calling
/// [setExitFunctionForTests] (and then restored to its default implementation
/// with [restoreExitFunction]). The default implementation delegates to
/// `dart:io`.
ExitFunction get exit {
assert(
_exitFunction != io.exit || !_inUnitTest(),
'io.exit was called with assertions active in a unit test',
);
return _exitFunction;
}
// coverage:ignore-start
// Whether the tool is executing in a unit test.
bool _inUnitTest() {
return Zone.current[#test.declarer] != null;
}
// coverage:ignore-end
/// Sets the [exit] function to a function that throws an exception rather
/// than exiting the process; this is intended for testing purposes.
@visibleForTesting
void setExitFunctionForTests([ExitFunction? exitFunction]) {
_exitFunction = exitFunction ??
(int exitCode) {
throw ProcessExit(exitCode, immediate: true);
};
}
/// Restores the [exit] function to the `dart:io` implementation.
@visibleForTesting
void restoreExitFunction() {
_exitFunction = _defaultExitFunction;
}
@@ -1,8 +1,9 @@
import 'dart:io';
import 'package:pub_semver/pub_semver.dart';
import 'package:shorebird_cli/src/platform.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
/// An exception thrown when a validation issue is found.
@@ -1,6 +1,7 @@
// cspell:words googleapis
import 'dart:io';
import 'package:shorebird_cli/src/http_client/http_client.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
/// Verifies that the user has access to storage.googleapis.com.
+2 -2
View File
@@ -457,10 +457,10 @@ packages:
dependency: "direct dev"
description:
name: mocktail
sha256: c4b5007d91ca4f67256e720cb1b6d704e79a510183a12fa551021f652577dce6
sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
version: "1.0.4"
node_preamble:
dependency: transitive
description:
@@ -1,7 +1,8 @@
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:path/path.dart' as p;
import 'package:shorebird_cli/src/archive/directory_archive.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:test/test.dart';
void main() {
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:mason_logger/mason_logger.dart';
@@ -14,7 +15,6 @@ import 'package:shorebird_cli/src/platform.dart';
import 'package:shorebird_cli/src/platform/platform.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_web_console.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
import 'package:test/test.dart';
@@ -161,11 +161,8 @@ void main() {
setUpAll(() {
registerFallbackValue(ReleasePlatform.android);
registerFallbackValue(ReleaseStatus.draft);
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
codePushClient = MockCodePushClient();
logger = MockShorebirdLogger();
@@ -1,8 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:shorebird_cli/src/code_signer.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:test/test.dart';
void main() {
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -10,7 +12,6 @@ import 'package:shorebird_cli/src/executables/executables.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:test/test.dart';
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -19,7 +21,6 @@ import 'package:shorebird_cli/src/shorebird_android_artifacts.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
import 'package:test/test.dart';
@@ -83,11 +84,8 @@ void main() {
registerFallbackValue(Directory(''));
registerFallbackValue(ReleasePlatform.android);
registerFallbackValue(Uri.parse('https://example.com'));
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
argResults = MockArgResults();
artifactBuilder = MockArtifactBuilder();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:crypto/crypto.dart';
import 'package:mason_logger/mason_logger.dart';
@@ -23,7 +25,6 @@ import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
@@ -109,11 +110,8 @@ void main() {
registerFallbackValue(File(''));
registerFallbackValue(ReleasePlatform.android);
registerFallbackValue(Uri.parse('https://example.com'));
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
argResults = MockArgResults();
artifactBuilder = MockArtifactBuilder();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -25,7 +27,6 @@ import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
@@ -88,11 +89,8 @@ void main() {
registerFallbackValue(File(''));
registerFallbackValue(ReleasePlatform.ios);
registerFallbackValue(Uri.parse('https://example.com'));
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
aotTools = MockAotTools();
argResults = MockArgResults();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -27,7 +29,6 @@ import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
@@ -97,11 +98,8 @@ void main() {
registerFallbackValue(File(''));
registerFallbackValue(ReleasePlatform.ios);
registerFallbackValue(Uri.parse('https://example.com'));
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
aotTools = MockAotTools();
argResults = MockArgResults();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:collection/collection.dart';
import 'package:mason_logger/mason_logger.dart';
@@ -20,7 +22,6 @@ import 'package:shorebird_cli/src/platform/platform.dart';
import 'package:shorebird_cli/src/release_type.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart';
import 'package:test/test.dart';
@@ -127,11 +128,8 @@ void main() {
registerFallbackValue(release);
registerFallbackValue(ReleasePlatform.android);
registerFallbackValue(Uri.parse('https://example.com'));
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
aotTools = MockAotTools();
archiveDiffer = MockAndroidArchiveDiffer();
@@ -1,10 +1,11 @@
import 'dart:io';
import 'package:shorebird_cli/src/archive_analysis/archive_differ.dart';
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
import 'package:shorebird_cli/src/commands/commands.dart';
import 'package:shorebird_cli/src/patch_diff_checker.dart';
import 'package:shorebird_cli/src/platform/platform.dart';
import 'package:shorebird_cli/src/release_type.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_code_push_protocol/src/models/create_patch_metadata.dart';
import 'package:test/test.dart';
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -18,7 +20,6 @@ import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
import 'package:test/test.dart';
@@ -69,11 +70,8 @@ void main() {
setUpAll(() {
registerFallbackValue(Directory(''));
registerFallbackValue(ReleasePlatform.android);
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
argResults = MockArgResults();
artifactBuilder = MockArtifactBuilder();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -21,7 +23,6 @@ import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
@@ -76,11 +77,8 @@ void main() {
registerFallbackValue(Directory(''));
registerFallbackValue(File(''));
registerFallbackValue(ReleasePlatform.android);
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
argResults = MockArgResults();
artifactBuilder = MockArtifactBuilder();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -18,7 +20,6 @@ import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
@@ -72,11 +73,8 @@ void main() {
setUpAll(() {
registerFallbackValue(Directory(''));
registerFallbackValue(ReleasePlatform.ios);
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
argResults = MockArgResults();
artifactBuilder = MockArtifactBuilder();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -21,7 +23,6 @@ import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/shorebird_validator.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
@@ -80,11 +81,8 @@ void main() {
registerFallbackValue(Directory(''));
registerFallbackValue(File(''));
registerFallbackValue(ReleasePlatform.android);
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
argResults = MockArgResults();
artifactBuilder = MockArtifactBuilder();
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -12,7 +14,6 @@ import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/release_type.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
import 'package:test/test.dart';
@@ -75,11 +76,8 @@ void main() {
registerFallbackValue(release);
registerFallbackValue(ReleasePlatform.android);
registerFallbackValue(ReleaseStatus.draft);
setExitFunctionForTests();
});
tearDownAll(restoreExitFunction);
setUp(() {
argResults = MockArgResults();
cache = MockCache();
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:io';
import 'package:mocktail/mocktail.dart';
import 'package:path/path.dart' as p;
@@ -8,7 +9,6 @@ import 'package:shorebird_cli/src/executables/idevicesyslog.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:test/test.dart';
import '../mocks.dart';
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:mocktail/mocktail.dart';
import 'package:path/path.dart' as p;
@@ -7,7 +9,6 @@ import 'package:shorebird_cli/src/executables/bundletool.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_cli/src/shorebird_android_artifacts.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:test/test.dart';
import 'mocks.dart';
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
@@ -9,7 +11,6 @@ import 'package:shorebird_cli/src/shorebird_cli_command_runner.dart';
import 'package:shorebird_cli/src/shorebird_env.dart';
import 'package:shorebird_cli/src/shorebird_flutter.dart';
import 'package:shorebird_cli/src/shorebird_version.dart';
import 'package:shorebird_cli/src/third_party/flutter_tools/lib/flutter_tools.dart';
import 'package:shorebird_cli/src/version.dart';
import 'package:test/test.dart';