refactor(shorebird_cli): use scoped auth (#662)
Co-authored-by: Bryan Oltman <bryanoltman@gmail.com>
This commit is contained in:
@@ -49,7 +49,7 @@ T read<T>(ScopedRef<T> 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})?''',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<void> main(List<String> args) async {
|
||||
await _flushThenExit(
|
||||
await runScoped(
|
||||
() async => ShorebirdCliCommandRunner().run(args),
|
||||
values: {loggerRef, platformRef},
|
||||
values: {
|
||||
authRef,
|
||||
loggerRef,
|
||||
platformRef,
|
||||
codePushClientWrapperRef,
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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<CodePushClientWrapper> 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.
|
||||
|
||||
@@ -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<Validator> _defaultValidators() => [
|
||||
|
||||
abstract class ShorebirdCommand extends Command<int> {
|
||||
ShorebirdCommand({
|
||||
Auth? auth,
|
||||
Cache? cache,
|
||||
CodePushClientBuilder? buildCodePushClient,
|
||||
CodePushClientWrapper? codePushClientWrapper,
|
||||
List<Validator>? 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<int> {
|
||||
|
||||
/// [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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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.';
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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: '''
|
||||
|
||||
@@ -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?');
|
||||
|
||||
@@ -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<AppMetadata> apps;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
+6
-3
@@ -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(
|
||||
'''
|
||||
|
||||
+6
-3
@@ -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(
|
||||
'''
|
||||
|
||||
+6
-3
@@ -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(
|
||||
'''
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 = <Arch, String>{};
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<App> 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 (_) {
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
@@ -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('''
|
||||
|
||||
@@ -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<Release> releases;
|
||||
|
||||
@@ -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<Release> releases;
|
||||
|
||||
@@ -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',
|
||||
|
||||
+4
-2
@@ -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;
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
|
||||
// A reference to a [Logger] instance.
|
||||
ScopedRef<Logger> loggerRef = create(Logger.new);
|
||||
final loggerRef = create(Logger.new);
|
||||
|
||||
// The [Logger] instance available in the current zone.
|
||||
Logger get logger => read(loggerRef);
|
||||
|
||||
@@ -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<App?> getApp({required String appId, String? flavor}) async {
|
||||
final codePushClient = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: hostedUri,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final List<App> 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<Release> releases;
|
||||
@@ -100,7 +102,7 @@ mixin ShorebirdCodePushClientMixin on ShorebirdConfigMixin {
|
||||
}) async {
|
||||
final codePushClient = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: hostedUri,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final releaseArtifacts = <Arch, ReleaseArtifact>{};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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''';
|
||||
|
||||
@@ -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>(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(
|
||||
|
||||
@@ -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<ProcessExit>().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);
|
||||
|
||||
@@ -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>(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 {
|
||||
|
||||
@@ -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>(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);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -29,7 +29,13 @@ void main() {
|
||||
late CreateAccountCommand createAccountCommand;
|
||||
|
||||
R runWithOverrides<R>(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', () {
|
||||
|
||||
+13
-5
@@ -34,7 +34,13 @@ void main() {
|
||||
|
||||
group(SubscribeAccountCommand, () {
|
||||
R runWithOverrides<R>(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;
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -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>(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;
|
||||
});
|
||||
|
||||
|
||||
@@ -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>(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;
|
||||
});
|
||||
|
||||
|
||||
@@ -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>(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;
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -64,7 +64,13 @@ flutter:
|
||||
late BuildAarCommand command;
|
||||
|
||||
R runWithOverrides<R>(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();
|
||||
|
||||
@@ -42,7 +42,13 @@ void main() {
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
|
||||
R runWithOverrides<R>(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
|
||||
|
||||
@@ -42,7 +42,13 @@ void main() {
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
|
||||
R runWithOverrides<R>(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
|
||||
|
||||
@@ -43,7 +43,13 @@ void main() {
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
|
||||
R runWithOverrides<R>(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
|
||||
|
||||
+17
-10
@@ -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>(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;
|
||||
});
|
||||
|
||||
|
||||
+17
-10
@@ -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>(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;
|
||||
});
|
||||
|
||||
|
||||
+17
-10
@@ -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>(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;
|
||||
});
|
||||
|
||||
|
||||
@@ -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>(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;
|
||||
|
||||
@@ -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>(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 {
|
||||
|
||||
@@ -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>(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 {
|
||||
|
||||
@@ -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>(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)]')}''',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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>(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)]')}''',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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>(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)]')}''',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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>(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
|
||||
|
||||
+22
-15
@@ -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>(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,
|
||||
|
||||
@@ -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>(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
|
||||
|
||||
+16
-9
@@ -50,7 +50,13 @@ flutter:
|
||||
late DeleteReleasesCommand command;
|
||||
|
||||
R runWithOverrides<R>(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;
|
||||
});
|
||||
|
||||
|
||||
@@ -45,7 +45,13 @@ flutter:
|
||||
- shorebird.yaml''';
|
||||
|
||||
R runWithOverrides<R>(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;
|
||||
});
|
||||
|
||||
|
||||
@@ -51,7 +51,13 @@ void main() {
|
||||
late RunCommand command;
|
||||
|
||||
R runWithOverrides<R>(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
|
||||
|
||||
+17
-9
@@ -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>(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;
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -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>(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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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>(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(
|
||||
|
||||
Reference in New Issue
Block a user