diff --git a/packages/scoped/lib/src/scoped.dart b/packages/scoped/lib/src/scoped.dart index 9784b049..cf60c70f 100644 --- a/packages/scoped/lib/src/scoped.dart +++ b/packages/scoped/lib/src/scoped.dart @@ -49,7 +49,7 @@ T read(ScopedRef ref, {T Function()? orElse}) { if (orElse != null) return orElse(); throw StateError( ''' -read(...) was called in a scope which does not contain a corresponding value for the provided ref. +read(ScopedRef<$T>) was called in a scope which does not contain a corresponding value for the provided ref. Did you forget to call: runScoped(() {...}, values: {value})?''', ); } diff --git a/packages/shorebird_cli/bin/shorebird.dart b/packages/shorebird_cli/bin/shorebird.dart index 8f3b879d..4ca9108b 100644 --- a/packages/shorebird_cli/bin/shorebird.dart +++ b/packages/shorebird_cli/bin/shorebird.dart @@ -1,6 +1,8 @@ import 'dart:io'; import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; +import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/command_runner.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/platform.dart'; @@ -9,7 +11,12 @@ Future main(List args) async { await _flushThenExit( await runScoped( () async => ShorebirdCliCommandRunner().run(args), - values: {loggerRef, platformRef}, + values: { + authRef, + loggerRef, + platformRef, + codePushClientWrapperRef, + }, ), ); } diff --git a/packages/shorebird_cli/lib/src/auth/auth.dart b/packages/shorebird_cli/lib/src/auth/auth.dart index 7b3166f7..68f4d507 100644 --- a/packages/shorebird_cli/lib/src/auth/auth.dart +++ b/packages/shorebird_cli/lib/src/auth/auth.dart @@ -5,12 +5,19 @@ import 'package:cli_util/cli_util.dart'; import 'package:googleapis_auth/auth_io.dart' as oauth2; import 'package:http/http.dart' as http; import 'package:path/path.dart' as p; +import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/auth/jwt.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/command_runner.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; +// A reference to a [Auth] instance. +final authRef = create(Auth.new); + +// The [Auth] instance available in the current zone. +Auth get auth => read(authRef); + final _clientId = oauth2.ClientId( /// Shorebird CLI's OAuth 2.0 identifier. '523302233293-eia5antm0tgvek240t46orctktiabrek.apps.googleusercontent.com', diff --git a/packages/shorebird_cli/lib/src/code_push_client_wrapper.dart b/packages/shorebird_cli/lib/src/code_push_client_wrapper.dart index d44f2f08..683ea902 100644 --- a/packages/shorebird_cli/lib/src/code_push_client_wrapper.dart +++ b/packages/shorebird_cli/lib/src/code_push_client_wrapper.dart @@ -3,8 +3,11 @@ import 'package:crypto/crypto.dart'; import 'package:mason_logger/mason_logger.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; +import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.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'; @@ -33,6 +36,20 @@ class PatchArtifactBundle { final int size; } +// A reference to a [CodePushClientWrapper] instance. +ScopedRef codePushClientWrapperRef = create(() { + return CodePushClientWrapper( + codePushClient: CodePushClient( + httpClient: auth.client, + hostedUri: ShorebirdEnvironment.hostedUri, + ), + ); +}); + +// The [CodePushClientWrapper] instance available in the current zone. +CodePushClientWrapper get codePushClientWrapper => + read(codePushClientWrapperRef); + /// {@template code_push_client_wrapper} /// Wraps [CodePushClient] interaction with logging and error handling to /// reduce the amount of command and command test code. diff --git a/packages/shorebird_cli/lib/src/command.dart b/packages/shorebird_cli/lib/src/command.dart index 4d2a067f..d41ef322 100644 --- a/packages/shorebird_cli/lib/src/command.dart +++ b/packages/shorebird_cli/lib/src/command.dart @@ -2,17 +2,10 @@ import 'dart:io'; import 'package:args/args.dart'; import 'package:args/command_runner.dart'; -import 'package:checked_yaml/checked_yaml.dart'; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; -import 'package:path/path.dart' as p; -import 'package:pubspec_parse/pubspec_parse.dart'; -import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/cache.dart'; -import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/command_runner.dart'; -import 'package:shorebird_cli/src/config/config.dart'; -import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; import 'package:shorebird_cli/src/validators/validators.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -40,28 +33,15 @@ List _defaultValidators() => [ abstract class ShorebirdCommand extends Command { ShorebirdCommand({ - Auth? auth, Cache? cache, CodePushClientBuilder? buildCodePushClient, - CodePushClientWrapper? codePushClientWrapper, List? validators, // For mocking. }) : cache = cache ?? Cache(), buildCodePushClient = buildCodePushClient ?? CodePushClient.new, - validators = validators ?? _defaultValidators() { - this.auth = auth ?? Auth(); - this.codePushClientWrapper = codePushClientWrapper ?? - CodePushClientWrapper( - codePushClient: CodePushClient( - httpClient: this.auth.client, - hostedUri: hostedUri, - ), - ); - } + validators = validators ?? _defaultValidators(); - late final Auth auth; final Cache cache; final CodePushClientBuilder buildCodePushClient; - late final CodePushClientWrapper codePushClientWrapper; // We don't currently have a test involving both a CommandRunner // and a Command, so we can't test this getter. @@ -98,32 +78,4 @@ abstract class ShorebirdCommand extends Command { /// [ArgResults] for the current command. ArgResults get results => testArgResults ?? argResults!; - - File getShorebirdYamlFile() { - return File(p.join(Directory.current.path, 'shorebird.yaml')); - } - - ShorebirdYaml? getShorebirdYaml() { - final file = getShorebirdYamlFile(); - if (!file.existsSync()) return null; - final yaml = file.readAsStringSync(); - return checkedYamlDecode(yaml, (m) => ShorebirdYaml.fromJson(m!)); - } - - Pubspec? getPubspecYaml() { - final file = File(p.join(Directory.current.path, 'pubspec.yaml')); - if (!file.existsSync()) return null; - final yaml = file.readAsStringSync(); - return Pubspec.parse(yaml); - } - - Uri? get hostedUri { - try { - final baseUrl = platform.environment['SHOREBIRD_HOSTED_URL'] ?? - getShorebirdYaml()?.baseUrl; - return baseUrl == null ? null : Uri.tryParse(baseUrl); - } catch (_) { - return null; - } - } } diff --git a/packages/shorebird_cli/lib/src/commands/account/account_command.dart b/packages/shorebird_cli/lib/src/commands/account/account_command.dart index aa2e3113..81110579 100644 --- a/packages/shorebird_cli/lib/src/commands/account/account_command.dart +++ b/packages/shorebird_cli/lib/src/commands/account/account_command.dart @@ -7,7 +7,7 @@ import 'package:shorebird_cli/src/commands/commands.dart'; /// {@endtemplate} class AccountCommand extends ShorebirdCommand { /// {@macro account_command} - AccountCommand({super.auth}) { + AccountCommand() { addSubcommand(CreateAccountCommand()); addSubcommand(SubscribeAccountCommand()); } diff --git a/packages/shorebird_cli/lib/src/commands/account/create_account_command.dart b/packages/shorebird_cli/lib/src/commands/account/create_account_command.dart index b4a23960..e5142a66 100644 --- a/packages/shorebird_cli/lib/src/commands/account/create_account_command.dart +++ b/packages/shorebird_cli/lib/src/commands/account/create_account_command.dart @@ -12,9 +12,6 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; /// Create a new Shorebird account. /// {@endtemplate} class CreateAccountCommand extends ShorebirdCommand with ShorebirdConfigMixin { - /// {@macro create_account_command} - CreateAccountCommand({super.auth}); - @override String get description => 'Create a new Shorebird account.'; diff --git a/packages/shorebird_cli/lib/src/commands/account/subscribe_account_command.dart b/packages/shorebird_cli/lib/src/commands/account/subscribe_account_command.dart index 741ed525..a57cf037 100644 --- a/packages/shorebird_cli/lib/src/commands/account/subscribe_account_command.dart +++ b/packages/shorebird_cli/lib/src/commands/account/subscribe_account_command.dart @@ -1,9 +1,11 @@ import 'dart:async'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -13,7 +15,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; class SubscribeAccountCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro subscribe_account_command} - SubscribeAccountCommand({super.auth, super.buildCodePushClient}); + SubscribeAccountCommand({super.buildCodePushClient}); @override String get name => 'subscribe'; @@ -41,7 +43,7 @@ Visit ${styleUnderlined.wrap(lightCyan.wrap('https://shorebird.dev'))} for more final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final progress = logger.progress('Retrieving account information'); diff --git a/packages/shorebird_cli/lib/src/commands/apps/create_apps_command.dart b/packages/shorebird_cli/lib/src/commands/apps/create_apps_command.dart index 5e9b5a02..8bdfa29a 100644 --- a/packages/shorebird_cli/lib/src/commands/apps/create_apps_command.dart +++ b/packages/shorebird_cli/lib/src/commands/apps/create_apps_command.dart @@ -19,7 +19,7 @@ class CreateAppCommand extends ShorebirdCommand ShorebirdValidationMixin, ShorebirdCreateAppMixin { /// {@macro create_app_command} - CreateAppCommand({super.buildCodePushClient, super.auth}) { + CreateAppCommand({super.buildCodePushClient}) { argParser.addOption( 'app-name', help: ''' diff --git a/packages/shorebird_cli/lib/src/commands/apps/delete_apps_command.dart b/packages/shorebird_cli/lib/src/commands/apps/delete_apps_command.dart index aa648cf4..a2d821f9 100644 --- a/packages/shorebird_cli/lib/src/commands/apps/delete_apps_command.dart +++ b/packages/shorebird_cli/lib/src/commands/apps/delete_apps_command.dart @@ -1,9 +1,11 @@ import 'dart:async'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; /// {@template delete_app_command} @@ -14,7 +16,7 @@ import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; class DeleteAppCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro delete_app_command} - DeleteAppCommand({super.buildCodePushClient, super.auth}) { + DeleteAppCommand({super.buildCodePushClient}) { argParser.addOption( 'app-id', help: ''' @@ -45,7 +47,7 @@ Defaults to the app_id in "shorebird.yaml".''', if (appIdArg == null) { String? defaultAppId; try { - defaultAppId = getShorebirdYaml()?.appId; + defaultAppId = ShorebirdEnvironment.getShorebirdYaml()?.appId; } catch (_) {} appId = logger.prompt( @@ -58,7 +60,7 @@ Defaults to the app_id in "shorebird.yaml".''', final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final confirm = logger.confirm('Deleting an app is permanent. Continue?'); diff --git a/packages/shorebird_cli/lib/src/commands/apps/list_apps_command.dart b/packages/shorebird_cli/lib/src/commands/apps/list_apps_command.dart index 4b28ba87..d582d959 100644 --- a/packages/shorebird_cli/lib/src/commands/apps/list_apps_command.dart +++ b/packages/shorebird_cli/lib/src/commands/apps/list_apps_command.dart @@ -2,9 +2,11 @@ import 'dart:async'; import 'package:barbecue/barbecue.dart'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -16,7 +18,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; class ListAppsCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro list_apps_command} - ListAppsCommand({super.buildCodePushClient, super.auth}); + ListAppsCommand({super.buildCodePushClient}); @override String get description => 'List all apps using Shorebird.'; @@ -39,7 +41,7 @@ class ListAppsCommand extends ShorebirdCommand final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final List apps; diff --git a/packages/shorebird_cli/lib/src/commands/build/build_aar_command.dart b/packages/shorebird_cli/lib/src/commands/build/build_aar_command.dart index 3266fee5..c0c7c7bb 100644 --- a/packages/shorebird_cli/lib/src/commands/build/build_aar_command.dart +++ b/packages/shorebird_cli/lib/src/commands/build/build_aar_command.dart @@ -16,7 +16,7 @@ import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; /// {@endtemplate} class BuildAarCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin, ShorebirdBuildMixin { - BuildAarCommand({super.auth, super.validators}) { + BuildAarCommand({super.validators}) { // We would have a "target" option here, similar to what [BuildApkCommand] // and [BuildAabCommand] have, but target cannot currently be configured in // `flutter build aar` and is always assumed to be lib/main.dart. diff --git a/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart b/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart index 065f25cd..51539a8c 100644 --- a/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart +++ b/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart @@ -16,7 +16,7 @@ import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; class BuildApkCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin, ShorebirdBuildMixin { /// {@macro build_apk_command} - BuildApkCommand({super.auth, super.validators}) { + BuildApkCommand({super.validators}) { argParser ..addOption( 'target', diff --git a/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart b/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart index ace06000..fbcbc66f 100644 --- a/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart +++ b/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart @@ -16,7 +16,7 @@ import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; class BuildAppBundleCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin, ShorebirdBuildMixin { /// {@macro build_app_bundle_command} - BuildAppBundleCommand({super.auth, super.validators}) { + BuildAppBundleCommand({super.validators}) { argParser ..addOption( 'target', diff --git a/packages/shorebird_cli/lib/src/commands/build/build_ipa_command.dart b/packages/shorebird_cli/lib/src/commands/build/build_ipa_command.dart index 1d79098e..ed0a4aaf 100644 --- a/packages/shorebird_cli/lib/src/commands/build/build_ipa_command.dart +++ b/packages/shorebird_cli/lib/src/commands/build/build_ipa_command.dart @@ -16,7 +16,7 @@ import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; class BuildIpaCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin, ShorebirdBuildMixin { /// {@macro build_ipa_command} - BuildIpaCommand({super.auth, super.validators}) { + BuildIpaCommand({super.validators}) { argParser ..addOption( 'target', diff --git a/packages/shorebird_cli/lib/src/commands/collaborators/add_collaborators_command.dart b/packages/shorebird_cli/lib/src/commands/collaborators/add_collaborators_command.dart index 9e45ba7c..ce646d82 100644 --- a/packages/shorebird_cli/lib/src/commands/collaborators/add_collaborators_command.dart +++ b/packages/shorebird_cli/lib/src/commands/collaborators/add_collaborators_command.dart @@ -1,9 +1,11 @@ import 'dart:async'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; /// {@template add_collaborators_command} @@ -13,7 +15,7 @@ import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; class AddCollaboratorsCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro add_collaborators_command} - AddCollaboratorsCommand({super.buildCodePushClient, super.auth}) { + AddCollaboratorsCommand({super.buildCodePushClient}) { argParser ..addOption( _appIdOption, @@ -46,10 +48,11 @@ class AddCollaboratorsCommand extends ShorebirdCommand final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); - final appId = results[_appIdOption] as String? ?? getShorebirdYaml()?.appId; + final appId = results[_appIdOption] as String? ?? + ShorebirdEnvironment.getShorebirdYaml()?.appId; if (appId == null) { logger.err( ''' diff --git a/packages/shorebird_cli/lib/src/commands/collaborators/delete_collaborators_command.dart b/packages/shorebird_cli/lib/src/commands/collaborators/delete_collaborators_command.dart index 4025ac53..db6d10d1 100644 --- a/packages/shorebird_cli/lib/src/commands/collaborators/delete_collaborators_command.dart +++ b/packages/shorebird_cli/lib/src/commands/collaborators/delete_collaborators_command.dart @@ -2,9 +2,11 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -15,7 +17,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; class DeleteCollaboratorsCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro delete_collaborators_command} - DeleteCollaboratorsCommand({super.buildCodePushClient, super.auth}) { + DeleteCollaboratorsCommand({super.buildCodePushClient}) { argParser ..addOption( _appIdOption, @@ -49,10 +51,11 @@ class DeleteCollaboratorsCommand extends ShorebirdCommand final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); - final appId = results[_appIdOption] as String? ?? getShorebirdYaml()?.appId; + final appId = results[_appIdOption] as String? ?? + ShorebirdEnvironment.getShorebirdYaml()?.appId; if (appId == null) { logger.err( ''' diff --git a/packages/shorebird_cli/lib/src/commands/collaborators/list_collaborators_command.dart b/packages/shorebird_cli/lib/src/commands/collaborators/list_collaborators_command.dart index 0abb4111..48e3f72b 100644 --- a/packages/shorebird_cli/lib/src/commands/collaborators/list_collaborators_command.dart +++ b/packages/shorebird_cli/lib/src/commands/collaborators/list_collaborators_command.dart @@ -2,9 +2,11 @@ import 'dart:async'; import 'package:barbecue/barbecue.dart'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -15,7 +17,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; class ListCollaboratorsCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro list_collaborators_command} - ListCollaboratorsCommand({super.buildCodePushClient, super.auth}) { + ListCollaboratorsCommand({super.buildCodePushClient}) { argParser.addOption( _appIdOption, help: 'The app id to list collaborators for.', @@ -45,10 +47,11 @@ class ListCollaboratorsCommand extends ShorebirdCommand final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); - final appId = results[_appIdOption] as String? ?? getShorebirdYaml()?.appId; + final appId = results[_appIdOption] as String? ?? + ShorebirdEnvironment.getShorebirdYaml()?.appId; if (appId == null) { logger.err( ''' diff --git a/packages/shorebird_cli/lib/src/commands/init_command.dart b/packages/shorebird_cli/lib/src/commands/init_command.dart index 48e45606..7e7560b0 100644 --- a/packages/shorebird_cli/lib/src/commands/init_command.dart +++ b/packages/shorebird_cli/lib/src/commands/init_command.dart @@ -5,6 +5,7 @@ import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; import 'package:shorebird_cli/src/shorebird_create_app_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_flavor_mixin.dart'; import 'package:shorebird_cli/src/shorebird_java_mixin.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; @@ -22,7 +23,7 @@ class InitCommand extends ShorebirdCommand ShorebirdJavaMixin, ShorebirdFlavorMixin { /// {@macro init_command} - InitCommand({super.auth, super.buildCodePushClient}) { + InitCommand({super.buildCodePushClient}) { argParser.addFlag( 'force', abbr: 'f', @@ -62,7 +63,7 @@ Please make sure you are running "shorebird init" from the root of your Flutter final force = results['force'] == true; if (force && hasShorebirdYaml) { - getShorebirdYamlFile().deleteSync(); + ShorebirdEnvironment.getShorebirdYamlFile().deleteSync(); } if (hasShorebirdYaml) { @@ -87,7 +88,7 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".'''); try { final displayName = logger.prompt( '${lightGreen.wrap('?')} How should we refer to this app?', - defaultValue: getPubspecYaml()?.name, + defaultValue: ShorebirdEnvironment.getPubspecYaml()?.name, ); if (productFlavors.isNotEmpty) { diff --git a/packages/shorebird_cli/lib/src/commands/login_command.dart b/packages/shorebird_cli/lib/src/commands/login_command.dart index cf632bfe..8baa2c59 100644 --- a/packages/shorebird_cli/lib/src/commands/login_command.dart +++ b/packages/shorebird_cli/lib/src/commands/login_command.dart @@ -8,9 +8,6 @@ import 'package:shorebird_cli/src/logger.dart'; /// Login as a new Shorebird user. /// {@endtemplate} class LoginCommand extends ShorebirdCommand { - /// {@macro login_command} - LoginCommand({super.auth}); - @override String get description => 'Login as a new Shorebird user.'; diff --git a/packages/shorebird_cli/lib/src/commands/logout_command.dart b/packages/shorebird_cli/lib/src/commands/logout_command.dart index 7e5fe2af..82f08b3c 100644 --- a/packages/shorebird_cli/lib/src/commands/logout_command.dart +++ b/packages/shorebird_cli/lib/src/commands/logout_command.dart @@ -1,4 +1,5 @@ import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; @@ -8,9 +9,6 @@ import 'package:shorebird_cli/src/logger.dart'; /// Logout of the current Shorebird user. /// {@endtemplate} class LogoutCommand extends ShorebirdCommand { - /// {@macro logout_command} - LogoutCommand({super.auth}); - @override String get description => 'Logout of the current Shorebird user'; diff --git a/packages/shorebird_cli/lib/src/commands/patch/patch_aar_command.dart b/packages/shorebird_cli/lib/src/commands/patch/patch_aar_command.dart index eb09ae50..8f1faf8f 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/patch_aar_command.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/patch_aar_command.dart @@ -7,6 +7,7 @@ import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; import 'package:path/path.dart' as p; import 'package:shorebird_cli/src/archive_analysis/archive_analysis.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/config/config.dart'; @@ -35,7 +36,6 @@ class PatchAarCommand extends ShorebirdCommand ShorebirdArtifactMixin { /// {@macro patch_aar_command} PatchAarCommand({ - super.auth, super.buildCodePushClient, super.cache, super.validators, @@ -138,10 +138,10 @@ of the Android app that is using this module.''', return ExitCode.software.code; } - final shorebirdYaml = getShorebirdYaml()!; + final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!; final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final appId = shorebirdYaml.getAppId(flavor: flavor); @@ -168,7 +168,7 @@ Did you forget to run "shorebird init"?''', return ExitCode.success.code; } - const platform = 'android'; + const platformName = 'android'; final channelName = results['channel'] as String; final Release? release; @@ -234,7 +234,7 @@ https://github.com/shorebirdtech/shorebird/issues/472 final releaseArtifacts = await getReleaseArtifacts( release: release, architectures: architectures, - platform: platform, + platform: platformName, ); if (releaseArtifacts == null) { return ExitCode.software.code; @@ -328,7 +328,7 @@ https://github.com/shorebirdtech/shorebird/issues/472 if (flavor != null) '🍧 Flavor: ${lightCyan.wrap(flavor)}', '📦 Release Version: ${lightCyan.wrap(releaseVersion)}', '📺 Channel: ${lightCyan.wrap(channelName)}', - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('[${archMetadata.join(', ')}]')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('[${archMetadata.join(', ')}]')}''', ]; logger.info( @@ -368,7 +368,7 @@ ${summary.join('\n')} patchId: patch.id, artifactPath: artifact.path, arch: artifact.arch, - platform: platform, + platform: platformName, hash: artifact.hash, ); } catch (error) { diff --git a/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart b/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart index 4d6f7a4c..36322cb9 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart @@ -33,10 +33,8 @@ class PatchAndroidCommand extends ShorebirdCommand ShorebirdReleaseVersionMixin { /// {@macro patch_android_command} PatchAndroidCommand({ - super.auth, super.cache, super.validators, - super.codePushClientWrapper, HashFunction? hashFn, http.Client? httpClient, AabDiffer? aabDiffer, @@ -113,7 +111,7 @@ class PatchAndroidCommand extends ShorebirdCommand await cache.updateAll(); - const platform = 'android'; + const platformName = 'android'; final channelName = results['channel'] as String; final flavor = results['flavor'] as String?; final target = results['target'] as String?; @@ -126,7 +124,7 @@ class PatchAndroidCommand extends ShorebirdCommand return ExitCode.software.code; } - final shorebirdYaml = getShorebirdYaml()!; + final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!; final appId = shorebirdYaml.getAppId(flavor: flavor); final app = await codePushClientWrapper.getApp(appId: appId); @@ -204,14 +202,14 @@ https://github.com/shorebirdtech/shorebird/issues/472 final releaseArtifacts = await codePushClientWrapper.getReleaseArtifacts( releaseId: release.id, architectures: architectures, - platform: platform, + platform: platformName, ); final releaseAabArtifact = await codePushClientWrapper.maybeGetReleaseArtifact( releaseId: release.id, arch: 'aab', - platform: platform, + platform: platformName, ); final releaseArtifactPaths = {}; @@ -332,7 +330,7 @@ If you believe you're seeing this in error, please reach out to us for support a if (flavor != null) '🍧 Flavor: ${lightCyan.wrap(flavor)}', '📦 Release Version: ${lightCyan.wrap(releaseVersion)}', '📺 Channel: ${lightCyan.wrap(channelName)}', - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('[${archMetadata.join(', ')}]')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('[${archMetadata.join(', ')}]')}''', ]; logger.info( @@ -357,7 +355,7 @@ ${summary.join('\n')} await codePushClientWrapper.publishPatch( appId: appId, releaseId: release.id, - platform: platform, + platform: platformName, channelName: channelName, patchArtifactBundles: patchArtifactBundles, ); diff --git a/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart b/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart index c4b15659..27061baa 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart @@ -27,8 +27,6 @@ class PatchIosCommand extends ShorebirdCommand ShorebirdArtifactMixin { /// {@macro patch_ios_command} PatchIosCommand({ - super.auth, - super.codePushClientWrapper, super.validators, HashFunction? hashFn, IpaReader? ipaReader, @@ -89,7 +87,7 @@ class PatchIosCommand extends ShorebirdCommand const arch = 'aarch64'; const channelName = 'stable'; - const platform = 'ios'; + const platformName = 'ios'; final force = results['force'] == true; final dryRun = results['dry-run'] == true; final flavor = results['flavor'] as String?; @@ -100,7 +98,7 @@ class PatchIosCommand extends ShorebirdCommand return ExitCode.usage.code; } - final shorebirdYaml = getShorebirdYaml()!; + final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!; final appId = shorebirdYaml.getAppId(flavor: flavor); final app = await codePushClientWrapper.getApp(appId: appId); @@ -129,7 +127,7 @@ class PatchIosCommand extends ShorebirdCommand 'Detecting release version', ); try { - final pubspec = getPubspecYaml()!; + final pubspec = ShorebirdEnvironment.getPubspecYaml()!; final ipa = _ipaReader.read( p.join( Directory.current.path, @@ -207,7 +205,7 @@ https://github.com/shorebirdtech/shorebird/issues/472 if (flavor != null) '🍧 Flavor: ${lightCyan.wrap(flavor)}', '📦 Release Version: ${lightCyan.wrap(releaseVersion)}', '📺 Channel: ${lightCyan.wrap(channelName)}', - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('[$arch (${formatBytes(aotFileSize)})]')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('[$arch (${formatBytes(aotFileSize)})]')}''', ]; logger.info( @@ -234,7 +232,7 @@ ${summary.join('\n')} await codePushClientWrapper.publishPatch( appId: appId, releaseId: release.id, - platform: platform, + platform: platformName, channelName: channelName, patchArtifactBundles: { Arch.arm64: PatchArtifactBundle( diff --git a/packages/shorebird_cli/lib/src/commands/release/release_aar_command.dart b/packages/shorebird_cli/lib/src/commands/release/release_aar_command.dart index 0f7fdfee..0687a009 100644 --- a/packages/shorebird_cli/lib/src/commands/release/release_aar_command.dart +++ b/packages/shorebird_cli/lib/src/commands/release/release_aar_command.dart @@ -6,6 +6,7 @@ import 'package:collection/collection.dart'; import 'package:crypto/crypto.dart'; import 'package:mason_logger/mason_logger.dart'; import 'package:path/path.dart' as p; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/config/config.dart'; import 'package:shorebird_cli/src/logger.dart'; @@ -13,6 +14,7 @@ import 'package:shorebird_cli/src/shorebird_artifact_mixin.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; import 'package:shorebird_cli/src/shorebird_create_app_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_java_mixin.dart'; import 'package:shorebird_cli/src/shorebird_release_version_mixin.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; @@ -33,7 +35,6 @@ class ReleaseAarCommand extends ShorebirdCommand ShorebirdArtifactMixin { /// {@macro release_aar_command} ReleaseAarCommand({ - super.auth, super.buildCodePushClient, super.validators, HashFunction? hashFn, @@ -110,10 +111,10 @@ make smaller updates to your app. buildProgress.complete(); - final shorebirdYaml = getShorebirdYaml()!; + final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!; final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); late final List apps; @@ -139,7 +140,7 @@ Did you forget to run "shorebird init"?''', return ExitCode.software.code; } - const platform = 'android'; + const platformName = 'android'; final archNames = architectures.keys.map( (arch) => arch.name, ); @@ -147,7 +148,7 @@ Did you forget to run "shorebird init"?''', '''📱 App: ${lightCyan.wrap(app.displayName)} ${lightCyan.wrap('(${app.id})')}''', if (flavor != null) '🍧 Flavor: ${lightCyan.wrap(flavor)}', '📦 Release Version: ${lightCyan.wrap(releaseVersion)}', - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('(${archNames.join(', ')})')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('(${archNames.join(', ')})')}''', ]; logger.info(''' @@ -230,7 +231,7 @@ ${summary.join('\n')} releaseId: release.id, artifactPath: artifact.path, arch: archMetadata.arch, - platform: platform, + platform: platformName, hash: hash, ); } on CodePushConflictException catch (_) { @@ -256,7 +257,7 @@ ${archMetadata.arch} artifact already exists, continuing...''', releaseId: release.id, artifactPath: aarPath, arch: 'aar', - platform: platform, + platform: platformName, hash: _hashFn(await File(aarPath).readAsBytes()), ); } on CodePushConflictException catch (_) { diff --git a/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart b/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart index 669f809b..9fe27d93 100644 --- a/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart +++ b/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart @@ -2,12 +2,14 @@ import 'dart:io'; import 'package:mason_logger/mason_logger.dart'; import 'package:path/path.dart' as p; +import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/config/shorebird_yaml.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; import 'package:shorebird_cli/src/shorebird_create_app_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_java_mixin.dart'; import 'package:shorebird_cli/src/shorebird_release_version_mixin.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; @@ -26,9 +28,7 @@ class ReleaseAndroidCommand extends ShorebirdCommand ShorebirdReleaseVersionMixin { /// {@macro release_android_command} ReleaseAndroidCommand({ - super.auth, super.cache, - super.codePushClientWrapper, super.validators, }) { argParser @@ -71,7 +71,7 @@ make smaller updates to your app. return e.exitCode.code; } - const platform = 'android'; + const platformName = 'android'; final flavor = results['flavor'] as String?; final target = results['target'] as String?; final buildProgress = logger.progress('Building release'); @@ -83,7 +83,7 @@ make smaller updates to your app. return ExitCode.software.code; } - final shorebirdYaml = getShorebirdYaml()!; + final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!; final appId = shorebirdYaml.getAppId(flavor: flavor); final app = await codePushClientWrapper.getApp(appId: appId); @@ -125,7 +125,7 @@ Please bump your version number and try again.''', '''📱 App: ${lightCyan.wrap(app.displayName)} ${lightCyan.wrap('(${app.appId})')}''', if (flavor != null) '🍧 Flavor: ${lightCyan.wrap(flavor)}', '📦 Release Version: ${lightCyan.wrap(releaseVersion)}', - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('(${archNames.join(', ')})')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('(${archNames.join(', ')})')}''', ]; logger.info(''' @@ -167,7 +167,7 @@ ${summary.join('\n')} await codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: release.id, aabPath: bundlePath, - platform: platform, + platform: platformName, architectures: architectures, flavor: flavor, ); diff --git a/packages/shorebird_cli/lib/src/commands/release/release_ios_command.dart b/packages/shorebird_cli/lib/src/commands/release/release_ios_command.dart index ecde4b11..7cce3004 100644 --- a/packages/shorebird_cli/lib/src/commands/release/release_ios_command.dart +++ b/packages/shorebird_cli/lib/src/commands/release/release_ios_command.dart @@ -3,11 +3,13 @@ import 'dart:io'; import 'package:mason_logger/mason_logger.dart'; import 'package:path/path.dart' as p; import 'package:shorebird_cli/src/archive_analysis/archive_analysis.dart'; +import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/config/config.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; /// {@template release_ios_command} @@ -18,8 +20,6 @@ class ReleaseIosCommand extends ShorebirdCommand with ShorebirdBuildMixin, ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro release_ios_command} ReleaseIosCommand({ - super.auth, - super.codePushClientWrapper, super.cache, super.validators, IpaReader? ipaReader, @@ -68,9 +68,9 @@ make smaller updates to your app. '''iOS support is in an experimental state and will not work without Flutter engine changes that have not yet been published.''', ); - const platform = 'ios'; + const platformName = 'ios'; final flavor = results['flavor'] as String?; - final shorebirdYaml = getShorebirdYaml()!; + final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!; final appId = shorebirdYaml.getAppId(flavor: flavor); final app = await codePushClientWrapper.getApp(appId: appId); @@ -89,7 +89,7 @@ make smaller updates to your app. buildProgress.complete(); final releaseVersionProgress = logger.progress('Getting release version'); - final pubspec = getPubspecYaml()!; + final pubspec = ShorebirdEnvironment.getPubspecYaml()!; final ipaPath = p.join( Directory.current.path, 'build', @@ -128,7 +128,7 @@ Please bump your version number and try again.''', '''📱 App: ${lightCyan.wrap(app.displayName)} ${lightCyan.wrap('($appId)')}''', if (flavor != null) '🍧 Flavor: ${lightCyan.wrap(flavor)}', '📦 Release Version: ${lightCyan.wrap(releaseVersion)}', - '''🕹️ Platform: ${lightCyan.wrap(platform)}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)}''', ]; logger.info(''' diff --git a/packages/shorebird_cli/lib/src/commands/releases/delete_releases_command.dart b/packages/shorebird_cli/lib/src/commands/releases/delete_releases_command.dart index fb7e8453..a9188a48 100644 --- a/packages/shorebird_cli/lib/src/commands/releases/delete_releases_command.dart +++ b/packages/shorebird_cli/lib/src/commands/releases/delete_releases_command.dart @@ -2,10 +2,12 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/config/shorebird_yaml.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -17,7 +19,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; class DeleteReleasesCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro delete_releases_command} - DeleteReleasesCommand({super.auth, super.buildCodePushClient}) { + DeleteReleasesCommand({super.buildCodePushClient}) { argParser ..addOption( 'version', @@ -47,11 +49,12 @@ class DeleteReleasesCommand extends ShorebirdCommand } final flavor = results['flavor'] as String?; - final appId = getShorebirdYaml()!.getAppId(flavor: flavor); + final appId = + ShorebirdEnvironment.getShorebirdYaml()!.getAppId(flavor: flavor); final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final List releases; diff --git a/packages/shorebird_cli/lib/src/commands/releases/list_releases_command.dart b/packages/shorebird_cli/lib/src/commands/releases/list_releases_command.dart index e893d622..b1588679 100644 --- a/packages/shorebird_cli/lib/src/commands/releases/list_releases_command.dart +++ b/packages/shorebird_cli/lib/src/commands/releases/list_releases_command.dart @@ -1,9 +1,11 @@ import 'package:barbecue/barbecue.dart'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/config/shorebird_yaml.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -15,7 +17,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; class ListReleasesCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro list_releases_command} - ListReleasesCommand({super.auth, super.buildCodePushClient}) { + ListReleasesCommand({super.buildCodePushClient}) { argParser.addOption( 'flavor', help: 'The product flavor to use when listing releases.', @@ -40,11 +42,12 @@ class ListReleasesCommand extends ShorebirdCommand } final flavor = results['flavor'] as String?; - final appId = getShorebirdYaml()!.getAppId(flavor: flavor); + final appId = + ShorebirdEnvironment.getShorebirdYaml()!.getAppId(flavor: flavor); final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final List releases; diff --git a/packages/shorebird_cli/lib/src/commands/run_command.dart b/packages/shorebird_cli/lib/src/commands/run_command.dart index 300334cc..716c33ed 100644 --- a/packages/shorebird_cli/lib/src/commands/run_command.dart +++ b/packages/shorebird_cli/lib/src/commands/run_command.dart @@ -12,7 +12,7 @@ import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; class RunCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { /// {@macro run_command} - RunCommand({super.auth, super.buildCodePushClient, super.validators}) { + RunCommand({super.buildCodePushClient, super.validators}) { argParser ..addOption( 'device-id', diff --git a/packages/shorebird_cli/lib/src/commands/subscription/cancel_subscription_command.dart b/packages/shorebird_cli/lib/src/commands/subscription/cancel_subscription_command.dart index 56bec551..1480939f 100644 --- a/packages/shorebird_cli/lib/src/commands/subscription/cancel_subscription_command.dart +++ b/packages/shorebird_cli/lib/src/commands/subscription/cancel_subscription_command.dart @@ -2,15 +2,17 @@ import 'dart:async'; import 'package:intl/intl.dart'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/command.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_validation_mixin.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; class CancelSubscriptionCommand extends ShorebirdCommand with ShorebirdConfigMixin, ShorebirdValidationMixin { - CancelSubscriptionCommand({super.auth, super.buildCodePushClient}); + CancelSubscriptionCommand({super.buildCodePushClient}); @override String get name => 'cancel'; @@ -30,7 +32,7 @@ class CancelSubscriptionCommand extends ShorebirdCommand final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final User user; diff --git a/packages/shorebird_cli/lib/src/logger.dart b/packages/shorebird_cli/lib/src/logger.dart index 59d4dd30..f4032517 100644 --- a/packages/shorebird_cli/lib/src/logger.dart +++ b/packages/shorebird_cli/lib/src/logger.dart @@ -2,7 +2,7 @@ import 'package:mason_logger/mason_logger.dart'; import 'package:scoped/scoped.dart'; // A reference to a [Logger] instance. -ScopedRef loggerRef = create(Logger.new); +final loggerRef = create(Logger.new); // The [Logger] instance available in the current zone. Logger get logger => read(loggerRef); diff --git a/packages/shorebird_cli/lib/src/shorebird_code_push_client_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_code_push_client_mixin.dart index cec2cd91..156a26e6 100644 --- a/packages/shorebird_cli/lib/src/shorebird_code_push_client_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_code_push_client_mixin.dart @@ -1,14 +1,16 @@ import 'package:collection/collection.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; mixin ShorebirdCodePushClientMixin on ShorebirdConfigMixin { Future getApp({required String appId, String? flavor}) async { final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final List apps; @@ -32,7 +34,7 @@ mixin ShorebirdCodePushClientMixin on ShorebirdConfigMixin { }) async { final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final fetchChannelsProgress = logger.progress('Fetching channels'); try { @@ -54,7 +56,7 @@ mixin ShorebirdCodePushClientMixin on ShorebirdConfigMixin { }) async { final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final createChannelProgress = logger.progress('Creating channel'); @@ -77,7 +79,7 @@ mixin ShorebirdCodePushClientMixin on ShorebirdConfigMixin { }) async { final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final List releases; @@ -100,7 +102,7 @@ mixin ShorebirdCodePushClientMixin on ShorebirdConfigMixin { }) async { final codePushClient = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); final releaseArtifacts = {}; diff --git a/packages/shorebird_cli/lib/src/shorebird_config_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_config_mixin.dart index c12826cc..3098a481 100644 --- a/packages/shorebird_cli/lib/src/shorebird_config_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_config_mixin.dart @@ -8,9 +8,10 @@ import 'package:yaml/yaml.dart'; import 'package:yaml_edit/yaml_edit.dart'; mixin ShorebirdConfigMixin on ShorebirdCommand { - bool get hasShorebirdYaml => getShorebirdYamlFile().existsSync(); + bool get hasShorebirdYaml => + ShorebirdEnvironment.getShorebirdYamlFile().existsSync(); - bool get hasPubspecYaml => getPubspecYaml() != null; + bool get hasPubspecYaml => ShorebirdEnvironment.getPubspecYaml() != null; bool get isShorebirdInitialized { return hasShorebirdYaml && pubspecContainsShorebirdYaml; @@ -29,7 +30,7 @@ mixin ShorebirdConfigMixin on ShorebirdCommand { /// Returns the Android package name from the pubspec.yaml file of a Flutter /// module. String? get androidPackageName { - final pubspec = getPubspecYaml()!; + final pubspec = ShorebirdEnvironment.getPubspecYaml()!; final module = pubspec.flutter?['module'] as Map?; return module?['androidPackage'] as String?; } @@ -52,7 +53,8 @@ app_id: if (flavors != null) editor.update(['flavors'], flavors); - getShorebirdYamlFile().writeAsStringSync(editor.toString()); + ShorebirdEnvironment.getShorebirdYamlFile() + .writeAsStringSync(editor.toString()); return ShorebirdYaml(appId: appId); } diff --git a/packages/shorebird_cli/lib/src/shorebird_create_app_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_create_app_mixin.dart index 2f8c71ef..276f4031 100644 --- a/packages/shorebird_cli/lib/src/shorebird_create_app_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_create_app_mixin.dart @@ -1,6 +1,8 @@ import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; mixin ShorebirdCreateAppMixin on ShorebirdConfigMixin { @@ -9,7 +11,7 @@ mixin ShorebirdCreateAppMixin on ShorebirdConfigMixin { if (appName == null) { String? defaultAppName; try { - defaultAppName = getPubspecYaml()?.name; + defaultAppName = ShorebirdEnvironment.getPubspecYaml()?.name; } catch (_) {} displayName = logger.prompt( @@ -22,7 +24,7 @@ mixin ShorebirdCreateAppMixin on ShorebirdConfigMixin { final client = buildCodePushClient( httpClient: auth.client, - hostedUri: hostedUri, + hostedUri: ShorebirdEnvironment.hostedUri, ); return client.createApp(displayName: displayName); diff --git a/packages/shorebird_cli/lib/src/shorebird_environment.dart b/packages/shorebird_cli/lib/src/shorebird_environment.dart index 15f94541..f076ad9e 100644 --- a/packages/shorebird_cli/lib/src/shorebird_environment.dart +++ b/packages/shorebird_cli/lib/src/shorebird_environment.dart @@ -1,13 +1,14 @@ import 'dart:io' hide Platform; +import 'package:checked_yaml/checked_yaml.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; import 'package:platform/platform.dart'; +import 'package:pubspec_parse/pubspec_parse.dart'; +import 'package:shorebird_cli/src/config/shorebird_yaml.dart'; +import 'package:shorebird_cli/src/platform.dart'; abstract class ShorebirdEnvironment { - @visibleForTesting - static Platform platform = const LocalPlatform(); - /// Environment variables from [Platform.environment]. static Map get environment => platform.environment; @@ -75,4 +76,45 @@ abstract class ShorebirdEnvironment { 'gen_snapshot_arm64', ), ); + + /// The `shorebird.yaml` file for this project. + static File getShorebirdYamlFile() { + return File(p.join(Directory.current.path, 'shorebird.yaml')); + } + + /// The `shorebird.yaml` file for this project, parsed into a [ShorebirdYaml] + /// object. + /// + /// Returns `null` if the file does not exist. + /// Throws a [ParsedYamlException] if the file exists but is invalid. + static ShorebirdYaml? getShorebirdYaml() { + final file = getShorebirdYamlFile(); + if (!file.existsSync()) return null; + final yaml = file.readAsStringSync(); + return checkedYamlDecode(yaml, (m) => ShorebirdYaml.fromJson(m!)); + } + + /// The `pubspec.yaml` file for this project, parsed into a [Pubspec] object. + /// + /// Returns `null` if the file does not exist. + /// Throws a [ParsedYamlException] if the file exists but is invalid. + static Pubspec? getPubspecYaml() { + final file = File(p.join(Directory.current.path, 'pubspec.yaml')); + if (!file.existsSync()) return null; + final yaml = file.readAsStringSync(); + return Pubspec.parse(yaml); + } + + /// The base URL for the Shorebird code push server that overrides the default + /// used by [CodePushClient]. If none is provided, [CodePushClient] will use + /// its default. + static Uri? get hostedUri { + try { + final baseUrl = platform.environment['SHOREBIRD_HOSTED_URL'] ?? + getShorebirdYaml()?.baseUrl; + return baseUrl == null ? null : Uri.tryParse(baseUrl); + } catch (_) { + return null; + } + } } diff --git a/packages/shorebird_cli/lib/src/shorebird_validation_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_validation_mixin.dart index fc4167d0..6fb26d47 100644 --- a/packages/shorebird_cli/lib/src/shorebird_validation_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_validation_mixin.dart @@ -1,5 +1,6 @@ import 'package:collection/collection.dart'; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/shorebird_config_mixin.dart'; import 'package:shorebird_cli/src/validators/validators.dart'; diff --git a/packages/shorebird_cli/test/src/auth/auth_test.dart b/packages/shorebird_cli/test/src/auth/auth_test.dart index 9e03a9a0..5e762b8e 100644 --- a/packages/shorebird_cli/test/src/auth/auth_test.dart +++ b/packages/shorebird_cli/test/src/auth/auth_test.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; +import 'package:cli_util/cli_util.dart'; import 'package:googleapis_auth/googleapis_auth.dart'; import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; @@ -8,6 +9,7 @@ import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/auth/auth.dart'; +import 'package:shorebird_cli/src/command_runner.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; import 'package:test/test.dart'; @@ -21,6 +23,16 @@ class _MockLogger extends Mock implements Logger {} class _MockHttpClient extends Mock implements http.Client {} void main() { + group('scoped', () { + test('creates instance with default constructor', () { + final instance = runScoped(() => auth, values: {authRef}); + expect( + instance.credentialsFilePath, + p.join(applicationConfigHome(executableName), 'credentials.json'), + ); + }); + }); + group('Auth', () { const idToken = '''eyJhbGciOiJSUzI1NiIsImN0eSI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAZW1haWwuY29tIn0.pD47BhF3MBLyIpfsgWCzP9twzC1HJxGukpcR36DqT6yfiOMHTLcjDbCjRLAnklWEHiT0BQTKTfhs8IousU90Fm5bVKObudfKu8pP5iZZ6Ls4ohDjTrXky9j3eZpZjwv8CnttBVgRfMJG-7YASTFRYFcOLUpnb4Zm5R6QdoCDUYg'''; diff --git a/packages/shorebird_cli/test/src/cache_test.dart b/packages/shorebird_cli/test/src/cache_test.dart index 776398f2..cfe2b10f 100644 --- a/packages/shorebird_cli/test/src/cache_test.dart +++ b/packages/shorebird_cli/test/src/cache_test.dart @@ -5,7 +5,9 @@ import 'package:http/http.dart' as http; import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; import 'package:platform/platform.dart'; +import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/cache.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:test/test.dart'; @@ -32,6 +34,15 @@ void main() { late Platform platform; late Cache cache; + R runWithOverrides(R Function() body) { + return runScoped( + () => body(), + values: { + platformRef.overrideWith(() => platform), + }, + ); + } + setUpAll(() { registerFallbackValue(_FakeBaseRequest()); }); @@ -41,9 +52,9 @@ void main() { platform = _MockPlatform(); shorebirdRoot = Directory.systemTemp.createTempSync(); - ShorebirdEnvironment.platform = platform; ShorebirdEnvironment.shorebirdEngineRevision = 'test-revision'; + when(() => platform.environment).thenReturn({}); when(() => platform.isMacOS).thenReturn(true); when(() => platform.isWindows).thenReturn(false); when(() => platform.isLinux).thenReturn(false); @@ -86,25 +97,32 @@ void main() { group('clear', () { test('deletes the cache directory', () async { - Cache.shorebirdCacheDirectory.createSync(recursive: true); - expect(Cache.shorebirdCacheDirectory.existsSync(), isTrue); - cache.clear(); - expect(Cache.shorebirdCacheDirectory.existsSync(), isFalse); + final shorebirdCacheDirectory = + runWithOverrides(() => Cache.shorebirdCacheDirectory) + ..createSync(recursive: true); + expect(shorebirdCacheDirectory.existsSync(), isTrue); + runWithOverrides(cache.clear); + expect(shorebirdCacheDirectory.existsSync(), isFalse); }); test('does nothing if directory does not exist', () { - expect(Cache.shorebirdCacheDirectory.existsSync(), isFalse); - cache.clear(); - expect(Cache.shorebirdCacheDirectory.existsSync(), isFalse); + final shorebirdCacheDirectory = + runWithOverrides(() => Cache.shorebirdCacheDirectory); + expect(shorebirdCacheDirectory.existsSync(), isFalse); + runWithOverrides(cache.clear); + expect(shorebirdCacheDirectory.existsSync(), isFalse); }); }); group('updateAll', () { group('patch', () { test('downloads correct artifacts', () async { - expect(cache.getArtifactDirectory('patch').existsSync(), isFalse); - await expectLater(cache.updateAll(), completes); - expect(cache.getArtifactDirectory('patch').existsSync(), isTrue); + final patchArtifactDirectory = runWithOverrides( + () => cache.getArtifactDirectory('patch'), + ); + expect(patchArtifactDirectory.existsSync(), isFalse); + await expectLater(runWithOverrides(cache.updateAll), completes); + expect(patchArtifactDirectory.existsSync(), isTrue); }); test('pull correct artifact for MacOS', () async { @@ -112,7 +130,8 @@ void main() { when(() => platform.isWindows).thenReturn(false); when(() => platform.isLinux).thenReturn(false); - await expectLater(cache.updateAll(), completes); + await expectLater(runWithOverrides(cache.updateAll), completes); + final request = verify(() => httpClient.send(captureAny())) .captured .first as http.BaseRequest; @@ -132,7 +151,8 @@ void main() { when(() => platform.isWindows).thenReturn(true); when(() => platform.isLinux).thenReturn(false); - await expectLater(cache.updateAll(), completes); + await expectLater(runWithOverrides(cache.updateAll), completes); + final request = verify(() => httpClient.send(captureAny())) .captured .first as http.BaseRequest; @@ -152,11 +172,11 @@ void main() { when(() => platform.isWindows).thenReturn(false); when(() => platform.isLinux).thenReturn(true); - await expectLater(cache.updateAll(), completes); + await expectLater(runWithOverrides(cache.updateAll), completes); + final request = verify(() => httpClient.send(captureAny())) .captured .first as http.BaseRequest; - expect( request.url, equals( diff --git a/packages/shorebird_cli/test/src/code_push_client_wrapper_test.dart b/packages/shorebird_cli/test/src/code_push_client_wrapper_test.dart index abd9f17e..be7cf553 100644 --- a/packages/shorebird_cli/test/src/code_push_client_wrapper_test.dart +++ b/packages/shorebird_cli/test/src/code_push_client_wrapper_test.dart @@ -1,21 +1,64 @@ +import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/logger.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.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'; +class _MockAuth extends Mock implements Auth {} + class _MockCodePushClient extends Mock implements CodePushClient {} +class _MockHttpClient extends Mock implements http.Client {} + class _MockLogger extends Mock implements Logger {} +class _MockPlatform extends Mock implements Platform {} + class _MockProgress extends Mock implements Progress {} void main() { + group('scoped', () { + late Auth auth; + late http.Client httpClient; + late Platform platform; + + setUp(() { + auth = _MockAuth(); + httpClient = _MockHttpClient(); + platform = _MockPlatform(); + + when(() => auth.client).thenReturn(httpClient); + when(() => platform.environment).thenReturn({ + 'SHOREBIRD_HOSTED_URL': 'http://example.com', + }); + }); + + test('creates instance from scoped Auth and ShorebirdEnvironment', () { + final instance = runScoped( + () => codePushClientWrapper, + values: { + codePushClientWrapperRef, + authRef.overrideWith(() => auth), + platformRef.overrideWith(() => platform), + }, + ); + expect( + instance.codePushClient.hostedUri, + Uri.parse('http://example.com'), + ); + verify(() => auth.client).called(1); + }); + }); + group(CodePushClientWrapper, () { Matcher exitsWithCode(ExitCode exitcode) => throwsA( isA().having( @@ -31,7 +74,7 @@ void main() { const patchId = 1; const patchNumber = 2; const patch = Patch(id: patchId, number: patchNumber); - const platform = 'ios'; + const platformName = 'ios'; const releaseId = 123; const arch = Arch.arm64; const flutterRevision = '123'; @@ -62,7 +105,7 @@ void main() { id: 1, releaseId: releaseId, arch: 'aarch64', - platform: platform, + platform: platformName, hash: 'asdf', size: 4, url: 'url', @@ -495,7 +538,7 @@ void main() { () => codePushClientWrapper.getReleaseArtifacts( releaseId: releaseId, architectures: archMap, - platform: platform, + platform: platformName, ), ), exitsWithCode(ExitCode.software), @@ -517,7 +560,7 @@ void main() { () => codePushClientWrapper.getReleaseArtifacts( releaseId: releaseId, architectures: archMap, - platform: platform, + platform: platformName, ), ); @@ -542,7 +585,7 @@ void main() { () => codePushClientWrapper.maybeGetReleaseArtifact( releaseId: releaseId, arch: arch.name, - platform: platform, + platform: platformName, ), ), exitsWithCode(ExitCode.software), @@ -564,7 +607,7 @@ void main() { () => codePushClientWrapper.maybeGetReleaseArtifact( releaseId: releaseId, arch: arch.name, - platform: platform, + platform: platformName, ), ); @@ -587,7 +630,7 @@ void main() { () => codePushClientWrapper.maybeGetReleaseArtifact( releaseId: releaseId, arch: arch.name, - platform: platform, + platform: platformName, ), ); @@ -652,7 +695,7 @@ void main() { () async => runWithOverrides( () async => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: releaseId, - platform: platform, + platform: platformName, aabPath: p.join(tempDir.path, aabPath), architectures: ShorebirdBuildMixin.allAndroidArchitectures, ), @@ -683,7 +726,7 @@ void main() { () async => runWithOverrides( () async => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: releaseId, - platform: platform, + platform: platformName, aabPath: p.join(tempDir.path, aabPath), architectures: ShorebirdBuildMixin.allAndroidArchitectures, ), @@ -714,7 +757,7 @@ void main() { () async => IOOverrides.runZoned( () async => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: releaseId, - platform: platform, + platform: platformName, aabPath: p.join(tempDir.path, aabPath), architectures: ShorebirdBuildMixin.allAndroidArchitectures, ), @@ -748,7 +791,7 @@ void main() { () async => IOOverrides.runZoned( () async => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: releaseId, - platform: platform, + platform: platformName, aabPath: p.join(tempDir.path, aabPath), architectures: ShorebirdBuildMixin.allAndroidArchitectures, ), @@ -780,7 +823,7 @@ void main() { () async => IOOverrides.runZoned( () async => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: releaseId, - platform: platform, + platform: platformName, aabPath: p.join(tempDir.path, aabPath), architectures: ShorebirdBuildMixin.allAndroidArchitectures, ), @@ -809,7 +852,7 @@ void main() { () async => IOOverrides.runZoned( () async => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: releaseId, - platform: platform, + platform: platformName, aabPath: p.join(tempDir.path, aabPath), architectures: ShorebirdBuildMixin.allAndroidArchitectures, flavor: flavorName, @@ -824,7 +867,7 @@ void main() { any(named: 'artifactPath', that: contains(flavorName)), releaseId: releaseId, arch: any(named: 'arch'), - platform: platform, + platform: platformName, hash: any(named: 'hash'), ), ).called(ShorebirdBuildMixin.allAndroidArchitectures.length); @@ -928,7 +971,7 @@ void main() { () async => runWithOverrides( () => codePushClientWrapper.createPatchArtifacts( patch: patch, - platform: platform, + platform: platformName, patchArtifactBundles: patchArtifactBundles, ), ), @@ -953,7 +996,7 @@ void main() { await runWithOverrides( () => codePushClientWrapper.createPatchArtifacts( patch: patch, - platform: platform, + platform: platformName, patchArtifactBundles: patchArtifactBundles, ), ); @@ -964,7 +1007,7 @@ void main() { artifactPath: partchArtifactBundle.path, patchId: patchId, arch: arch.name, - platform: platform, + platform: platformName, hash: partchArtifactBundle.hash, ), ).called(1); @@ -1001,7 +1044,7 @@ void main() { () => codePushClientWrapper.publishPatch( appId: appId, releaseId: releaseId, - platform: platform, + platform: platformName, channelName: channelName, patchArtifactBundles: patchArtifactBundles, ), @@ -1015,7 +1058,7 @@ void main() { artifactPath: partchArtifactBundle.path, patchId: patchId, arch: arch.name, - platform: platform, + platform: platformName, hash: partchArtifactBundle.hash, ), ).called(1); @@ -1050,7 +1093,7 @@ void main() { () => codePushClientWrapper.publishPatch( appId: appId, releaseId: releaseId, - platform: platform, + platform: platformName, channelName: channelName, patchArtifactBundles: patchArtifactBundles, ), @@ -1064,7 +1107,7 @@ void main() { artifactPath: partchArtifactBundle.path, patchId: patchId, arch: arch.name, - platform: platform, + platform: platformName, hash: partchArtifactBundle.hash, ), ).called(1); diff --git a/packages/shorebird_cli/test/src/command_runner_test.dart b/packages/shorebird_cli/test/src/command_runner_test.dart index d113aab6..936b026c 100644 --- a/packages/shorebird_cli/test/src/command_runner_test.dart +++ b/packages/shorebird_cli/test/src/command_runner_test.dart @@ -1,7 +1,9 @@ import 'package:args/command_runner.dart'; +import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; import 'package:mocktail/mocktail.dart'; import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/auth/auth.dart' hide auth; import 'package:shorebird_cli/src/command_runner.dart'; import 'package:shorebird_cli/src/logger.dart' hide logger; import 'package:shorebird_cli/src/shorebird_environment.dart'; @@ -9,33 +11,41 @@ import 'package:shorebird_cli/src/shorebird_process.dart'; import 'package:shorebird_cli/src/version.dart'; import 'package:test/test.dart'; +class _MockAuth extends Mock implements Auth {} + class _MockLogger extends Mock implements Logger {} +class _MockHttpClient extends Mock implements http.Client {} + class _MockProcessResult extends Mock implements ShorebirdProcessResult {} void main() { - group('ShorebirdCliCommandRunner', () { + group(ShorebirdCliCommandRunner, () { + late http.Client httpClient; + late Auth auth; late Logger logger; late ShorebirdProcessResult processResult; late ShorebirdCliCommandRunner commandRunner; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); - } - - ShorebirdCliCommandRunner buildRunner() { return runScoped( - ShorebirdCliCommandRunner.new, - values: {loggerRef.overrideWith(() => logger)}, + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, ); } setUp(() { + httpClient = _MockHttpClient(); + auth = _MockAuth(); logger = _MockLogger(); ShorebirdEnvironment.shorebirdEngineRevision = 'test-revision'; processResult = _MockProcessResult(); + when(() => auth.client).thenReturn(httpClient); when(() => processResult.exitCode).thenReturn(ExitCode.success.code); - commandRunner = buildRunner(); + commandRunner = runWithOverrides(ShorebirdCliCommandRunner.new); }); test('handles FormatException', () async { diff --git a/packages/shorebird_cli/test/src/command_test.dart b/packages/shorebird_cli/test/src/command_test.dart deleted file mode 100644 index 713ddb84..00000000 --- a/packages/shorebird_cli/test/src/command_test.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'dart:io'; - -import 'package:mocktail/mocktail.dart'; -import 'package:path/path.dart' as p; -import 'package:platform/platform.dart'; -import 'package:scoped/scoped.dart'; -import 'package:shorebird_cli/src/command.dart'; -import 'package:shorebird_cli/src/platform.dart'; -import 'package:test/test.dart'; - -class _MockPlatform extends Mock implements Platform {} - -class TestCommand extends ShorebirdCommand { - @override - String get description => 'test'; - - @override - String get name => 'test'; -} - -void main() { - group('ShorebirdCommand', () { - late Platform platform; - late ShorebirdCommand command; - - R runWithOverrides(R Function() body) { - return runScoped( - () => body(), - values: { - platformRef.overrideWith(() => platform), - }, - ); - } - - setUp(() { - platform = _MockPlatform(); - when(() => platform.environment).thenReturn(const {}); - command = runWithOverrides(TestCommand.new); - }); - - group('hostedUrl', () { - test('returns hosted url from env if available', () { - when(() => platform.environment).thenReturn({ - 'SHOREBIRD_HOSTED_URL': 'https://example.com', - }); - expect( - runWithOverrides(() => command.hostedUri), - equals(Uri.parse('https://example.com')), - ); - }); - - test('falls back to shorebird.yaml', () { - final directory = Directory.systemTemp.createTempSync(); - File(p.join(directory.path, 'shorebird.yaml')).writeAsStringSync(''' -app_id: test-id -base_url: https://example.com'''); - expect( - IOOverrides.runZoned( - () => runWithOverrides(() => command.hostedUri), - getCurrentDirectory: () => directory, - ), - equals(Uri.parse('https://example.com')), - ); - }); - - test('returns null when there is no env override or shorebird.yaml', () { - expect(runWithOverrides(() => command.hostedUri), isNull); - }); - }); - }); -} diff --git a/packages/shorebird_cli/test/src/commands/account/create_account_command_test.dart b/packages/shorebird_cli/test/src/commands/account/create_account_command_test.dart index 762e83f9..60dbbb70 100644 --- a/packages/shorebird_cli/test/src/commands/account/create_account_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/account/create_account_command_test.dart @@ -29,7 +29,13 @@ void main() { late CreateAccountCommand createAccountCommand; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -46,7 +52,7 @@ void main() { when(() => user.displayName).thenReturn(userName); when(() => user.email).thenReturn(email); - createAccountCommand = CreateAccountCommand(auth: auth); + createAccountCommand = runWithOverrides(CreateAccountCommand.new); }); test('has a description', () { diff --git a/packages/shorebird_cli/test/src/commands/account/subscribe_account_command_test.dart b/packages/shorebird_cli/test/src/commands/account/subscribe_account_command_test.dart index 8ef79994..a626682f 100644 --- a/packages/shorebird_cli/test/src/commands/account/subscribe_account_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/account/subscribe_account_command_test.dart @@ -34,7 +34,13 @@ void main() { group(SubscribeAccountCommand, () { R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -58,10 +64,12 @@ void main() { when(() => user.hasActiveSubscription).thenReturn(false); - subscribeAccountCommand = SubscribeAccountCommand( - auth: auth, - buildCodePushClient: ({required httpClient, hostedUri}) => - codePushClient, + subscribeAccountCommand = runWithOverrides( + () => SubscribeAccountCommand( + buildCodePushClient: ({required httpClient, hostedUri}) { + return codePushClient; + }, + ), ); }); diff --git a/packages/shorebird_cli/test/src/commands/apps/create_apps_command_test.dart b/packages/shorebird_cli/test/src/commands/apps/create_apps_command_test.dart index 55627b25..b291b6e3 100644 --- a/packages/shorebird_cli/test/src/commands/apps/create_apps_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/apps/create_apps_command_test.dart @@ -20,7 +20,7 @@ class _MockCodePushClient extends Mock implements CodePushClient {} class _MockLogger extends Mock implements Logger {} void main() { - group('create', () { + group(CreateAppCommand, () { const appId = 'app-id'; const displayName = 'Example App'; @@ -32,7 +32,13 @@ void main() { late CreateAppCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -45,14 +51,15 @@ void main() { when(() => auth.client).thenReturn(httpClient); when(() => auth.isAuthenticated).thenReturn(true); - command = CreateAppCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => CreateAppCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), )..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/apps/delete_apps_command_test.dart b/packages/shorebird_cli/test/src/commands/apps/delete_apps_command_test.dart index 302d8f88..d5ac87d0 100644 --- a/packages/shorebird_cli/test/src/commands/apps/delete_apps_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/apps/delete_apps_command_test.dart @@ -20,7 +20,7 @@ class _MockCodePushClient extends Mock implements CodePushClient {} class _MockLogger extends Mock implements Logger {} void main() { - group('delete', () { + group(DeleteAppCommand, () { const appId = 'example'; late ArgResults argResults; @@ -31,7 +31,13 @@ void main() { late DeleteAppCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -44,14 +50,15 @@ void main() { when(() => auth.isAuthenticated).thenReturn(true); when(() => auth.client).thenReturn(httpClient); - command = DeleteAppCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => DeleteAppCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), )..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/apps/list_apps_command_test.dart b/packages/shorebird_cli/test/src/commands/apps/list_apps_command_test.dart index 20c8c494..b59d876b 100644 --- a/packages/shorebird_cli/test/src/commands/apps/list_apps_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/apps/list_apps_command_test.dart @@ -17,7 +17,7 @@ class _MockCodePushClient extends Mock implements CodePushClient {} class _MockLogger extends Mock implements Logger {} void main() { - group('list', () { + group(ListAppsCommand, () { late http.Client httpClient; late Auth auth; late CodePushClient codePushClient; @@ -25,7 +25,13 @@ void main() { late ListAppsCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -37,14 +43,15 @@ void main() { when(() => auth.isAuthenticated).thenReturn(true); when(() => auth.client).thenReturn(httpClient); - command = ListAppsCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => ListAppsCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), ); }); diff --git a/packages/shorebird_cli/test/src/commands/build/build_aar_command_test.dart b/packages/shorebird_cli/test/src/commands/build/build_aar_command_test.dart index c29f12e9..9a507969 100644 --- a/packages/shorebird_cli/test/src/commands/build/build_aar_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/build/build_aar_command_test.dart @@ -64,7 +64,13 @@ flutter: late BuildAarCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } Directory setUpTempDir({bool includeModule = true}) { @@ -105,7 +111,7 @@ flutter: return processResult; }); - command = BuildAarCommand(auth: auth, validators: []) + command = runWithOverrides(() => BuildAarCommand(validators: [])) ..testArgResults = argResults ..testProcess = shorebirdProcess ..testEngineConfig = const EngineConfig.empty(); diff --git a/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart b/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart index c47c330f..80b3bbd5 100644 --- a/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart @@ -42,7 +42,13 @@ void main() { late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -70,9 +76,8 @@ void main() { when(() => logger.info(any())).thenReturn(null); when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); - command = BuildApkCommand( - auth: auth, - validators: [flutterValidator], + command = runWithOverrides( + () => BuildApkCommand(validators: [flutterValidator]), ) ..testArgResults = argResults ..testProcess = shorebirdProcess diff --git a/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart b/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart index b8b4a286..5f87ec87 100644 --- a/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart @@ -42,7 +42,13 @@ void main() { late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -70,9 +76,8 @@ void main() { when(() => logger.info(any())).thenReturn(null); when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); - command = BuildAppBundleCommand( - auth: auth, - validators: [flutterValidator], + command = runWithOverrides( + () => BuildAppBundleCommand(validators: [flutterValidator]), ) ..testArgResults = argResults ..testProcess = shorebirdProcess diff --git a/packages/shorebird_cli/test/src/commands/build/build_ipa_command_test.dart b/packages/shorebird_cli/test/src/commands/build/build_ipa_command_test.dart index 8ed66826..97979656 100644 --- a/packages/shorebird_cli/test/src/commands/build/build_ipa_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/build/build_ipa_command_test.dart @@ -43,7 +43,13 @@ void main() { late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -72,9 +78,8 @@ void main() { when(() => logger.info(any())).thenReturn(null); when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); - command = BuildIpaCommand( - auth: auth, - validators: [flutterValidator], + command = runWithOverrides( + () => BuildIpaCommand(validators: [flutterValidator]), ) ..testArgResults = argResults ..testProcess = shorebirdProcess diff --git a/packages/shorebird_cli/test/src/commands/collaborators/add_collaborators_command_test.dart b/packages/shorebird_cli/test/src/commands/collaborators/add_collaborators_command_test.dart index b25ac9bc..d0e7e2da 100644 --- a/packages/shorebird_cli/test/src/commands/collaborators/add_collaborators_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/collaborators/add_collaborators_command_test.dart @@ -22,7 +22,7 @@ class _MockLogger extends Mock implements Logger {} class _MockProgress extends Mock implements Progress {} void main() { - group('create', () { + group(AddCollaboratorsCommand, () { const appId = 'test-app-id'; const email = 'jane.doe@shorebird.dev'; @@ -35,7 +35,13 @@ void main() { late AddCollaboratorsCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -53,14 +59,15 @@ void main() { when(() => logger.confirm(any())).thenReturn(true); when(() => logger.progress(any())).thenReturn(progress); - command = AddCollaboratorsCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => AddCollaboratorsCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), )..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/collaborators/delete_collaborators_command_test.dart b/packages/shorebird_cli/test/src/commands/collaborators/delete_collaborators_command_test.dart index 92b8a52c..e44b2f25 100644 --- a/packages/shorebird_cli/test/src/commands/collaborators/delete_collaborators_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/collaborators/delete_collaborators_command_test.dart @@ -25,7 +25,7 @@ class _MockLogger extends Mock implements Logger {} class _MockProgress extends Mock implements Progress {} void main() { - group('delete', () { + group(DeleteCollaboratorsCommand, () { const appId = 'test-app-id'; const email = 'jane.doe@shorebird.dev'; const collaborator = Collaborator(userId: 0, email: email); @@ -39,7 +39,13 @@ void main() { late DeleteCollaboratorsCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -66,14 +72,15 @@ void main() { ), ).thenAnswer((_) async {}); - command = DeleteCollaboratorsCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => DeleteCollaboratorsCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), )..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/collaborators/list_collaborators_command_test.dart b/packages/shorebird_cli/test/src/commands/collaborators/list_collaborators_command_test.dart index a4484f4c..72caf731 100644 --- a/packages/shorebird_cli/test/src/commands/collaborators/list_collaborators_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/collaborators/list_collaborators_command_test.dart @@ -20,7 +20,7 @@ class _MockCodePushClient extends Mock implements CodePushClient {} class _MockLogger extends Mock implements Logger {} void main() { - group('collborators list', () { + group(ListCollaboratorsCommand, () { const appId = 'test-app-id'; late ArgResults argResults; @@ -31,7 +31,13 @@ void main() { late ListCollaboratorsCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -45,14 +51,15 @@ void main() { when(() => auth.client).thenReturn(httpClient); when(() => auth.isAuthenticated).thenReturn(true); - command = ListCollaboratorsCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => ListCollaboratorsCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), )..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/init_command_test.dart b/packages/shorebird_cli/test/src/commands/init_command_test.dart index e639af04..5c5724f2 100644 --- a/packages/shorebird_cli/test/src/commands/init_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/init_command_test.dart @@ -33,7 +33,7 @@ class _MockProcessResult extends Mock implements ShorebirdProcessResult {} class _MockPlatform extends Mock implements Platform {} void main() { - group('init', () { + group(InitCommand, () { const version = '1.2.3'; const appId = 'test_app_id'; const appName = 'test_app_name'; @@ -56,7 +56,13 @@ environment: late InitCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } Directory setUpAppTempDir() { @@ -106,14 +112,15 @@ environment: when(() => result.exitCode).thenReturn(ExitCode.success.code); when(() => result.stdout).thenReturn(''); - command = InitCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => InitCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), ) ..testProcess = process ..testArgResults = argResults; diff --git a/packages/shorebird_cli/test/src/commands/login_command_test.dart b/packages/shorebird_cli/test/src/commands/login_command_test.dart index 2369dde2..e6bcc4cb 100644 --- a/packages/shorebird_cli/test/src/commands/login_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/login_command_test.dart @@ -17,7 +17,7 @@ class _MockHttpClient extends Mock implements http.Client {} class _MockLogger extends Mock implements Logger {} void main() { - group('login', () { + group(LoginCommand, () { const email = 'test@email.com'; late Auth auth; @@ -27,7 +27,13 @@ void main() { late LoginCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -41,7 +47,7 @@ void main() { p.join(applicationConfigHome.path, 'credentials.json'), ); - command = LoginCommand(auth: auth); + command = runWithOverrides(LoginCommand.new); }); test('exits with code 0 when already logged in', () async { diff --git a/packages/shorebird_cli/test/src/commands/logout_command_test.dart b/packages/shorebird_cli/test/src/commands/logout_command_test.dart index 211a4d8e..4d0d1c4d 100644 --- a/packages/shorebird_cli/test/src/commands/logout_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/logout_command_test.dart @@ -16,14 +16,20 @@ class _MockHttpClient extends Mock implements http.Client {} class _MockProgress extends Mock implements Progress {} void main() { - group('logout', () { + group(LogoutCommand, () { late Auth auth; late Logger logger; late http.Client httpClient; late LogoutCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -34,7 +40,7 @@ void main() { when(() => auth.client).thenReturn(httpClient); when(() => logger.progress(any())).thenReturn(_MockProgress()); - command = LogoutCommand(auth: auth); + command = runWithOverrides(LogoutCommand.new); }); test('exits with code 0 when already logged out', () async { diff --git a/packages/shorebird_cli/test/src/commands/patch/patch_aar_command_test.dart b/packages/shorebird_cli/test/src/commands/patch/patch_aar_command_test.dart index 9f1b80b9..6efdf561 100644 --- a/packages/shorebird_cli/test/src/commands/patch/patch_aar_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/patch/patch_aar_command_test.dart @@ -12,6 +12,7 @@ import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/cache.dart' show Cache; import 'package:shorebird_cli/src/commands/commands.dart'; import 'package:shorebird_cli/src/logger.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; @@ -57,7 +58,7 @@ void main() { const versionCode = '1'; const version = '$versionName+$versionCode'; const arch = 'aarch64'; - const platform = 'android'; + const platformName = 'android'; const channelName = 'stable'; const appDisplayName = 'Test App'; const appMetadata = AppMetadata(appId: appId, displayName: appDisplayName); @@ -65,7 +66,7 @@ void main() { id: 0, patchId: 0, arch: arch, - platform: platform, + platform: platformName, hash: '#', size: 42, url: 'https://example.com', @@ -74,7 +75,7 @@ void main() { id: 0, releaseId: 0, arch: arch, - platform: platform, + platform: platformName, hash: '#', size: 42, url: 'https://example.com/release.so', @@ -83,7 +84,7 @@ void main() { id: 0, releaseId: 0, arch: arch, - platform: platform, + platform: platformName, hash: '#', size: 42, url: 'https://example.com/release.aar', @@ -125,7 +126,7 @@ flutter: late ArgResults argResults; late Auth auth; late Directory shorebirdRoot; - late Platform environmentPlatform; + late Platform platform; late Progress progress; late Logger logger; late ShorebirdProcessResult flutterBuildProcessResult; @@ -140,7 +141,14 @@ flutter: late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger), + platformRef.overrideWith(() => platform), + }, + ); } Directory setUpTempDir({bool includeModule = true}) { @@ -193,7 +201,7 @@ flutter: argResults = _MockArgResults(); auth = _MockAuth(); shorebirdRoot = Directory.systemTemp.createTempSync(); - environmentPlatform = _MockPlatform(); + platform = _MockPlatform(); progress = _MockProgress(); logger = _MockLogger(); flutterBuildProcessResult = _MockProcessResult(); @@ -205,8 +213,8 @@ flutter: cache = _MockCache(); shorebirdProcess = _MockShorebirdProcess(); - ShorebirdEnvironment.platform = environmentPlatform; - when(() => environmentPlatform.script).thenReturn( + when(() => platform.environment).thenReturn({}); + when(() => platform.script).thenReturn( Uri.file( p.join( shorebirdRoot.path, @@ -328,20 +336,21 @@ flutter: () => cache.getArtifactDirectory(any()), ).thenReturn(Directory.systemTemp.createTempSync()); - command = PatchAarCommand( - aarDiffer: aarDiffer, - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - capturedHostedUri = hostedUri; - return codePushClient; - }, - cache: cache, - httpClient: httpClient, - validators: [flutterValidator], - unzipFn: (_, __) async {}, + command = runWithOverrides( + () => PatchAarCommand( + aarDiffer: aarDiffer, + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + capturedHostedUri = hostedUri; + return codePushClient; + }, + cache: cache, + httpClient: httpClient, + validators: [flutterValidator], + unzipFn: (_, __) async {}, + ), ) ..testArgResults = argResults ..testProcess = shorebirdProcess @@ -471,13 +480,16 @@ Did you forget to run "shorebird init"?''', const otherRevision = 'other-revision'; when(() => flutterRevisionProcessResult.stdout).thenReturn(otherRevision); final tempDir = setUpTempDir(); + final flutterDir = + runWithOverrides(() => ShorebirdEnvironment.flutterDirectory.path); setUpTempArtifacts(tempDir); + final exitCode = await IOOverrides.runZoned( () => runWithOverrides(command.run), getCurrentDirectory: () => tempDir, ); + expect(exitCode, ExitCode.software.code); - final shorebirdFlutterPath = ShorebirdEnvironment.flutterDirectory.path; verify( () => logger.err(''' Flutter revision mismatch. @@ -494,7 +506,7 @@ Either create a new release using: ${lightCyan.wrap('shorebird release aar')} Or downgrade your Flutter version and try again using: - ${lightCyan.wrap('cd $shorebirdFlutterPath')} + ${lightCyan.wrap('cd $flutterDir')} ${lightCyan.wrap('git checkout ${release.flutterRevision}')} Shorebird plans to support this automatically, let us know if it's important to you: @@ -875,7 +887,7 @@ Please create a release using "shorebird release aar" and try again. () => logger.info( any( that: contains( - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('[arm64 (4 B), arm32 (4 B), x86_64 (4 B)]')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('[arm64 (4 B), arm32 (4 B), x86_64 (4 B)]')}''', ), ), ), diff --git a/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart b/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart index 63105d90..42017c80 100644 --- a/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart @@ -13,6 +13,7 @@ import 'package:shorebird_cli/src/cache.dart' show Cache; import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/commands/patch/patch_android_command.dart'; import 'package:shorebird_cli/src/logger.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; @@ -58,7 +59,7 @@ void main() { const versionCode = '1'; const version = '$versionName+$versionCode'; const arch = 'aarch64'; - const platform = 'android'; + const platformName = 'android'; const channelName = 'stable'; const appDisplayName = 'Test App'; const app = AppMetadata(appId: appId, displayName: appDisplayName); @@ -66,7 +67,7 @@ void main() { id: 0, releaseId: 0, arch: arch, - platform: platform, + platform: platformName, hash: '#', size: 42, url: 'https://example.com', @@ -75,7 +76,7 @@ void main() { id: 0, releaseId: 0, arch: arch, - platform: platform, + platform: platformName, hash: '#', size: 42, url: 'https://example.com/release.aab', @@ -102,7 +103,7 @@ flutter: late Auth auth; late CodePushClientWrapper codePushClientWrapper; late Directory shorebirdRoot; - late Platform environmentPlatform; + late Platform platform; late Progress progress; late Logger logger; late ShorebirdProcessResult flutterBuildProcessResult; @@ -117,7 +118,15 @@ flutter: late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger), + platformRef.overrideWith(() => platform), + codePushClientWrapperRef.overrideWith(() => codePushClientWrapper), + }, + ); } Directory setUpTempDir() { @@ -161,7 +170,7 @@ flutter: auth = _MockAuth(); codePushClientWrapper = _MockCodePushClientWrapper(); shorebirdRoot = Directory.systemTemp.createTempSync(); - environmentPlatform = _MockPlatform(); + platform = _MockPlatform(); progress = _MockProgress(); logger = _MockLogger(); flutterBuildProcessResult = _MockProcessResult(); @@ -173,20 +182,19 @@ flutter: flutterValidator = _MockShorebirdFlutterValidator(); cache = _MockCache(); shorebirdProcess = _MockShorebirdProcess(); - command = PatchAndroidCommand( - aabDiffer: aabDiffer, - auth: auth, - codePushClientWrapper: codePushClientWrapper, - cache: cache, - httpClient: httpClient, - validators: [flutterValidator], + command = runWithOverrides( + () => PatchAndroidCommand( + aabDiffer: aabDiffer, + cache: cache, + httpClient: httpClient, + validators: [flutterValidator], + ), ) ..testArgResults = argResults ..testProcess = shorebirdProcess ..testEngineConfig = const EngineConfig.empty(); - ShorebirdEnvironment.platform = environmentPlatform; - when(() => environmentPlatform.script).thenReturn( + when(() => platform.script).thenReturn( Uri.file( p.join( shorebirdRoot.path, @@ -421,7 +429,9 @@ flutter: getCurrentDirectory: () => tempDir, ); expect(exitCode, ExitCode.software.code); - final shorebirdFlutterPath = ShorebirdEnvironment.flutterDirectory.path; + final shorebirdFlutterPath = runWithOverrides( + () => ShorebirdEnvironment.flutterDirectory.path, + ); verify( () => logger.err(''' Flutter revision mismatch. @@ -723,7 +733,7 @@ https://github.com/shorebirdtech/shorebird/issues/472 () => logger.info( any( that: contains( - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('[arm32 (4 B), arm64 (4 B), x86_64 (4 B)]')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('[arm32 (4 B), arm64 (4 B), x86_64 (4 B)]')}''', ), ), ), diff --git a/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart b/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart index 001a6fdc..b7a2d562 100644 --- a/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart @@ -5,6 +5,7 @@ import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; +import 'package:platform/platform.dart'; import 'package:propertylistserialization/propertylistserialization.dart'; import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/archive_analysis/archive_analysis.dart'; @@ -12,8 +13,10 @@ import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/commands/patch/patch.dart'; import 'package:shorebird_cli/src/logger.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_environment.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_cli/src/validators/validators.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; import 'package:test/test.dart'; @@ -33,6 +36,8 @@ class _MockIpa extends Mock implements Ipa {} class _MockLogger extends Mock implements Logger {} +class _MockPlatform extends Mock implements Platform {} + class _MockProgress extends Mock implements Progress {} class _MockProcessResult extends Mock implements ShorebirdProcessResult {} @@ -54,7 +59,7 @@ void main() { const version = '$versionName+$versionCode'; const arch = 'aarch64'; const appDisplayName = 'Test App'; - const platform = 'ios'; + const platformName = 'ios'; const elfAotSnapshotFileName = 'out.aot'; const pubspecYamlContent = ''' name: example @@ -83,6 +88,7 @@ flutter: late IpaReader ipaReader; late Progress progress; late Logger logger; + late Platform platform; late ShorebirdProcessResult aotBuildProcessResult; late ShorebirdProcessResult flutterBuildProcessResult; late ShorebirdProcessResult flutterRevisionProcessResult; @@ -92,7 +98,15 @@ flutter: late PatchIosCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger), + platformRef.overrideWith(() => platform), + codePushClientWrapperRef.overrideWith(() => codePushClientWrapper), + }, + ); } Directory setUpTempDir() { @@ -138,6 +152,7 @@ flutter: ipa = _MockIpa(); progress = _MockProgress(); logger = _MockLogger(); + platform = _MockPlatform(); aotBuildProcessResult = _MockProcessResult(); flutterBuildProcessResult = _MockProcessResult(); flutterRevisionProcessResult = _MockProcessResult(); @@ -174,6 +189,17 @@ flutter: when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); when(() => logger.confirm(any())).thenReturn(true); when(() => logger.progress(any())).thenReturn(progress); + when(() => platform.environment).thenReturn({}); + when(() => platform.script).thenReturn( + Uri.file( + p.join( + Directory.systemTemp.createTempSync().path, + 'bin', + 'cache', + 'shorebird.snapshot', + ), + ), + ); when(() => aotBuildProcessResult.exitCode) .thenReturn(ExitCode.success.code); when(() => flutterBuildProcessResult.exitCode) @@ -206,11 +232,11 @@ flutter: ), ).thenAnswer((_) async => aotBuildProcessResult); - command = PatchIosCommand( - auth: auth, - codePushClientWrapper: codePushClientWrapper, - ipaReader: ipaReader, - validators: [flutterValidator], + command = runWithOverrides( + () => PatchIosCommand( + ipaReader: ipaReader, + validators: [flutterValidator], + ), ) ..testArgResults = argResults ..testProcess = shorebirdProcess @@ -303,7 +329,9 @@ flutter: getCurrentDirectory: () => tempDir, ); expect(exitCode, ExitCode.software.code); - final shorebirdFlutterPath = ShorebirdEnvironment.flutterDirectory.path; + final shorebirdFlutterPath = runWithOverrides( + () => ShorebirdEnvironment.flutterDirectory.path, + ); verify( () => logger.err(''' Flutter revision mismatch. @@ -426,7 +454,7 @@ https://github.com/shorebirdtech/shorebird/issues/472 () => logger.info( any( that: contains( - '''🕹️ Platform: ${lightCyan.wrap(platform)} ${lightCyan.wrap('[aarch64 (0 B)]')}''', + '''🕹️ Platform: ${lightCyan.wrap(platformName)} ${lightCyan.wrap('[aarch64 (0 B)]')}''', ), ), ), diff --git a/packages/shorebird_cli/test/src/commands/release/release_aar_command_test.dart b/packages/shorebird_cli/test/src/commands/release/release_aar_command_test.dart index 698aa34e..2d7fb907 100644 --- a/packages/shorebird_cli/test/src/commands/release/release_aar_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/release/release_aar_command_test.dart @@ -54,12 +54,12 @@ void main() { ); const arch = 'aarch64'; - const platform = 'android'; + const platformName = 'android'; const releaseArtifact = ReleaseArtifact( id: 0, releaseId: 0, arch: arch, - platform: platform, + platform: platformName, hash: '#', size: 42, url: 'https://example.com', @@ -104,7 +104,13 @@ flutter: late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } Directory setUpTempDir({bool includeModule = true}) { @@ -222,17 +228,18 @@ flutter: when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); - command = ReleaseAarCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - capturedHostedUri = hostedUri; - return codePushClient; - }, - unzipFn: (_, __) async {}, - validators: [flutterValidator], + command = runWithOverrides( + () => ReleaseAarCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + capturedHostedUri = hostedUri; + return codePushClient; + }, + unzipFn: (_, __) async {}, + validators: [flutterValidator], + ), ) ..testArgResults = argResults ..testProcess = shorebirdProcess diff --git a/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart b/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart index 0db169ca..1568d596 100644 --- a/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart @@ -12,7 +12,7 @@ import 'package:shorebird_cli/src/cache.dart'; import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/commands/commands.dart'; import 'package:shorebird_cli/src/logger.dart'; -import 'package:shorebird_cli/src/shorebird_environment.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; import 'package:shorebird_cli/src/validators/validators.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -51,7 +51,7 @@ void main() { const version = '$versionName+$versionCode'; const appDisplayName = 'Test App'; const arch = 'aarch64'; - const platform = 'android'; + const platformName = 'android'; const appMetadata = AppMetadata(appId: appId, displayName: appDisplayName); const release = Release( id: 0, @@ -75,7 +75,7 @@ flutter: late http.Client httpClient; late CodePushClientWrapper codePushClientWrapper; late Directory shorebirdRoot; - late Platform environmentPlatform; + late Platform platform; late Auth auth; late Cache cache; late Progress progress; @@ -89,7 +89,15 @@ flutter: late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger), + platformRef.overrideWith(() => platform), + codePushClientWrapperRef.overrideWith(() => codePushClientWrapper), + }, + ); } Directory setUpTempDir() { @@ -107,7 +115,7 @@ flutter: argResults = _MockArgResults(); codePushClientWrapper = _MockCodePushClientWrapper(); httpClient = _MockHttpClient(); - environmentPlatform = _MockPlatform(); + platform = _MockPlatform(); shorebirdRoot = Directory.systemTemp.createTempSync(); auth = _MockAuth(); cache = _MockCache(); @@ -122,8 +130,7 @@ flutter: registerFallbackValue(shorebirdProcess); - ShorebirdEnvironment.platform = environmentPlatform; - when(() => environmentPlatform.script).thenReturn( + when(() => platform.script).thenReturn( Uri.file( p.join( shorebirdRoot.path, @@ -163,7 +170,7 @@ flutter: }); when(() => argResults.rest).thenReturn([]); when(() => argResults['arch']).thenReturn(arch); - when(() => argResults['platform']).thenReturn(platform); + when(() => argResults['platform']).thenReturn(platformName); when(() => auth.isAuthenticated).thenReturn(true); when(() => auth.client).thenReturn(httpClient); when(() => cache.updateAll()).thenAnswer((_) async => {}); @@ -223,11 +230,11 @@ flutter: ).thenAnswer((_) async {}); when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); - command = ReleaseAndroidCommand( - auth: auth, - codePushClientWrapper: codePushClientWrapper, - cache: cache, - validators: [flutterValidator], + command = runWithOverrides( + () => ReleaseAndroidCommand( + cache: cache, + validators: [flutterValidator], + ), ) ..testArgResults = argResults ..testProcess = shorebirdProcess @@ -423,7 +430,7 @@ Please bump your version number and try again.'''), verify( () => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: release.id, - platform: platform, + platform: platformName, aabPath: any(named: 'aabPath'), architectures: any(named: 'architectures'), ), @@ -455,7 +462,7 @@ flavors: verify( () => codePushClientWrapper.createAndroidReleaseArtifacts( releaseId: release.id, - platform: platform, + platform: platformName, aabPath: any(named: 'aabPath'), architectures: any(named: 'architectures'), flavor: flavor, diff --git a/packages/shorebird_cli/test/src/commands/release/release_ios_command_test.dart b/packages/shorebird_cli/test/src/commands/release/release_ios_command_test.dart index 5374bfb8..2df4ea54 100644 --- a/packages/shorebird_cli/test/src/commands/release/release_ios_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/release/release_ios_command_test.dart @@ -13,7 +13,7 @@ import 'package:shorebird_cli/src/auth/auth.dart'; import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/commands/commands.dart'; import 'package:shorebird_cli/src/logger.dart'; -import 'package:shorebird_cli/src/shorebird_environment.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; import 'package:shorebird_cli/src/validators/validators.dart'; import 'package:shorebird_code_push_client/shorebird_code_push_client.dart'; @@ -54,7 +54,7 @@ void main() { const version = '$versionName+$versionCode'; const appDisplayName = 'Test App'; const arch = 'armv7'; - const platform = 'ios'; + const platformName = 'ios'; const appMetadata = AppMetadata(appId: appId, displayName: appDisplayName); const release = Release( id: 0, @@ -91,7 +91,15 @@ flutter: late ShorebirdProcess shorebirdProcess; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger), + platformRef.overrideWith(() => environmentPlatform), + codePushClientWrapperRef.overrideWith(() => codePushClientWrapper), + }, + ); } Directory setUpTempDir() { @@ -124,7 +132,6 @@ flutter: registerFallbackValue(shorebirdProcess); - ShorebirdEnvironment.platform = environmentPlatform; when(() => environmentPlatform.script).thenReturn( Uri.file( p.join( @@ -152,7 +159,7 @@ flutter: ).thenAnswer((_) async => flutterRevisionProcessResult); when(() => argResults.rest).thenReturn([]); when(() => argResults['arch']).thenReturn(arch); - when(() => argResults['platform']).thenReturn(platform); + when(() => argResults['platform']).thenReturn(platformName); when(() => auth.isAuthenticated).thenReturn(true); when(() => auth.client).thenReturn(httpClient); when(() => ipaReader.read(any())).thenReturn(ipa); @@ -189,11 +196,11 @@ flutter: ).thenAnswer((_) async => release); when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); - command = ReleaseIosCommand( - auth: auth, - codePushClientWrapper: codePushClientWrapper, - ipaReader: ipaReader, - validators: [flutterValidator], + command = runWithOverrides( + () => ReleaseIosCommand( + ipaReader: ipaReader, + validators: [flutterValidator], + ), ) ..testArgResults = argResults ..testProcess = shorebirdProcess diff --git a/packages/shorebird_cli/test/src/commands/releases/delete_releases_command_test.dart b/packages/shorebird_cli/test/src/commands/releases/delete_releases_command_test.dart index 16bef069..5acd1a9f 100644 --- a/packages/shorebird_cli/test/src/commands/releases/delete_releases_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/releases/delete_releases_command_test.dart @@ -50,7 +50,13 @@ flutter: late DeleteReleasesCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } Directory setUpTempDir() { @@ -107,14 +113,15 @@ flutter: when(() => logger.confirm(any())).thenReturn(true); when(() => logger.progress(any())).thenReturn(progress); - command = DeleteReleasesCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, + command = runWithOverrides( + () => DeleteReleasesCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), )..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/releases/list_releases_command_test.dart b/packages/shorebird_cli/test/src/commands/releases/list_releases_command_test.dart index 627747c1..9ebc4a3f 100644 --- a/packages/shorebird_cli/test/src/commands/releases/list_releases_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/releases/list_releases_command_test.dart @@ -45,7 +45,13 @@ flutter: - shorebird.yaml'''; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } Directory setUpTempDir() { @@ -69,13 +75,12 @@ flutter: when(() => auth.client).thenReturn(httpClient); when(() => auth.isAuthenticated).thenReturn(true); - command = ListReleasesCommand( - auth: auth, - buildCodePushClient: ({ - required httpClient, - hostedUri, - }) => - codePushClient, + command = runWithOverrides( + () => ListReleasesCommand( + buildCodePushClient: ({required httpClient, hostedUri}) { + return codePushClient; + }, + ), )..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/run_command_test.dart b/packages/shorebird_cli/test/src/commands/run_command_test.dart index d677042c..b6828d58 100644 --- a/packages/shorebird_cli/test/src/commands/run_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/run_command_test.dart @@ -51,7 +51,13 @@ void main() { late RunCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -84,18 +90,19 @@ void main() { ).thenAnswer((_) async => []); when(() => flutterValidator.validate(any())).thenAnswer((_) async => []); - command = RunCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) { - return codePushClient; - }, - validators: [ - androidInternetPermissionValidator, - flutterValidator, - ], + command = runWithOverrides( + () => RunCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + validators: [ + androidInternetPermissionValidator, + flutterValidator, + ], + ), ) ..testArgResults = argResults ..testProcess = shorebirdProcess diff --git a/packages/shorebird_cli/test/src/commands/subscription/cancel_subscription_command_test.dart b/packages/shorebird_cli/test/src/commands/subscription/cancel_subscription_command_test.dart index 452fa8f3..27707505 100644 --- a/packages/shorebird_cli/test/src/commands/subscription/cancel_subscription_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/subscription/cancel_subscription_command_test.dart @@ -19,7 +19,7 @@ class _MockLogger extends Mock implements Logger {} class _MockProgress extends Mock implements Progress {} void main() { - group('CancelSubscriptionCommand', () { + group(CancelSubscriptionCommand, () { const noSubscriptionUser = User(id: 1, email: 'tester1@shorebird.dev'); const subscriptionUser = User( id: 2, @@ -35,7 +35,13 @@ void main() { late CancelSubscriptionCommand command; R runWithOverrides(R Function() body) { - return runScoped(body, values: {loggerRef.overrideWith(() => logger)}); + return runScoped( + body, + values: { + authRef.overrideWith(() => auth), + loggerRef.overrideWith(() => logger) + }, + ); } setUp(() { @@ -49,13 +55,15 @@ void main() { when(() => logger.progress(any())).thenReturn(progress); - command = CancelSubscriptionCommand( - auth: auth, - buildCodePushClient: ({ - required http.Client httpClient, - Uri? hostedUri, - }) => - codePushClient, + command = runWithOverrides( + () => CancelSubscriptionCommand( + buildCodePushClient: ({ + required http.Client httpClient, + Uri? hostedUri, + }) { + return codePushClient; + }, + ), ); }); diff --git a/packages/shorebird_cli/test/src/shorebird_environment_test.dart b/packages/shorebird_cli/test/src/shorebird_environment_test.dart index e32a269d..8f948be8 100644 --- a/packages/shorebird_cli/test/src/shorebird_environment_test.dart +++ b/packages/shorebird_cli/test/src/shorebird_environment_test.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; import 'package:platform/platform.dart'; +import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:test/test.dart'; @@ -14,14 +16,23 @@ void main() { late Directory shorebirdRoot; late Uri platformScript; + R runWithOverrides(R Function() body) { + return runScoped( + () => body(), + values: { + platformRef.overrideWith(() => platform), + }, + ); + } + setUp(() { shorebirdRoot = Directory.systemTemp.createTempSync(); platformScript = Uri.file( p.join(shorebirdRoot.path, 'bin', 'cache', 'shorebird.snapshot'), ); platform = _MockPlatform(); - ShorebirdEnvironment.platform = platform; + when(() => platform.environment).thenReturn(const {}); when(() => platform.script).thenReturn(platformScript); }); @@ -31,7 +42,10 @@ void main() { File(p.join(shorebirdRoot.path, 'bin', 'internal', 'flutter.version')) ..createSync(recursive: true) ..writeAsStringSync(revision, flush: true); - expect(ShorebirdEnvironment.flutterRevision, equals(revision)); + expect( + runWithOverrides(() => ShorebirdEnvironment.flutterRevision), + equals(revision), + ); }); test('trims revision file content', () { @@ -45,7 +59,10 @@ test-revision ..createSync(recursive: true) ..writeAsStringSync(revision, flush: true); - expect(ShorebirdEnvironment.flutterRevision, 'test-revision'); + expect( + runWithOverrides(() => ShorebirdEnvironment.flutterRevision), + 'test-revision', + ); }); }); @@ -65,7 +82,40 @@ test-revision ) ..createSync(recursive: true) ..writeAsStringSync(revision, flush: true); - expect(ShorebirdEnvironment.shorebirdEngineRevision, equals(revision)); + expect( + runWithOverrides(() => ShorebirdEnvironment.shorebirdEngineRevision), + equals(revision), + ); + }); + }); + + group('hostedUrl', () { + test('returns hosted url from env if available', () { + when(() => platform.environment).thenReturn({ + 'SHOREBIRD_HOSTED_URL': 'https://example.com', + }); + expect( + runWithOverrides(() => ShorebirdEnvironment.hostedUri), + equals(Uri.parse('https://example.com')), + ); + }); + + test('falls back to shorebird.yaml', () { + final directory = Directory.systemTemp.createTempSync(); + File(p.join(directory.path, 'shorebird.yaml')).writeAsStringSync(''' +app_id: test-id +base_url: https://example.com'''); + expect( + IOOverrides.runZoned( + () => runWithOverrides(() => ShorebirdEnvironment.hostedUri), + getCurrentDirectory: () => directory, + ), + equals(Uri.parse('https://example.com')), + ); + }); + + test('returns null when there is no env override or shorebird.yaml', () { + expect(runWithOverrides(() => ShorebirdEnvironment.hostedUri), isNull); }); }); }); diff --git a/packages/shorebird_cli/test/src/validators/shorebird_flutter_validator_test.dart b/packages/shorebird_cli/test/src/validators/shorebird_flutter_validator_test.dart index 35c85164..0cfe35a7 100644 --- a/packages/shorebird_cli/test/src/validators/shorebird_flutter_validator_test.dart +++ b/packages/shorebird_cli/test/src/validators/shorebird_flutter_validator_test.dart @@ -3,6 +3,8 @@ import 'dart:io' hide Platform; import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; import 'package:platform/platform.dart'; +import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/shorebird_environment.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; import 'package:shorebird_cli/src/validators/validators.dart'; @@ -42,6 +44,16 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 late ShorebirdProcessResult shorebirdFlutterVersionProcessResult; late ShorebirdProcessResult gitStatusProcessResult; late ShorebirdProcess shorebirdProcess; + late Platform platform; + + R runWithOverrides(R Function() body) { + return runScoped( + () => body(), + values: { + platformRef.overrideWith(() => platform), + }, + ); + } Directory flutterDirectory(Directory root) => Directory(p.join(root.path, 'bin', 'cache', 'flutter')); @@ -58,12 +70,11 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 setUp(() { tempDir = setupTempDirectory(); + platform = _MockPlatform(); - ShorebirdEnvironment.platform = _MockPlatform(); ShorebirdEnvironment.flutterRevision = flutterRevision; - when(() => ShorebirdEnvironment.platform.script) - .thenReturn(shorebirdScriptFile(tempDir).uri); - when(() => ShorebirdEnvironment.platform.environment).thenReturn({}); + when(() => platform.script).thenReturn(shorebirdScriptFile(tempDir).uri); + when(() => platform.environment).thenReturn({}); pathFlutterVersionProcessResult = _MockProcessResult(); shorebirdFlutterVersionProcessResult = _MockProcessResult(); @@ -106,7 +117,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 }); test('returns no issues when the Flutter install is good', () async { - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, isEmpty); }); @@ -125,7 +138,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 when(() => gitStatusProcessResult.stdout) .thenReturn('Changes not staged for commit'); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, hasLength(1)); expect(results.first.severity, ValidationIssueSeverity.warning); @@ -140,7 +155,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 pathFlutterVersionMessage.replaceAll('3.7.9', '3.7.10'), ); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, isEmpty); }, @@ -154,7 +171,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 pathFlutterVersionMessage.replaceAll('3.7.9', '3.8.9'), ); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, hasLength(1)); expect(results.first.severity, ValidationIssueSeverity.warning); @@ -171,11 +190,13 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 test( 'warns if FLUTTER_STORAGE_BASE_URL has a non-empty value', () async { - when(() => ShorebirdEnvironment.platform.environment).thenReturn( + when(() => platform.environment).thenReturn( {'FLUTTER_STORAGE_BASE_URL': 'https://storage.flutter-io.cn'}, ); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, hasLength(1)); expect(results.first.severity, ValidationIssueSeverity.warning); @@ -194,7 +215,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 when(() => pathFlutterVersionProcessResult.stdout) .thenReturn('OH NO THERE IS NO FLUTTER VERSION HERE'); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, hasLength(1)); expect( @@ -213,7 +236,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 when(() => pathFlutterVersionProcessResult.stderr) .thenReturn('error getting Flutter version'); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, hasLength(1)); expect( @@ -231,7 +256,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 when(() => shorebirdFlutterVersionProcessResult.stdout) .thenReturn('OH NO THERE IS NO FLUTTER VERSION HERE'); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, hasLength(1)); expect( @@ -250,7 +277,9 @@ Tools • Dart 2.19.6 • DevTools 2.20.1 when(() => shorebirdFlutterVersionProcessResult.stderr) .thenReturn('error getting Flutter version'); - final results = await validator.validate(shorebirdProcess); + final results = await runWithOverrides( + () => validator.validate(shorebirdProcess), + ); expect(results, hasLength(1)); expect(