refactor(shorebird_cli): use scoped ShorebirdEnv and remove buildCodePushClient (#1005)
This commit is contained in:
@@ -16,6 +16,7 @@ import 'package:shorebird_cli/src/java.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_cli/src/xcodebuild.dart';
|
||||
@@ -40,6 +41,7 @@ Future<void> main(List<String> args) async {
|
||||
loggerRef,
|
||||
platformRef,
|
||||
processRef,
|
||||
shorebirdEnvRef,
|
||||
shorebirdValidatorRef,
|
||||
shorebirdVersionManagerRef,
|
||||
xcodeBuildRef,
|
||||
|
||||
@@ -7,7 +7,8 @@ import 'package:path/path.dart' as p;
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/http_client/http_client.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
|
||||
typedef ArchiveExtracter = Future<void> Function(
|
||||
String archivePath,
|
||||
@@ -32,7 +33,6 @@ class Cache {
|
||||
Cache({
|
||||
http.Client? httpClient,
|
||||
this.extractArchive = _defaultArchiveExtractor,
|
||||
Platform platform = const LocalPlatform(),
|
||||
}) : httpClient = httpClient ?? retryingHttpClient(http.Client()) {
|
||||
registerArtifact(PatchArtifact(cache: this, platform: platform));
|
||||
registerArtifact(BundleToolArtifact(cache: this, platform: platform));
|
||||
@@ -72,7 +72,7 @@ class Cache {
|
||||
/// The Shorebird cache directory.
|
||||
static Directory get shorebirdCacheDirectory {
|
||||
return Directory(
|
||||
p.join(ShorebirdEnvironment.shorebirdRoot.path, 'bin', 'cache'),
|
||||
p.join(shorebirdEnv.shorebirdRoot.path, 'bin', 'cache'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ class PatchArtifact extends CachedArtifact {
|
||||
artifactName += 'windows-x64.zip';
|
||||
}
|
||||
|
||||
return '${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/${ShorebirdEnvironment.shorebirdEngineRevision}/$artifactName';
|
||||
return '${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/${shorebirdEnv.shorebirdEngineRevision}/$artifactName';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ 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/shorebird_env.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';
|
||||
|
||||
@@ -44,7 +44,7 @@ ScopedRef<CodePushClientWrapper> codePushClientWrapperRef = create(() {
|
||||
return CodePushClientWrapper(
|
||||
codePushClient: CodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
hostedUri: shorebirdEnv.hostedUri,
|
||||
),
|
||||
);
|
||||
});
|
||||
@@ -63,6 +63,25 @@ class CodePushClientWrapper {
|
||||
|
||||
final CodePushClient codePushClient;
|
||||
|
||||
Future<App> createApp({String? appName}) async {
|
||||
late final String displayName;
|
||||
if (appName == null) {
|
||||
String? defaultAppName;
|
||||
try {
|
||||
defaultAppName = shorebirdEnv.getPubspecYaml()?.name;
|
||||
} catch (_) {}
|
||||
|
||||
displayName = logger.prompt(
|
||||
'${lightGreen.wrap('?')} How should we refer to this app?',
|
||||
defaultValue: defaultAppName,
|
||||
);
|
||||
} else {
|
||||
displayName = appName;
|
||||
}
|
||||
|
||||
return codePushClient.createApp(displayName: displayName);
|
||||
}
|
||||
|
||||
Future<List<AppMetadata>> getApps() async {
|
||||
final fetchAppsProgress = logger.progress('Fetching apps');
|
||||
try {
|
||||
|
||||
@@ -25,12 +25,6 @@ typedef StartProcess = Future<Process> Function(
|
||||
});
|
||||
|
||||
abstract class ShorebirdCommand extends Command<int> {
|
||||
ShorebirdCommand({
|
||||
CodePushClientBuilder? buildCodePushClient,
|
||||
}) : buildCodePushClient = buildCodePushClient ?? CodePushClient.new;
|
||||
|
||||
final CodePushClientBuilder buildCodePushClient;
|
||||
|
||||
// We don't currently have a test involving both a CommandRunner
|
||||
// and a Command, so we can't test this getter.
|
||||
// coverage:ignore-start
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/version.dart';
|
||||
|
||||
const executableName = 'shorebird';
|
||||
@@ -144,7 +144,7 @@ ${lightCyan.wrap('shorebird release android -- --no-pub lib/main.dart')}''',
|
||||
logger.info(
|
||||
'''
|
||||
Shorebird $packageVersion
|
||||
Shorebird Engine • revision ${ShorebirdEnvironment.shorebirdEngineRevision}''',
|
||||
Shorebird Engine • revision ${shorebirdEnv.shorebirdEngineRevision}''',
|
||||
);
|
||||
exitCode = ExitCode.success.code;
|
||||
} else {
|
||||
|
||||
@@ -2,15 +2,14 @@ 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/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
class DowngradeAccountCommand extends ShorebirdCommand {
|
||||
DowngradeAccountCommand({super.buildCodePushClient});
|
||||
DowngradeAccountCommand();
|
||||
|
||||
@override
|
||||
String get name => 'downgrade';
|
||||
@@ -28,14 +27,10 @@ class DowngradeAccountCommand extends ShorebirdCommand {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final client = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final User user;
|
||||
try {
|
||||
final currentUser = await client.getCurrentUser();
|
||||
final currentUser =
|
||||
await codePushClientWrapper.codePushClient.getCurrentUser();
|
||||
if (currentUser == null) {
|
||||
throw Exception('Failed to retrieve user information.');
|
||||
}
|
||||
@@ -65,7 +60,8 @@ class DowngradeAccountCommand extends ShorebirdCommand {
|
||||
|
||||
final DateTime cancellationDate;
|
||||
try {
|
||||
cancellationDate = await client.cancelSubscription();
|
||||
cancellationDate =
|
||||
await codePushClientWrapper.codePushClient.cancelSubscription();
|
||||
} catch (error) {
|
||||
progress.fail('Failed to downgrade plan. Error: $error');
|
||||
return ExitCode.software.code;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:mason_logger/mason_logger.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/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
@@ -13,7 +12,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// {@endtemplate}
|
||||
class UpgradeAccountCommand extends ShorebirdCommand {
|
||||
/// {@macro upgrade_account_command}
|
||||
UpgradeAccountCommand({super.buildCodePushClient});
|
||||
UpgradeAccountCommand();
|
||||
|
||||
@override
|
||||
String get name => 'upgrade';
|
||||
@@ -38,16 +37,11 @@ Please use $consoleLink instead.''',
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final client = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final progress = logger.progress('Retrieving account information');
|
||||
|
||||
final User? user;
|
||||
try {
|
||||
user = await client.getCurrentUser();
|
||||
user = await codePushClientWrapper.codePushClient.getCurrentUser();
|
||||
if (user == null) {
|
||||
progress.fail('''
|
||||
We're having trouble retrieving your account information.
|
||||
@@ -69,7 +63,8 @@ Please try logging out using ${lightCyan.wrap('shorebird logout')} and logging b
|
||||
|
||||
final Uri paymentLink;
|
||||
try {
|
||||
paymentLink = await client.createPaymentLink();
|
||||
paymentLink =
|
||||
await codePushClientWrapper.codePushClient.createPaymentLink();
|
||||
} catch (error) {
|
||||
progress.fail(error.toString());
|
||||
return ExitCode.software.code;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.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_create_app_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
@@ -13,10 +12,9 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// `shorebird apps create`
|
||||
/// Create a new app on Shorebird.
|
||||
/// {@endtemplate}
|
||||
class CreateAppCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdCreateAppMixin {
|
||||
class CreateAppCommand extends ShorebirdCommand {
|
||||
/// {@macro create_app_command}
|
||||
CreateAppCommand({super.buildCodePushClient}) {
|
||||
CreateAppCommand() {
|
||||
argParser.addOption(
|
||||
'app-name',
|
||||
help: '''
|
||||
@@ -44,7 +42,7 @@ Defaults to the name in "pubspec.yaml".''',
|
||||
final appName = results['app-name'] as String?;
|
||||
late final App app;
|
||||
try {
|
||||
app = await createApp(appName: appName);
|
||||
app = await codePushClientWrapper.createApp(appName: appName);
|
||||
} catch (error) {
|
||||
logger.err('$error');
|
||||
return ExitCode.software.code;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:mason_logger/mason_logger.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/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
|
||||
/// {@template delete_app_command}
|
||||
@@ -14,7 +14,7 @@ import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
/// {@endtemplate}
|
||||
class DeleteAppCommand extends ShorebirdCommand {
|
||||
/// {@macro delete_app_command}
|
||||
DeleteAppCommand({super.buildCodePushClient}) {
|
||||
DeleteAppCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
'app-id',
|
||||
@@ -60,7 +60,7 @@ Please use $consoleLink instead.''',
|
||||
if (appIdArg == null) {
|
||||
String? defaultAppId;
|
||||
try {
|
||||
defaultAppId = ShorebirdEnvironment.getShorebirdYaml()?.appId;
|
||||
defaultAppId = shorebirdEnv.getShorebirdYaml()?.appId;
|
||||
} catch (_) {}
|
||||
|
||||
appId = logger.prompt(
|
||||
@@ -71,11 +71,6 @@ Please use $consoleLink instead.''',
|
||||
appId = appIdArg;
|
||||
}
|
||||
|
||||
final client = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final shouldProceed =
|
||||
force || logger.confirm('Deleting an app is permanent. Continue?');
|
||||
if (!shouldProceed) {
|
||||
@@ -84,7 +79,7 @@ Please use $consoleLink instead.''',
|
||||
}
|
||||
|
||||
try {
|
||||
await client.deleteApp(appId: appId);
|
||||
await codePushClientWrapper.codePushClient.deleteApp(appId: appId);
|
||||
} catch (error) {
|
||||
logger.err('$error');
|
||||
return ExitCode.software.code;
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/command.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_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
|
||||
/// {@template build_aar_command}
|
||||
@@ -14,8 +14,7 @@ import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
/// `shorebird build aar`
|
||||
/// Build an Android aar file from your app.
|
||||
/// {@endtemplate}
|
||||
class BuildAarCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin {
|
||||
class BuildAarCommand extends ShorebirdCommand with ShorebirdBuildMixin {
|
||||
BuildAarCommand() {
|
||||
// We would have a "target" option here, similar to what [BuildApkCommand]
|
||||
// and [BuildAabCommand] have, but target cannot currently be configured in
|
||||
@@ -47,7 +46,7 @@ class BuildAarCommand extends ShorebirdCommand
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
if (androidPackageName == null) {
|
||||
if (shorebirdEnv.androidPackageName == null) {
|
||||
logger.err('Could not find androidPackage in pubspec.yaml.');
|
||||
return ExitCode.config.code;
|
||||
}
|
||||
@@ -68,7 +67,7 @@ class BuildAarCommand extends ShorebirdCommand
|
||||
'host',
|
||||
'outputs',
|
||||
'repo',
|
||||
...androidPackageName!.split('.'),
|
||||
...shorebirdEnv.androidPackageName!.split('.'),
|
||||
'flutter_release',
|
||||
buildNumber,
|
||||
'flutter_release-$buildNumber.aar',
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/doctor.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_validator.dart';
|
||||
|
||||
/// {@template build_apk_command}
|
||||
@@ -14,8 +13,7 @@ import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
/// `shorebird build apk`
|
||||
/// Build an Android APK file from your app.
|
||||
/// {@endtemplate}
|
||||
class BuildApkCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin {
|
||||
class BuildApkCommand extends ShorebirdCommand with ShorebirdBuildMixin {
|
||||
/// {@macro build_apk_command}
|
||||
BuildApkCommand() {
|
||||
argParser
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/doctor.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_validator.dart';
|
||||
|
||||
/// {@template build_app_bundle_command}
|
||||
@@ -14,8 +13,7 @@ import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
/// `shorebird build appbundle`
|
||||
/// Build an Android App Bundle file from your app.
|
||||
/// {@endtemplate}
|
||||
class BuildAppBundleCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin {
|
||||
class BuildAppBundleCommand extends ShorebirdCommand with ShorebirdBuildMixin {
|
||||
/// {@macro build_app_bundle_command}
|
||||
BuildAppBundleCommand() {
|
||||
argParser
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/doctor.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_validator.dart';
|
||||
|
||||
/// {@template build_ipa_command}
|
||||
@@ -14,8 +13,7 @@ import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
/// Builds an .xcarchive and optionally .ipa for an iOS app to be generated for
|
||||
/// App Store submission.
|
||||
/// {@endtemplate}
|
||||
class BuildIpaCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin {
|
||||
class BuildIpaCommand extends ShorebirdCommand with ShorebirdBuildMixin {
|
||||
/// {@macro build_ipa_command}
|
||||
BuildIpaCommand() {
|
||||
argParser
|
||||
|
||||
@@ -6,13 +6,12 @@ import 'package:shorebird_cli/src/cache.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_config_mixin.dart';
|
||||
|
||||
/// {@template clean_cache_command}
|
||||
/// `shorebird cache clean`
|
||||
/// Clears the Shorebird cache directory.
|
||||
/// {@endtemplate}
|
||||
class CleanCacheCommand extends ShorebirdCommand with ShorebirdConfigMixin {
|
||||
class CleanCacheCommand extends ShorebirdCommand {
|
||||
/// {@macro clean_cache_command}
|
||||
CleanCacheCommand();
|
||||
|
||||
|
||||
+8
-10
@@ -1,10 +1,10 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:mason_logger/mason_logger.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/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
|
||||
/// {@template add_collaborators_command}
|
||||
@@ -13,7 +13,7 @@ import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
/// {@endtemplate}
|
||||
class AddCollaboratorsCommand extends ShorebirdCommand {
|
||||
/// {@macro add_collaborators_command}
|
||||
AddCollaboratorsCommand({super.buildCodePushClient}) {
|
||||
AddCollaboratorsCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
_appIdOption,
|
||||
@@ -44,13 +44,8 @@ class AddCollaboratorsCommand extends ShorebirdCommand {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final client = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final appId = results[_appIdOption] as String? ??
|
||||
ShorebirdEnvironment.getShorebirdYaml()?.appId;
|
||||
shorebirdEnv.getShorebirdYaml()?.appId;
|
||||
if (appId == null) {
|
||||
logger.err(
|
||||
'''
|
||||
@@ -82,7 +77,10 @@ ${styleBold.wrap(lightGreen.wrap('🚀 Ready to add a new collaborator!'))}
|
||||
|
||||
final progress = logger.progress('Adding collaborator');
|
||||
try {
|
||||
await client.createCollaborator(appId: appId, email: collaborator);
|
||||
await codePushClientWrapper.codePushClient.createCollaborator(
|
||||
appId: appId,
|
||||
email: collaborator,
|
||||
);
|
||||
progress.complete();
|
||||
} catch (error) {
|
||||
progress.fail();
|
||||
|
||||
+7
-11
@@ -2,10 +2,10 @@ 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/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// {@endtemplate}
|
||||
class DeleteCollaboratorsCommand extends ShorebirdCommand {
|
||||
/// {@macro delete_collaborators_command}
|
||||
DeleteCollaboratorsCommand({super.buildCodePushClient}) {
|
||||
DeleteCollaboratorsCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
_appIdOption,
|
||||
@@ -47,13 +47,8 @@ class DeleteCollaboratorsCommand extends ShorebirdCommand {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final client = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final appId = results[_appIdOption] as String? ??
|
||||
ShorebirdEnvironment.getShorebirdYaml()?.appId;
|
||||
shorebirdEnv.getShorebirdYaml()?.appId;
|
||||
if (appId == null) {
|
||||
logger.err(
|
||||
'''
|
||||
@@ -71,7 +66,8 @@ You must either specify an app id via the "--$_appIdOption" flag or run this com
|
||||
final getCollaboratorsProgress = logger.progress('Fetching collaborators');
|
||||
final List<Collaborator> collaborators;
|
||||
try {
|
||||
collaborators = await client.getCollaborators(appId: appId);
|
||||
collaborators = await codePushClientWrapper.codePushClient
|
||||
.getCollaborators(appId: appId);
|
||||
getCollaboratorsProgress.complete();
|
||||
} catch (error) {
|
||||
getCollaboratorsProgress.fail();
|
||||
@@ -109,7 +105,7 @@ ${styleBold.wrap(lightGreen.wrap('🗑️ Ready to delete an existing collabora
|
||||
|
||||
final progress = logger.progress('Deleting collaborator');
|
||||
try {
|
||||
await client.deleteCollaborator(
|
||||
await codePushClientWrapper.codePushClient.deleteCollaborator(
|
||||
appId: appId,
|
||||
userId: collaborator.userId,
|
||||
);
|
||||
|
||||
+6
-10
@@ -2,10 +2,10 @@ 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/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// {@endtemplate}
|
||||
class ListCollaboratorsCommand extends ShorebirdCommand {
|
||||
/// {@macro list_collaborators_command}
|
||||
ListCollaboratorsCommand({super.buildCodePushClient}) {
|
||||
ListCollaboratorsCommand() {
|
||||
argParser.addOption(
|
||||
_appIdOption,
|
||||
help: 'The app id to list collaborators for.',
|
||||
@@ -43,13 +43,8 @@ class ListCollaboratorsCommand extends ShorebirdCommand {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final client = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
final appId = results[_appIdOption] as String? ??
|
||||
ShorebirdEnvironment.getShorebirdYaml()?.appId;
|
||||
shorebirdEnv.getShorebirdYaml()?.appId;
|
||||
if (appId == null) {
|
||||
logger.err(
|
||||
'''
|
||||
@@ -61,7 +56,8 @@ You must either specify an app id via the "--$_appIdOption" flag or run this com
|
||||
|
||||
final List<Collaborator> collaborators;
|
||||
try {
|
||||
collaborators = await client.getCollaborators(appId: appId);
|
||||
collaborators = await codePushClientWrapper.codePushClient
|
||||
.getCollaborators(appId: appId);
|
||||
} catch (error) {
|
||||
logger.err('$error');
|
||||
return ExitCode.software.code;
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/version.dart';
|
||||
|
||||
/// {@template doctor_command}
|
||||
@@ -34,7 +34,7 @@ class DoctorCommand extends ShorebirdCommand {
|
||||
logger.info('''
|
||||
|
||||
Shorebird v$packageVersion
|
||||
Shorebird Engine • revision ${ShorebirdEnvironment.shorebirdEngineRevision}
|
||||
Shorebird Engine • revision ${shorebirdEnv.shorebirdEngineRevision}
|
||||
''');
|
||||
|
||||
await doctor.runValidators(doctor.allValidators, applyFixes: shouldFix);
|
||||
|
||||
@@ -3,26 +3,27 @@ import 'dart:io';
|
||||
import 'package:collection/collection.dart';
|
||||
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/config.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/gradlew.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.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_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/xcodebuild.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
import 'package:yaml_edit/yaml_edit.dart';
|
||||
|
||||
/// {@template init_command}
|
||||
///
|
||||
/// `shorebird init`
|
||||
/// Initialize Shorebird.
|
||||
/// {@endtemplate}
|
||||
class InitCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdCreateAppMixin {
|
||||
class InitCommand extends ShorebirdCommand {
|
||||
/// {@macro init_command}
|
||||
InitCommand({super.buildCodePushClient}) {
|
||||
InitCommand() {
|
||||
argParser.addFlag(
|
||||
'force',
|
||||
abbr: 'f',
|
||||
@@ -48,7 +49,7 @@ class InitCommand extends ShorebirdCommand
|
||||
}
|
||||
|
||||
try {
|
||||
if (!ShorebirdEnvironment.hasPubspecYaml) {
|
||||
if (!shorebirdEnv.hasPubspecYaml) {
|
||||
logger.err('''
|
||||
Could not find a "pubspec.yaml".
|
||||
Please make sure you are running "shorebird init" from the root of your Flutter project.
|
||||
@@ -61,11 +62,8 @@ Please make sure you are running "shorebird init" from the root of your Flutter
|
||||
}
|
||||
|
||||
final force = results['force'] == true;
|
||||
if (force && ShorebirdEnvironment.hasShorebirdYaml) {
|
||||
ShorebirdEnvironment.getShorebirdYamlFile().deleteSync();
|
||||
}
|
||||
|
||||
if (ShorebirdEnvironment.hasShorebirdYaml) {
|
||||
if (!force && shorebirdEnv.hasShorebirdYaml) {
|
||||
logger.err('''
|
||||
A "shorebird.yaml" already exists.
|
||||
If you want to reinitialize Shorebird, please run "shorebird init --force".''');
|
||||
@@ -99,7 +97,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: ShorebirdEnvironment.getPubspecYaml()?.name,
|
||||
defaultValue: shorebirdEnv.getPubspecYaml()?.name,
|
||||
);
|
||||
final hasNoFlavors = productFlavors.isEmpty;
|
||||
final hasSomeFlavors = productFlavors.isNotEmpty &&
|
||||
@@ -109,15 +107,19 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''');
|
||||
if (hasNoFlavors) {
|
||||
// No platforms have any flavors so we just create a single app
|
||||
// and assign it as the default.
|
||||
appId = (await createApp(appName: displayName)).id;
|
||||
final app = await codePushClientWrapper.createApp(appName: displayName);
|
||||
appId = app.id;
|
||||
} else if (hasSomeFlavors) {
|
||||
// Some platforms have flavors and some do not so we create an app
|
||||
// for the default (no flavor) and then create an app per flavor.
|
||||
appId = (await createApp(appName: displayName)).id;
|
||||
final app = await codePushClientWrapper.createApp(appName: displayName);
|
||||
appId = app.id;
|
||||
final values = <String, String>{};
|
||||
for (final flavor in productFlavors) {
|
||||
values[flavor] =
|
||||
(await createApp(appName: '$displayName ($flavor)')).id;
|
||||
final app = await codePushClientWrapper.createApp(
|
||||
appName: '$displayName ($flavor)',
|
||||
);
|
||||
values[flavor] = app.id;
|
||||
}
|
||||
flavors = values;
|
||||
} else {
|
||||
@@ -125,8 +127,10 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''');
|
||||
// and assign the default to the first flavor.
|
||||
final values = <String, String>{};
|
||||
for (final flavor in productFlavors) {
|
||||
values[flavor] =
|
||||
(await createApp(appName: '$displayName ($flavor)')).id;
|
||||
final app = await codePushClientWrapper.createApp(
|
||||
appName: '$displayName ($flavor)',
|
||||
);
|
||||
values[flavor] = app.id;
|
||||
}
|
||||
flavors = values;
|
||||
appId = flavors.values.first;
|
||||
@@ -136,10 +140,10 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''');
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
addShorebirdYamlToProject(appId, flavors: flavors);
|
||||
_addShorebirdYamlToProject(appId, flavors: flavors);
|
||||
|
||||
if (!ShorebirdEnvironment.pubspecContainsShorebirdYaml) {
|
||||
addShorebirdYamlToPubspecAssets();
|
||||
if (!shorebirdEnv.pubspecContainsShorebirdYaml) {
|
||||
_addShorebirdYamlToPubspecAssets();
|
||||
}
|
||||
|
||||
await doctor.runValidators(doctor.allValidators, applyFixes: true);
|
||||
@@ -207,4 +211,56 @@ For more information about Shorebird, visit ${link(uri: Uri.parse('https://shore
|
||||
.toSet();
|
||||
}
|
||||
}
|
||||
|
||||
ShorebirdYaml _addShorebirdYamlToProject(
|
||||
String appId, {
|
||||
Map<String, String>? flavors,
|
||||
}) {
|
||||
const content = '''
|
||||
# This file is used to configure the Shorebird updater used by your application.
|
||||
# Learn more at https://shorebird.dev
|
||||
# This file should be checked into version control.
|
||||
|
||||
# This is the unique identifier assigned to your app.
|
||||
# It is used by your app to request the correct patches from Shorebird servers.
|
||||
app_id:
|
||||
''';
|
||||
|
||||
final editor = YamlEditor(content)..update(['app_id'], appId);
|
||||
|
||||
if (flavors != null) editor.update(['flavors'], flavors);
|
||||
|
||||
shorebirdEnv.getShorebirdYamlFile().writeAsStringSync(editor.toString());
|
||||
|
||||
return ShorebirdYaml(appId: appId);
|
||||
}
|
||||
|
||||
void _addShorebirdYamlToPubspecAssets() {
|
||||
final pubspecFile = shorebirdEnv.getPubspecYamlFile();
|
||||
final pubspecContents = pubspecFile.readAsStringSync();
|
||||
final yaml = loadYaml(pubspecContents, sourceUrl: pubspecFile.uri) as Map;
|
||||
final editor = YamlEditor(pubspecContents);
|
||||
|
||||
if (!yaml.containsKey('flutter')) {
|
||||
editor.update(
|
||||
['flutter'],
|
||||
{
|
||||
'assets': ['shorebird.yaml']
|
||||
},
|
||||
);
|
||||
} else {
|
||||
if (!(yaml['flutter'] as Map).containsKey('assets')) {
|
||||
editor.update(['flutter', 'assets'], ['shorebird.yaml']);
|
||||
} else {
|
||||
final assets = (yaml['flutter'] as Map)['assets'] as List;
|
||||
if (!assets.contains('shorebird.yaml')) {
|
||||
editor.update(['flutter', 'assets'], [...assets, 'shorebird.yaml']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (editor.edits.isEmpty) return;
|
||||
|
||||
pubspecFile.writeAsStringSync(editor.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ import 'package:shorebird_cli/src/formatters/file_size_formatter.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
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_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
/// {@template patch_aar_command}
|
||||
@@ -25,7 +25,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// Create a patch for an Android archive release.
|
||||
/// {@endtemplate}
|
||||
class PatchAarCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin, ShorebirdArtifactMixin {
|
||||
with ShorebirdBuildMixin, ShorebirdArtifactMixin {
|
||||
/// {@macro patch_aar_command}
|
||||
PatchAarCommand({
|
||||
HashFunction? hashFn,
|
||||
@@ -105,7 +105,7 @@ of the Android app that is using this module.''',
|
||||
|
||||
await cache.updateAll();
|
||||
|
||||
if (androidPackageName == null) {
|
||||
if (shorebirdEnv.androidPackageName == null) {
|
||||
logger.err('Could not find androidPackage in pubspec.yaml.');
|
||||
return ExitCode.config.code;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ of the Android app that is using this module.''',
|
||||
final buildNumber = results['build-number'] as String;
|
||||
final releaseVersion = results['release-version'] as String;
|
||||
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId();
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -148,7 +148,8 @@ Please re-run the release command for this version or create a new release.''');
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
@@ -171,7 +172,7 @@ Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release aar')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd ${ShorebirdEnvironment.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
@@ -217,7 +218,7 @@ https://github.com/shorebirdtech/shorebird/issues/472
|
||||
final contentDiffs = _aarDiffer.changedFiles(
|
||||
releaseAarPath,
|
||||
aarArtifactPath(
|
||||
packageName: androidPackageName!,
|
||||
packageName: shorebirdEnv.androidPackageName!,
|
||||
buildNumber: buildNumber,
|
||||
),
|
||||
);
|
||||
@@ -247,7 +248,7 @@ https://github.com/shorebirdtech/shorebird/issues/472
|
||||
}
|
||||
|
||||
final extractedAarDir = await extractAar(
|
||||
packageName: androidPackageName!,
|
||||
packageName: shorebirdEnv.androidPackageName!,
|
||||
buildNumber: buildNumber,
|
||||
unzipFn: _unzipFn,
|
||||
);
|
||||
|
||||
@@ -14,10 +14,10 @@ import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/formatters/formatters.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_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_release_version_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
/// {@template patch_android_command}
|
||||
@@ -26,10 +26,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// push server.
|
||||
/// {@endtemplate}
|
||||
class PatchAndroidCommand extends ShorebirdCommand
|
||||
with
|
||||
ShorebirdConfigMixin,
|
||||
ShorebirdBuildMixin,
|
||||
ShorebirdReleaseVersionMixin {
|
||||
with ShorebirdBuildMixin, ShorebirdReleaseVersionMixin {
|
||||
/// {@macro patch_android_command}
|
||||
PatchAndroidCommand({
|
||||
HashFunction? hashFn,
|
||||
@@ -112,7 +109,7 @@ class PatchAndroidCommand extends ShorebirdCommand
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId(flavor: flavor);
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -156,7 +153,8 @@ Please re-run the release command for this version or create a new release.''');
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
@@ -179,7 +177,7 @@ Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd ${ShorebirdEnvironment.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
|
||||
@@ -14,16 +14,16 @@ import 'package:shorebird_cli/src/ios.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
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_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
/// {@template patch_ios_command}
|
||||
/// `shorebird patch ios-alpha` command.
|
||||
/// {@endtemplate}
|
||||
class PatchIosCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin, ShorebirdArtifactMixin {
|
||||
with ShorebirdBuildMixin, ShorebirdArtifactMixin {
|
||||
/// {@macro patch_ios_command}
|
||||
PatchIosCommand({
|
||||
HashFunction? hashFn,
|
||||
@@ -92,7 +92,7 @@ class PatchIosCommand extends ShorebirdCommand
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId(flavor: flavor);
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -158,7 +158,8 @@ Please re-run the release command for this version or create a new release.''');
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
@@ -181,7 +182,7 @@ Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd ${ShorebirdEnvironment.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
|
||||
@@ -12,13 +12,13 @@ import 'package:shorebird_cli/src/ios.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
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_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
class PatchIosFrameworkCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin, ShorebirdArtifactMixin {
|
||||
with ShorebirdBuildMixin, ShorebirdArtifactMixin {
|
||||
PatchIosFrameworkCommand({
|
||||
HashFunction? hashFn,
|
||||
}) : _hashFn = hashFn ?? ((m) => sha256.convert(m).toString()) {
|
||||
@@ -73,7 +73,7 @@ of the iOS app that is using this module.''',
|
||||
const releasePlatform = ReleasePlatform.ios;
|
||||
final releaseVersion = results['release-version'] as String;
|
||||
final dryRun = results['dry-run'] == true;
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId();
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -115,7 +115,8 @@ Please re-run the release command for this version or create a new release.''');
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
@@ -138,7 +139,7 @@ Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd ${ShorebirdEnvironment.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
|
||||
@@ -9,10 +9,10 @@ import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
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_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_release_version_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
/// {@template release_aar_command}
|
||||
@@ -21,7 +21,6 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// {@endtemplate}
|
||||
class ReleaseAarCommand extends ShorebirdCommand
|
||||
with
|
||||
ShorebirdConfigMixin,
|
||||
ShorebirdBuildMixin,
|
||||
ShorebirdReleaseVersionMixin,
|
||||
ShorebirdArtifactMixin {
|
||||
@@ -75,7 +74,7 @@ make smaller updates to your app.
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
if (androidPackageName == null) {
|
||||
if (shorebirdEnv.androidPackageName == null) {
|
||||
logger.err('Could not find androidPackage in pubspec.yaml.');
|
||||
return ExitCode.config.code;
|
||||
}
|
||||
@@ -85,7 +84,7 @@ make smaller updates to your app.
|
||||
final releaseVersion = results['release-version'] as String;
|
||||
final buildProgress = logger.progress('Building aar');
|
||||
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId();
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -141,7 +140,8 @@ ${summary.join('\n')}
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
@@ -168,7 +168,7 @@ ${summary.join('\n')}
|
||||
|
||||
final extractAarProgress = logger.progress('Creating artifacts');
|
||||
final extractedAarDir = await extractAar(
|
||||
packageName: androidPackageName!,
|
||||
packageName: shorebirdEnv.androidPackageName!,
|
||||
buildNumber: buildNumber,
|
||||
unzipFn: _unzipFn,
|
||||
);
|
||||
@@ -179,7 +179,7 @@ ${summary.join('\n')}
|
||||
releaseId: release.id,
|
||||
platform: platform,
|
||||
aarPath: aarArtifactPath(
|
||||
packageName: androidPackageName!,
|
||||
packageName: shorebirdEnv.androidPackageName!,
|
||||
buildNumber: buildNumber,
|
||||
),
|
||||
extractedAarDir: extractedAarDir,
|
||||
@@ -201,7 +201,7 @@ Your next step is to add this module as a dependency in your app's build.gradle:
|
||||
${lightCyan.wrap('''
|
||||
dependencies {
|
||||
// ...
|
||||
releaseImplementation '$androidPackageName:flutter_release:$buildNumber'
|
||||
releaseImplementation '${shorebirdEnv.androidPackageName}:flutter_release:$buildNumber'
|
||||
// ...
|
||||
}''')}
|
||||
''');
|
||||
|
||||
@@ -8,10 +8,10 @@ import 'package:shorebird_cli/src/config/shorebird_yaml.dart';
|
||||
import 'package:shorebird_cli/src/doctor.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_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_release_version_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
/// {@template release_android_command}
|
||||
@@ -19,10 +19,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// Create new app releases for Android.
|
||||
/// {@endtemplate}
|
||||
class ReleaseAndroidCommand extends ShorebirdCommand
|
||||
with
|
||||
ShorebirdConfigMixin,
|
||||
ShorebirdBuildMixin,
|
||||
ShorebirdReleaseVersionMixin {
|
||||
with ShorebirdBuildMixin, ShorebirdReleaseVersionMixin {
|
||||
/// {@macro release_android_command}
|
||||
ReleaseAndroidCommand() {
|
||||
argParser
|
||||
@@ -89,8 +86,7 @@ make smaller updates to your app.
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId(flavor: flavor);
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -158,7 +154,8 @@ ${summary.join('\n')}
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
|
||||
@@ -12,9 +12,9 @@ import 'package:shorebird_cli/src/ios.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
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_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
/// {@template release_ios_command}
|
||||
@@ -22,7 +22,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// Create new app releases for iOS.
|
||||
/// {@endtemplate}
|
||||
class ReleaseIosCommand extends ShorebirdCommand
|
||||
with ShorebirdBuildMixin, ShorebirdConfigMixin, ShorebirdArtifactMixin {
|
||||
with ShorebirdBuildMixin, ShorebirdArtifactMixin {
|
||||
/// {@macro release_ios_command}
|
||||
ReleaseIosCommand({
|
||||
IpaReader? ipaReader,
|
||||
@@ -75,7 +75,7 @@ make smaller updates to your app.
|
||||
const releasePlatform = ReleasePlatform.ios;
|
||||
final flavor = results['flavor'] as String?;
|
||||
final target = results['target'] as String?;
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId(flavor: flavor);
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -165,7 +165,8 @@ ${summary.join('\n')}
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
|
||||
@@ -10,13 +10,13 @@ import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/ios.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_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
class ReleaseIosFrameworkCommand extends ShorebirdCommand
|
||||
with ShorebirdConfigMixin, ShorebirdBuildMixin {
|
||||
with ShorebirdBuildMixin {
|
||||
ReleaseIosFrameworkCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
@@ -58,7 +58,7 @@ of the iOS app that is using this module.''',
|
||||
|
||||
const releasePlatform = ReleasePlatform.ios;
|
||||
final releaseVersion = results['release-version'] as String;
|
||||
final shorebirdYaml = ShorebirdEnvironment.getShorebirdYaml()!;
|
||||
final shorebirdYaml = shorebirdEnv.getShorebirdYaml()!;
|
||||
final appId = shorebirdYaml.getAppId();
|
||||
final app = await codePushClientWrapper.getApp(appId: appId);
|
||||
|
||||
@@ -113,7 +113,8 @@ ${summary.join('\n')}
|
||||
);
|
||||
final String shorebirdFlutterRevision;
|
||||
try {
|
||||
shorebirdFlutterRevision = await getShorebirdFlutterRevision();
|
||||
shorebirdFlutterRevision =
|
||||
await shorebirdVersionManager.fetchCurrentGitHash();
|
||||
flutterRevisionProgress.complete();
|
||||
} catch (error) {
|
||||
flutterRevisionProgress.fail('$error');
|
||||
|
||||
@@ -2,11 +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/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_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
@@ -17,7 +17,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// {@endtemplate}
|
||||
class DeleteReleasesCommand extends ShorebirdCommand {
|
||||
/// {@macro delete_releases_command}
|
||||
DeleteReleasesCommand({super.buildCodePushClient}) {
|
||||
DeleteReleasesCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
'version',
|
||||
@@ -47,18 +47,14 @@ class DeleteReleasesCommand extends ShorebirdCommand {
|
||||
}
|
||||
|
||||
final flavor = results['flavor'] as String?;
|
||||
final appId =
|
||||
ShorebirdEnvironment.getShorebirdYaml()!.getAppId(flavor: flavor);
|
||||
|
||||
final codePushClient = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
final appId = shorebirdEnv.getShorebirdYaml()!.getAppId(flavor: flavor);
|
||||
|
||||
final List<Release> releases;
|
||||
var progress = logger.progress('Fetching releases');
|
||||
try {
|
||||
releases = await codePushClient.getReleases(appId: appId);
|
||||
releases = await codePushClientWrapper.codePushClient.getReleases(
|
||||
appId: appId,
|
||||
);
|
||||
progress.complete('Fetched releases.');
|
||||
} catch (error) {
|
||||
progress.fail('$error');
|
||||
@@ -89,7 +85,7 @@ class DeleteReleasesCommand extends ShorebirdCommand {
|
||||
progress = logger.progress('Deleting release');
|
||||
|
||||
try {
|
||||
await codePushClient.deleteRelease(
|
||||
await codePushClientWrapper.codePushClient.deleteRelease(
|
||||
appId: appId,
|
||||
releaseId: releaseToDelete.id,
|
||||
);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
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/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_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
/// {@endtemplate}
|
||||
class ListReleasesCommand extends ShorebirdCommand {
|
||||
/// {@macro list_releases_command}
|
||||
ListReleasesCommand({super.buildCodePushClient}) {
|
||||
ListReleasesCommand() {
|
||||
argParser.addOption(
|
||||
'flavor',
|
||||
help: 'The product flavor to use when listing releases.',
|
||||
@@ -47,17 +47,13 @@ Please use $consoleLink instead.''',
|
||||
}
|
||||
|
||||
final flavor = results['flavor'] as String?;
|
||||
final appId =
|
||||
ShorebirdEnvironment.getShorebirdYaml()!.getAppId(flavor: flavor);
|
||||
|
||||
final codePushClient = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
final appId = shorebirdEnv.getShorebirdYaml()!.getAppId(flavor: flavor);
|
||||
|
||||
final List<Release> releases;
|
||||
try {
|
||||
releases = await codePushClient.getReleases(appId: appId);
|
||||
releases = await codePushClientWrapper.codePushClient.getReleases(
|
||||
appId: appId,
|
||||
);
|
||||
} catch (error) {
|
||||
logger.err('$error');
|
||||
return ExitCode.software.code;
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
/// {@endtemplate}
|
||||
class RunCommand extends ShorebirdCommand {
|
||||
/// {@macro run_command}
|
||||
RunCommand({super.buildCodePushClient}) {
|
||||
RunCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
'device-id',
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
|
||||
/// {@template upgrade_command}
|
||||
@@ -91,7 +91,7 @@ class UpgradeCommand extends ShorebirdCommand {
|
||||
final result = await process.run(
|
||||
executable,
|
||||
args,
|
||||
workingDirectory: ShorebirdEnvironment.flutterDirectory.path,
|
||||
workingDirectory: shorebirdEnv.flutterDirectory.path,
|
||||
);
|
||||
|
||||
if (result.exitCode != 0) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:path/path.dart' as p;
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
|
||||
/// A reference to a [IOSDeploy] instance.
|
||||
final iosDeployRef = create(IOSDeploy.new);
|
||||
@@ -33,7 +33,7 @@ class IOSDeploy {
|
||||
@visibleForTesting
|
||||
static File get iosDeployExecutable => File(
|
||||
p.join(
|
||||
ShorebirdEnvironment.flutterDirectory.path,
|
||||
shorebirdEnv.flutterDirectory.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'dart:io';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
|
||||
// A reference to a [EngineConfig] instance.
|
||||
final engineConfigRef = create(() => const EngineConfig.empty());
|
||||
@@ -111,10 +111,7 @@ class ShorebirdProcess {
|
||||
}
|
||||
|
||||
String _resolveExecutable(String executable) {
|
||||
if (executable == 'flutter') {
|
||||
return ShorebirdEnvironment.flutterBinaryFile.path;
|
||||
}
|
||||
|
||||
if (executable == 'flutter') return shorebirdEnv.flutterBinaryFile.path;
|
||||
return executable;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/cache.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
|
||||
enum Arch {
|
||||
arm64,
|
||||
@@ -328,7 +328,7 @@ mixin ShorebirdBuildMixin on ShorebirdCommand {
|
||||
];
|
||||
|
||||
final result = await process.run(
|
||||
ShorebirdEnvironment.genSnapshotFile.path,
|
||||
shorebirdEnv.genSnapshotFile.path,
|
||||
arguments,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
import 'package:yaml_edit/yaml_edit.dart';
|
||||
|
||||
mixin ShorebirdConfigMixin on ShorebirdCommand {
|
||||
/// Returns the Android package name from the pubspec.yaml file of a Flutter
|
||||
/// module.
|
||||
String? get androidPackageName {
|
||||
final pubspec = ShorebirdEnvironment.getPubspecYaml();
|
||||
final module = pubspec?.flutter?['module'] as Map?;
|
||||
return module?['androidPackage'] as String?;
|
||||
}
|
||||
|
||||
ShorebirdYaml addShorebirdYamlToProject(
|
||||
String appId, {
|
||||
Map<String, String>? flavors,
|
||||
}) {
|
||||
const content = '''
|
||||
# This file is used to configure the Shorebird updater used by your application.
|
||||
# Learn more at https://shorebird.dev
|
||||
# This file should be checked into version control.
|
||||
|
||||
# This is the unique identifier assigned to your app.
|
||||
# It is used by your app to request the correct patches from Shorebird servers.
|
||||
app_id:
|
||||
''';
|
||||
|
||||
final editor = YamlEditor(content)..update(['app_id'], appId);
|
||||
|
||||
if (flavors != null) editor.update(['flavors'], flavors);
|
||||
|
||||
ShorebirdEnvironment.getShorebirdYamlFile()
|
||||
.writeAsStringSync(editor.toString());
|
||||
|
||||
return ShorebirdYaml(appId: appId);
|
||||
}
|
||||
|
||||
void addShorebirdYamlToPubspecAssets() {
|
||||
final pubspecFile = File(p.join(Directory.current.path, 'pubspec.yaml'));
|
||||
final pubspecContents = pubspecFile.readAsStringSync();
|
||||
final yaml = loadYaml(pubspecContents, sourceUrl: pubspecFile.uri) as Map;
|
||||
final editor = YamlEditor(pubspecContents);
|
||||
|
||||
if (!yaml.containsKey('flutter')) {
|
||||
editor.update(
|
||||
['flutter'],
|
||||
{
|
||||
'assets': ['shorebird.yaml']
|
||||
},
|
||||
);
|
||||
} else {
|
||||
if (!(yaml['flutter'] as Map).containsKey('assets')) {
|
||||
editor.update(['flutter', 'assets'], ['shorebird.yaml']);
|
||||
} else {
|
||||
final assets = (yaml['flutter'] as Map)['assets'] as List;
|
||||
if (!assets.contains('shorebird.yaml')) {
|
||||
editor.update(['flutter', 'assets'], [...assets, 'shorebird.yaml']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (editor.edits.isEmpty) return;
|
||||
|
||||
pubspecFile.writeAsStringSync(editor.toString());
|
||||
}
|
||||
|
||||
Future<String> getShorebirdFlutterRevision() async {
|
||||
final result = await process.run(
|
||||
'git',
|
||||
['rev-parse', 'HEAD'],
|
||||
workingDirectory: ShorebirdEnvironment.flutterDirectory.path,
|
||||
);
|
||||
if (result.exitCode != 0) {
|
||||
throw Exception('Unable to determine flutter revision: ${result.stderr}');
|
||||
}
|
||||
return (result.stdout as String).trim();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
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 {
|
||||
Future<App> createApp({String? appName}) async {
|
||||
late final String displayName;
|
||||
if (appName == null) {
|
||||
String? defaultAppName;
|
||||
try {
|
||||
defaultAppName = ShorebirdEnvironment.getPubspecYaml()?.name;
|
||||
} catch (_) {}
|
||||
|
||||
displayName = logger.prompt(
|
||||
'${lightGreen.wrap('?')} How should we refer to this app?',
|
||||
defaultValue: defaultAppName,
|
||||
);
|
||||
} else {
|
||||
displayName = appName;
|
||||
}
|
||||
|
||||
final client = buildCodePushClient(
|
||||
httpClient: auth.client,
|
||||
hostedUri: ShorebirdEnvironment.hostedUri,
|
||||
);
|
||||
|
||||
return client.createApp(displayName: displayName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
import 'dart:io' hide Platform;
|
||||
|
||||
import 'package:checked_yaml/checked_yaml.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:pubspec_parse/pubspec_parse.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/config/shorebird_yaml.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
/// A reference to a [ShorebirdEnv] instance.
|
||||
final shorebirdEnvRef = create(ShorebirdEnv.new);
|
||||
|
||||
/// The [ShorebirdEnv] instance available in the current zone.
|
||||
ShorebirdEnv get shorebirdEnv => read(shorebirdEnvRef);
|
||||
|
||||
/// {@template shorebird_env}
|
||||
/// A class that provides access to shorebird environment metadata.
|
||||
/// {@endtemplate}
|
||||
class ShorebirdEnv {
|
||||
/// {@macro shorebird_env}
|
||||
const ShorebirdEnv();
|
||||
|
||||
/// The root directory of the Shorebird install.
|
||||
///
|
||||
/// Assumes we are running from $ROOT/bin/cache.
|
||||
Directory get shorebirdRoot {
|
||||
return File(platform.script.toFilePath()).parent.parent.parent;
|
||||
}
|
||||
|
||||
String get shorebirdEngineRevision {
|
||||
return File(
|
||||
p.join(flutterDirectory.path, 'bin', 'internal', 'engine.version'),
|
||||
).readAsStringSync().trim();
|
||||
}
|
||||
|
||||
String get flutterRevision {
|
||||
return File(
|
||||
p.join(shorebirdRoot.path, 'bin', 'internal', 'flutter.version'),
|
||||
).readAsStringSync().trim();
|
||||
}
|
||||
|
||||
/// The root of the Shorebird-vended Flutter git checkout.
|
||||
Directory get flutterDirectory {
|
||||
return Directory(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'flutter',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// The Shorebird-vended Flutter binary.
|
||||
File get flutterBinaryFile {
|
||||
return File(
|
||||
p.join(
|
||||
flutterDirectory.path,
|
||||
'bin',
|
||||
'flutter',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
File get genSnapshotFile {
|
||||
return File(
|
||||
p.join(
|
||||
flutterDirectory.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
'engine',
|
||||
'ios-release',
|
||||
'gen_snapshot_arm64',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// The `shorebird.yaml` file for this project.
|
||||
File getShorebirdYamlFile() {
|
||||
return File(p.join(Directory.current.path, 'shorebird.yaml'));
|
||||
}
|
||||
|
||||
/// The `pubspec.yaml` file for this project.
|
||||
File getPubspecYamlFile() {
|
||||
return File(p.join(Directory.current.path, 'pubspec.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.
|
||||
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.
|
||||
Pubspec? getPubspecYaml() {
|
||||
final file = getPubspecYamlFile();
|
||||
if (!file.existsSync()) return null;
|
||||
final yaml = file.readAsStringSync();
|
||||
return Pubspec.parse(yaml);
|
||||
}
|
||||
|
||||
/// Whether `shorebird init` has been run in the current project.
|
||||
bool get isShorebirdInitialized {
|
||||
return hasShorebirdYaml && pubspecContainsShorebirdYaml;
|
||||
}
|
||||
|
||||
/// Whether the current project has a `shorebird.yaml` file.
|
||||
bool get hasShorebirdYaml => getShorebirdYamlFile().existsSync();
|
||||
|
||||
/// Whether the current project has a `pubspec.yaml` file.
|
||||
bool get hasPubspecYaml => getPubspecYaml() != null;
|
||||
|
||||
/// Whether the current project's `pubspec.yaml` file contains a reference to
|
||||
/// `shorebird.yaml` in its `assets` section.
|
||||
bool get pubspecContainsShorebirdYaml {
|
||||
final file = File(p.join(Directory.current.path, 'pubspec.yaml'));
|
||||
final pubspecContents = file.readAsStringSync();
|
||||
final yaml = loadYaml(pubspecContents, sourceUrl: file.uri) as Map;
|
||||
if (!yaml.containsKey('flutter')) return false;
|
||||
if (!(yaml['flutter'] as Map).containsKey('assets')) return false;
|
||||
final assets = (yaml['flutter'] as Map)['assets'] as List;
|
||||
return assets.contains('shorebird.yaml');
|
||||
}
|
||||
|
||||
/// Returns the Android package name from the pubspec.yaml file of a Flutter
|
||||
/// module.
|
||||
String? get androidPackageName {
|
||||
final pubspec = getPubspecYaml();
|
||||
final module = pubspec?.flutter?['module'] as Map?;
|
||||
return module?['androidPackage'] as String?;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
Uri? get hostedUri {
|
||||
try {
|
||||
final baseUrl = platform.environment['SHOREBIRD_HOSTED_URL'] ??
|
||||
getShorebirdYaml()?.baseUrl;
|
||||
return baseUrl == null ? null : Uri.tryParse(baseUrl);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
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';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
abstract class ShorebirdEnvironment {
|
||||
/// Environment variables from [Platform.environment].
|
||||
static Map<String, String> get environment => platform.environment;
|
||||
|
||||
/// The root directory of the Shorebird install.
|
||||
///
|
||||
/// Assumes we are running from $ROOT/bin/cache.
|
||||
static Directory get shorebirdRoot =>
|
||||
File(platform.script.toFilePath()).parent.parent.parent;
|
||||
|
||||
static String get shorebirdEngineRevision {
|
||||
return _shorebirdEngineRevision ??
|
||||
File(p.join(flutterDirectory.path, 'bin', 'internal', 'engine.version'))
|
||||
.readAsStringSync()
|
||||
.trim();
|
||||
}
|
||||
|
||||
static String? _shorebirdEngineRevision;
|
||||
|
||||
@visibleForTesting
|
||||
static set shorebirdEngineRevision(String revision) {
|
||||
_shorebirdEngineRevision = revision;
|
||||
}
|
||||
|
||||
static String? _flutterRevision;
|
||||
|
||||
@visibleForTesting
|
||||
static set flutterRevision(String revision) {
|
||||
_flutterRevision = revision;
|
||||
}
|
||||
|
||||
static String get flutterRevision {
|
||||
return _flutterRevision ??
|
||||
File(
|
||||
p.join(shorebirdRoot.path, 'bin', 'internal', 'flutter.version'),
|
||||
).readAsStringSync().trim();
|
||||
}
|
||||
|
||||
/// The root of the Shorebird-vended Flutter git checkout.
|
||||
static Directory get flutterDirectory => Directory(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'flutter',
|
||||
),
|
||||
);
|
||||
|
||||
/// The Shorebird-vended Flutter binary.
|
||||
static File get flutterBinaryFile => File(
|
||||
p.join(
|
||||
flutterDirectory.path,
|
||||
'bin',
|
||||
'flutter',
|
||||
),
|
||||
);
|
||||
|
||||
static File get genSnapshotFile => File(
|
||||
p.join(
|
||||
flutterDirectory.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
'engine',
|
||||
'ios-release',
|
||||
'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!));
|
||||
}
|
||||
|
||||
static bool get isShorebirdInitialized {
|
||||
return hasShorebirdYaml && pubspecContainsShorebirdYaml;
|
||||
}
|
||||
|
||||
static bool get hasShorebirdYaml {
|
||||
return ShorebirdEnvironment.getShorebirdYamlFile().existsSync();
|
||||
}
|
||||
|
||||
static bool get hasPubspecYaml {
|
||||
return ShorebirdEnvironment.getPubspecYaml() != null;
|
||||
}
|
||||
|
||||
static bool get pubspecContainsShorebirdYaml {
|
||||
final file = File(p.join(Directory.current.path, 'pubspec.yaml'));
|
||||
final pubspecContents = file.readAsStringSync();
|
||||
final yaml = loadYaml(pubspecContents, sourceUrl: file.uri) as Map;
|
||||
if (!yaml.containsKey('flutter')) return false;
|
||||
if (!(yaml['flutter'] as Map).containsKey('assets')) return false;
|
||||
final assets = (yaml['flutter'] as Map)['assets'] as List;
|
||||
return assets.contains('shorebird.yaml');
|
||||
}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ 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/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
|
||||
abstract interface class PreconditionFailedException implements Exception {
|
||||
@@ -73,8 +73,7 @@ class ShorebirdValidator {
|
||||
throw UserNotAuthorizedException();
|
||||
}
|
||||
|
||||
if (checkShorebirdInitialized &&
|
||||
!ShorebirdEnvironment.isShorebirdInitialized) {
|
||||
if (checkShorebirdInitialized && !shorebirdEnv.isShorebirdInitialized) {
|
||||
logger.err(
|
||||
'Shorebird is not initialized. Did you run "shorebird init"?',
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
import 'package:version/version.dart';
|
||||
|
||||
@@ -28,9 +29,9 @@ class ShorebirdFlutterValidator extends Validator {
|
||||
Future<List<ValidationIssue>> validate() async {
|
||||
final issues = <ValidationIssue>[];
|
||||
|
||||
if (!ShorebirdEnvironment.flutterDirectory.existsSync()) {
|
||||
if (!shorebirdEnv.flutterDirectory.existsSync()) {
|
||||
final message = 'No Flutter directory found at '
|
||||
'${ShorebirdEnvironment.flutterDirectory}';
|
||||
'${shorebirdEnv.flutterDirectory}';
|
||||
issues.add(
|
||||
ValidationIssue(
|
||||
severity: ValidationIssueSeverity.error,
|
||||
@@ -43,7 +44,7 @@ class ShorebirdFlutterValidator extends Validator {
|
||||
issues.add(
|
||||
ValidationIssue(
|
||||
severity: ValidationIssueSeverity.warning,
|
||||
message: '${ShorebirdEnvironment.flutterDirectory} has local '
|
||||
message: '${shorebirdEnv.flutterDirectory} has local '
|
||||
'modifications',
|
||||
),
|
||||
);
|
||||
@@ -96,7 +97,7 @@ This can cause unexpected behavior if you are switching between the tools and th
|
||||
}
|
||||
|
||||
final flutterStorageEnvironmentValue =
|
||||
ShorebirdEnvironment.environment['FLUTTER_STORAGE_BASE_URL'];
|
||||
platform.environment['FLUTTER_STORAGE_BASE_URL'];
|
||||
if (flutterStorageEnvironmentValue != null &&
|
||||
flutterStorageEnvironmentValue.isNotEmpty) {
|
||||
issues.add(
|
||||
@@ -115,7 +116,7 @@ This can cause unexpected behavior if you are switching between the tools and th
|
||||
final result = await process.run(
|
||||
'git',
|
||||
['status', '--untracked-files=no', '--porcelain'],
|
||||
workingDirectory: ShorebirdEnvironment.flutterDirectory.path,
|
||||
workingDirectory: shorebirdEnv.flutterDirectory.path,
|
||||
);
|
||||
return result.stdout.toString().trim().isEmpty;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ 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:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _FakeBaseRequest extends Fake implements http.BaseRequest {}
|
||||
@@ -17,6 +17,8 @@ class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class TestCachedArtifact extends CachedArtifact {
|
||||
TestCachedArtifact({required super.cache, required super.platform});
|
||||
|
||||
@@ -29,9 +31,12 @@ class TestCachedArtifact extends CachedArtifact {
|
||||
|
||||
void main() {
|
||||
group('Cache', () {
|
||||
const shorebirdEngineRevision = 'test-revision';
|
||||
|
||||
late Directory shorebirdRoot;
|
||||
late http.Client httpClient;
|
||||
late Platform platform;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late Cache cache;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -40,6 +45,7 @@ void main() {
|
||||
values: {
|
||||
cacheRef.overrideWith(() => cache),
|
||||
platformRef.overrideWith(() => platform),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -51,24 +57,18 @@ void main() {
|
||||
setUp(() {
|
||||
httpClient = _MockHttpClient();
|
||||
platform = _MockPlatform();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
|
||||
shorebirdRoot = Directory.systemTemp.createTempSync();
|
||||
ShorebirdEnvironment.shorebirdEngineRevision = 'test-revision';
|
||||
when(
|
||||
() => shorebirdEnv.shorebirdEngineRevision,
|
||||
).thenReturn(shorebirdEngineRevision);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
|
||||
when(() => platform.environment).thenReturn({});
|
||||
when(() => platform.isMacOS).thenReturn(true);
|
||||
when(() => platform.isWindows).thenReturn(false);
|
||||
when(() => platform.isLinux).thenReturn(false);
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
when(() => httpClient.send(any())).thenAnswer(
|
||||
(_) async => http.StreamedResponse(
|
||||
@@ -77,7 +77,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
cache = Cache(httpClient: httpClient, platform: platform);
|
||||
cache = runWithOverrides(() => Cache(httpClient: httpClient));
|
||||
});
|
||||
|
||||
test('can be instantiated w/out args', () {
|
||||
@@ -86,7 +86,9 @@ void main() {
|
||||
|
||||
group('getArtifactDirectory', () {
|
||||
test('returns correct directory', () {
|
||||
final directory = cache.getArtifactDirectory('test');
|
||||
final directory = runWithOverrides(
|
||||
() => cache.getArtifactDirectory('test'),
|
||||
);
|
||||
expect(
|
||||
directory.path.endsWith(
|
||||
p.join(
|
||||
@@ -103,7 +105,9 @@ void main() {
|
||||
|
||||
group('getPreviewDirectory', () {
|
||||
test('returns correct directory', () {
|
||||
final directory = cache.getPreviewDirectory('test');
|
||||
final directory = runWithOverrides(
|
||||
() => cache.getPreviewDirectory('test'),
|
||||
);
|
||||
expect(
|
||||
directory.path.endsWith(
|
||||
p.join(
|
||||
@@ -132,17 +136,18 @@ void main() {
|
||||
|
||||
group('clear', () {
|
||||
test('deletes the cache directory', () async {
|
||||
final shorebirdCacheDirectory =
|
||||
runWithOverrides(() => Cache.shorebirdCacheDirectory)
|
||||
..createSync(recursive: true);
|
||||
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', () {
|
||||
final shorebirdCacheDirectory =
|
||||
runWithOverrides(() => Cache.shorebirdCacheDirectory);
|
||||
final shorebirdCacheDirectory = runWithOverrides(
|
||||
() => Cache.shorebirdCacheDirectory,
|
||||
);
|
||||
expect(shorebirdCacheDirectory.existsSync(), isFalse);
|
||||
runWithOverrides(cache.clear);
|
||||
expect(shorebirdCacheDirectory.existsSync(), isFalse);
|
||||
@@ -175,7 +180,7 @@ void main() {
|
||||
request.url,
|
||||
equals(
|
||||
Uri.parse(
|
||||
'${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/${ShorebirdEnvironment.shorebirdEngineRevision}/patch-darwin-x64.zip',
|
||||
'${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/$shorebirdEngineRevision/patch-darwin-x64.zip',
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -196,7 +201,7 @@ void main() {
|
||||
request.url,
|
||||
equals(
|
||||
Uri.parse(
|
||||
'${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/${ShorebirdEnvironment.shorebirdEngineRevision}/patch-windows-x64.zip',
|
||||
'${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/$shorebirdEngineRevision/patch-windows-x64.zip',
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -216,7 +221,7 @@ void main() {
|
||||
request.url,
|
||||
equals(
|
||||
Uri.parse(
|
||||
'${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/${ShorebirdEnvironment.shorebirdEngineRevision}/patch-linux-x64.zip',
|
||||
'${cache.storageBaseUrl}/${cache.storageBucket}/shorebird/$shorebirdEngineRevision/patch-linux-x64.zip',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ 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/shorebird_env.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';
|
||||
@@ -25,21 +26,25 @@ class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
void main() {
|
||||
group('scoped', () {
|
||||
late Auth auth;
|
||||
late http.Client httpClient;
|
||||
late Platform platform;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
|
||||
setUp(() {
|
||||
auth = _MockAuth();
|
||||
httpClient = _MockHttpClient();
|
||||
platform = _MockPlatform();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => platform.environment).thenReturn({
|
||||
'SHOREBIRD_HOSTED_URL': 'http://example.com',
|
||||
});
|
||||
when(() => shorebirdEnv.hostedUri).thenReturn(
|
||||
Uri.parse('http://example.com'),
|
||||
);
|
||||
});
|
||||
|
||||
test('creates instance from scoped Auth and ShorebirdEnvironment', () {
|
||||
@@ -49,6 +54,7 @@ void main() {
|
||||
codePushClientWrapperRef,
|
||||
authRef.overrideWith(() => auth),
|
||||
platformRef.overrideWith(() => platform),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
expect(
|
||||
@@ -160,6 +166,43 @@ void main() {
|
||||
});
|
||||
|
||||
group('app', () {
|
||||
group('createApp', () {
|
||||
test('prompts for displayName when not provided', () async {
|
||||
const appName = 'test app';
|
||||
const app = App(id: appId, displayName: 'Test App');
|
||||
when(() => logger.prompt(any())).thenReturn(appName);
|
||||
when(() => codePushClient.createApp(displayName: appName)).thenAnswer(
|
||||
(_) async => app,
|
||||
);
|
||||
|
||||
await runWithOverrides(
|
||||
() => codePushClientWrapper.createApp(),
|
||||
);
|
||||
|
||||
verify(() => logger.prompt(any())).called(1);
|
||||
verify(
|
||||
() => codePushClient.createApp(displayName: appName),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('does not prompt for displayName when not provided', () async {
|
||||
const appName = 'test app';
|
||||
const app = App(id: appId, displayName: 'Test App');
|
||||
when(() => codePushClient.createApp(displayName: appName)).thenAnswer(
|
||||
(_) async => app,
|
||||
);
|
||||
|
||||
await runWithOverrides(
|
||||
() => codePushClientWrapper.createApp(appName: appName),
|
||||
);
|
||||
|
||||
verifyNever(() => logger.prompt(any()));
|
||||
verify(
|
||||
() => codePushClient.createApp(displayName: appName),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('getApps', () {
|
||||
test('exits with code 70 when getting apps fails', () async {
|
||||
const error = 'something went wrong';
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
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/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.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 _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
void main() {
|
||||
group(ShorebirdCliCommandRunner, () {
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
const shorebirdEngineRevision = 'test-revision';
|
||||
|
||||
late Logger logger;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdProcessResult processResult;
|
||||
late ShorebirdCliCommandRunner commandRunner;
|
||||
|
||||
@@ -31,20 +28,20 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
loggerRef.overrideWith(() => logger)
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
logger = _MockLogger();
|
||||
ShorebirdEnvironment.shorebirdEngineRevision = 'test-revision';
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
processResult = _MockProcessResult();
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => processResult.exitCode).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => shorebirdEnv.shorebirdEngineRevision,
|
||||
).thenReturn(shorebirdEngineRevision);
|
||||
commandRunner = runWithOverrides(ShorebirdCliCommandRunner.new);
|
||||
});
|
||||
|
||||
@@ -122,7 +119,7 @@ ${lightCyan.wrap('shorebird release android -- --no-pub lib/main.dart')}''',
|
||||
() => logger.info(
|
||||
'''
|
||||
Shorebird $packageVersion
|
||||
Shorebird Engine • revision ${ShorebirdEnvironment.shorebirdEngineRevision}''',
|
||||
Shorebird Engine • revision $shorebirdEngineRevision''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
+10
-28
@@ -1,20 +1,18 @@
|
||||
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';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/account/account.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
@@ -30,9 +28,8 @@ void main() {
|
||||
hasActiveSubscription: true,
|
||||
);
|
||||
|
||||
late Auth auth;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late http.Client httpClient;
|
||||
late Logger logger;
|
||||
late Progress progress;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
@@ -42,7 +39,7 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
@@ -50,14 +47,15 @@ void main() {
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
httpClient = _MockHttpClient();
|
||||
logger = _MockLogger();
|
||||
progress = _MockProgress();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
@@ -65,16 +63,7 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(
|
||||
() => DowngradeAccountCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
);
|
||||
command = runWithOverrides(DowngradeAccountCommand.new);
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
@@ -100,7 +89,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('prints an error if fetch current user fails', () async {
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => codePushClient.getCurrentUser()).thenThrow(
|
||||
Exception('an error occurred'),
|
||||
);
|
||||
@@ -114,7 +102,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('prints an error if fetch current user returns null', () async {
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => codePushClient.getCurrentUser()).thenAnswer((_) async => null);
|
||||
|
||||
final result = await runWithOverrides(command.run);
|
||||
@@ -130,7 +117,6 @@ void main() {
|
||||
test(
|
||||
'prints an error if the user does not have an active subscription',
|
||||
() async {
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(
|
||||
() => codePushClient.getCurrentUser(),
|
||||
).thenAnswer((_) async => noSubscriptionUser);
|
||||
@@ -147,7 +133,6 @@ void main() {
|
||||
);
|
||||
|
||||
test('exits successfully if the user opts not to cancel', () async {
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(
|
||||
() => codePushClient.getCurrentUser(),
|
||||
).thenAnswer((_) async => subscriptionUser);
|
||||
@@ -162,7 +147,6 @@ void main() {
|
||||
});
|
||||
|
||||
test('prints an error if call to cancel subscription fails', () async {
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(
|
||||
() => codePushClient.getCurrentUser(),
|
||||
).thenAnswer((_) async => subscriptionUser);
|
||||
@@ -184,8 +168,6 @@ void main() {
|
||||
test('exits successfully on subscription cancellation', () async {
|
||||
// Fri Apr 14 2023 07:00:00 GMT+0000
|
||||
const cancellationTimestamp = 1681455600;
|
||||
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(
|
||||
() => codePushClient.getCurrentUser(),
|
||||
).thenAnswer((_) async => subscriptionUser);
|
||||
|
||||
+10
-20
@@ -1,20 +1,18 @@
|
||||
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';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/account/account.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
@@ -26,9 +24,8 @@ class _MockUser extends Mock implements User {}
|
||||
void main() {
|
||||
final paymentLink = Uri.parse('https://example.com/payment-link');
|
||||
|
||||
late Auth auth;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late http.Client httpClient;
|
||||
late Logger logger;
|
||||
late Progress progress;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
@@ -40,7 +37,7 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
@@ -48,17 +45,16 @@ void main() {
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
httpClient = _MockHttpClient();
|
||||
logger = _MockLogger();
|
||||
progress = _MockProgress();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
user = _MockUser();
|
||||
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
when(
|
||||
() => codePushClient.createPaymentLink(),
|
||||
).thenAnswer((_) async => paymentLink);
|
||||
@@ -76,13 +72,7 @@ void main() {
|
||||
|
||||
when(() => user.hasActiveSubscription).thenReturn(false);
|
||||
|
||||
command = runWithOverrides(
|
||||
() => UpgradeAccountCommand(
|
||||
buildCodePushClient: ({required httpClient, hostedUri}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
);
|
||||
command = runWithOverrides(UpgradeAccountCommand.new);
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import 'package:args/args.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';
|
||||
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_validator.dart';
|
||||
@@ -12,11 +11,8 @@ import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
@@ -25,13 +21,11 @@ class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
void main() {
|
||||
group(CreateAppCommand, () {
|
||||
const appId = 'app-id';
|
||||
const displayName = 'Example App';
|
||||
const appName = 'Example App';
|
||||
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late Logger logger;
|
||||
late CodePushClient codePushClient;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late CreateAppCommand command;
|
||||
|
||||
@@ -39,7 +33,7 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
@@ -48,30 +42,22 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
logger = _MockLogger();
|
||||
codePushClient = _MockCodePushClient();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => argResults['app-name']).thenReturn(appName);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => codePushClientWrapper.createApp(appName: appName),
|
||||
).thenAnswer((_) async => const App(id: appId, displayName: appName));
|
||||
|
||||
command = runWithOverrides(
|
||||
() => CreateAppCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(CreateAppCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
@@ -96,42 +82,28 @@ void main() {
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('prompts for app name when not provided', () async {
|
||||
when(
|
||||
() => logger.prompt(any(), defaultValue: any(named: 'defaultValue')),
|
||||
).thenReturn(displayName);
|
||||
test('calls createApp with no app-name when not provided', () async {
|
||||
when(() => argResults['app-name']).thenReturn(null);
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => logger.prompt(any(), defaultValue: any(named: 'defaultValue')),
|
||||
).called(1);
|
||||
verify(
|
||||
() => codePushClient.createApp(displayName: displayName),
|
||||
).called(1);
|
||||
verify(() => codePushClientWrapper.createApp()).called(1);
|
||||
});
|
||||
|
||||
test('uses provided app name when provided', () async {
|
||||
when(() => argResults['app-name']).thenReturn(displayName);
|
||||
await runWithOverrides(command.run);
|
||||
verifyNever(() => logger.prompt(any()));
|
||||
verify(
|
||||
() => codePushClient.createApp(displayName: displayName),
|
||||
() => codePushClientWrapper.createApp(appName: appName),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('returns success when app is created', () async {
|
||||
when(() => argResults['app-name']).thenReturn(displayName);
|
||||
when(
|
||||
() => codePushClient.createApp(displayName: displayName),
|
||||
).thenAnswer((_) async => const App(id: appId, displayName: displayName));
|
||||
final result = await runWithOverrides(command.run);
|
||||
expect(result, ExitCode.success.code);
|
||||
});
|
||||
|
||||
test('returns software error when app creation fails', () async {
|
||||
final error = Exception('oops');
|
||||
when(() => argResults['app-name']).thenReturn(displayName);
|
||||
when(
|
||||
() => codePushClient.createApp(displayName: displayName),
|
||||
() => codePushClientWrapper.createApp(appName: appName),
|
||||
).thenThrow(error);
|
||||
final result = await runWithOverrides(command.run);
|
||||
expect(result, ExitCode.software.code);
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
import 'package:args/args.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';
|
||||
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_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
@@ -22,15 +21,17 @@ class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
void main() {
|
||||
group(DeleteAppCommand, () {
|
||||
const appId = 'example';
|
||||
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late Logger logger;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late DeleteAppCommand command;
|
||||
|
||||
@@ -38,8 +39,9 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
@@ -47,30 +49,23 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
logger = _MockLogger();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
|
||||
command = runWithOverrides(
|
||||
() => DeleteAppCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(DeleteAppCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
|
||||
@@ -1,67 +1,38 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
void main() {
|
||||
group(BuildAarCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const buildNumber = '1.0';
|
||||
const noModulePubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.0
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
const pubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.0
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
module:
|
||||
androidX: true
|
||||
androidPackage: com.example.my_flutter_module
|
||||
iosBundleIdentifier: com.example.myFlutterModule
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
const androidPackageName = 'com.example.my_flutter_module';
|
||||
|
||||
late ArgResults argResults;
|
||||
late Auth auth;
|
||||
late http.Client httpClient;
|
||||
late Logger logger;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdProcessResult processResult;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
@@ -71,41 +42,25 @@ flutter:
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory setUpTempDir({bool includeModule = true}) {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(
|
||||
includeModule ? pubspecYamlContent : noModulePubspecYamlContent,
|
||||
);
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: $appId');
|
||||
return tempDir;
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
auth = _MockAuth();
|
||||
httpClient = _MockHttpClient();
|
||||
logger = _MockLogger();
|
||||
processResult = _MockProcessResult();
|
||||
progress = _MockProgress();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['build-number']).thenReturn(buildNumber);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
|
||||
when(
|
||||
@@ -125,6 +80,10 @@ flutter:
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
when(
|
||||
() => shorebirdEnv.androidPackageName,
|
||||
).thenReturn(androidPackageName);
|
||||
|
||||
command = runWithOverrides(BuildAarCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
@@ -153,35 +112,17 @@ flutter:
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with 78 if no pubspec.yaml exists', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
final result = await IOOverrides.runZoned(
|
||||
() async => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(result, ExitCode.config.code);
|
||||
});
|
||||
|
||||
test('exits with 78 if no module entry exists in pubspec.yaml', () async {
|
||||
final tempDir = setUpTempDir(includeModule: false);
|
||||
final result = await IOOverrides.runZoned(
|
||||
() async => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
when(() => shorebirdEnv.androidPackageName).thenReturn(null);
|
||||
final result = await runWithOverrides(command.run);
|
||||
expect(result, ExitCode.config.code);
|
||||
});
|
||||
|
||||
test('exits with code 70 when building aar fails', () async {
|
||||
when(() => processResult.exitCode).thenReturn(1);
|
||||
when(() => processResult.stderr).thenReturn('oops');
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final result = await IOOverrides.runZoned(
|
||||
() async => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.software.code));
|
||||
verify(
|
||||
@@ -204,11 +145,7 @@ flutter:
|
||||
|
||||
test('exits with code 0 when building aar succeeds', () async {
|
||||
when(() => processResult.exitCode).thenReturn(ExitCode.success.code);
|
||||
final tempDir = setUpTempDir();
|
||||
final result = await IOOverrides.runZoned(
|
||||
() async => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.success.code));
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
@@ -17,10 +15,6 @@ import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockDoctor extends Mock implements Doctor {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
@@ -36,11 +30,11 @@ class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
|
||||
void main() {
|
||||
group(BuildApkCommand, () {
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late Doctor doctor;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult processResult;
|
||||
@@ -53,7 +47,6 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
@@ -62,10 +55,12 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(_FakeShorebirdProcess());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
doctor = _MockDoctor();
|
||||
logger = _MockLogger();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
@@ -73,8 +68,6 @@ void main() {
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
registerFallbackValue(shorebirdProcess);
|
||||
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
any(),
|
||||
@@ -83,8 +76,6 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async => processResult);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => logger.progress(any())).thenReturn(_MockProgress());
|
||||
when(() => logger.info(any())).thenReturn(null);
|
||||
when(
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
@@ -17,10 +15,6 @@ import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockDoctor extends Mock implements Doctor {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
@@ -41,8 +35,6 @@ class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
void main() {
|
||||
group(BuildAppBundleCommand, () {
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late Doctor doctor;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult processResult;
|
||||
@@ -55,7 +47,6 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
engineConfigRef.overrideWith(() => const EngineConfig.empty()),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
@@ -72,8 +63,6 @@ void main() {
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
doctor = _MockDoctor();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
logger = _MockLogger();
|
||||
processResult = _MockProcessResult();
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
@@ -88,8 +77,6 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async => processResult);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => logger.progress(any())).thenReturn(_MockProgress());
|
||||
when(() => logger.info(any())).thenReturn(null);
|
||||
when(
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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:propertylistserialization/propertylistserialization.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
@@ -18,10 +16,6 @@ import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockDoctor extends Mock implements Doctor {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
@@ -42,8 +36,6 @@ class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
void main() {
|
||||
group(BuildIpaCommand, () {
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late Doctor doctor;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult processResult;
|
||||
@@ -56,7 +48,6 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
@@ -71,8 +62,6 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
doctor = _MockDoctor();
|
||||
logger = _MockLogger();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
@@ -89,8 +78,6 @@ void main() {
|
||||
).thenAnswer((_) async => processResult);
|
||||
when(() => argResults['codesign']).thenReturn(true);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => logger.progress(any())).thenReturn(_MockProgress());
|
||||
when(() => logger.info(any())).thenReturn(null);
|
||||
when(() => doctor.iosCommandValidators).thenReturn([flutterValidator]);
|
||||
|
||||
+8
-10
@@ -2,13 +2,13 @@ import 'dart:io';
|
||||
|
||||
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/cache.dart';
|
||||
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_env.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockCache extends Mock implements Cache {}
|
||||
@@ -19,12 +19,15 @@ class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
void main() {
|
||||
group('cache clean', () {
|
||||
late Cache cache;
|
||||
late Logger logger;
|
||||
late Platform platform;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late CleanCacheCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -34,6 +37,7 @@ void main() {
|
||||
cacheRef.overrideWith(() => cache),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -43,18 +47,12 @@ void main() {
|
||||
logger = _MockLogger();
|
||||
platform = _MockPlatform();
|
||||
progress = _MockProgress();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
command = runWithOverrides(CleanCacheCommand.new);
|
||||
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
Directory.systemTemp.createTempSync().path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(
|
||||
Directory.systemTemp.createTempSync(),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
+21
-22
@@ -1,20 +1,20 @@
|
||||
import 'package:args/args.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';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
@@ -22,19 +22,22 @@ class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
void main() {
|
||||
group(AddCollaboratorsCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const email = 'jane.doe@shorebird.dev';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late Logger logger;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late AddCollaboratorsCommand command;
|
||||
|
||||
@@ -42,8 +45,9 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
@@ -51,35 +55,29 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
logger = _MockLogger();
|
||||
progress = _MockProgress();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['app-id']).thenReturn(appId);
|
||||
when(() => argResults['email']).thenReturn(email);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
when(() => logger.confirm(any())).thenReturn(true);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(
|
||||
() => AddCollaboratorsCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(AddCollaboratorsCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('name is correct', () {
|
||||
@@ -113,6 +111,7 @@ void main() {
|
||||
|
||||
test('returns ExitCode.usage when app id is missing.', () async {
|
||||
when(() => argResults['app-id']).thenReturn(null);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(null);
|
||||
expect(await runWithOverrides(command.run), ExitCode.usage.code);
|
||||
});
|
||||
|
||||
|
||||
+21
-22
@@ -1,23 +1,23 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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: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/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
@@ -25,12 +25,15 @@ class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
void main() {
|
||||
group(DeleteCollaboratorsCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const email = 'jane.doe@shorebird.dev';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const collaborator = Collaborator(
|
||||
userId: 0,
|
||||
email: email,
|
||||
@@ -38,11 +41,11 @@ void main() {
|
||||
);
|
||||
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late Logger logger;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late DeleteCollaboratorsCommand command;
|
||||
|
||||
@@ -50,8 +53,9 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
@@ -59,19 +63,20 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
logger = _MockLogger();
|
||||
progress = _MockProgress();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['app-id']).thenReturn(appId);
|
||||
when(() => argResults['email']).thenReturn(email);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => logger.confirm(any())).thenReturn(true);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
when(
|
||||
() => codePushClient.getCollaborators(appId: any(named: 'appId')),
|
||||
).thenAnswer((_) async => [collaborator]);
|
||||
@@ -81,22 +86,15 @@ void main() {
|
||||
userId: any(named: 'userId'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(
|
||||
() => DeleteCollaboratorsCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(DeleteCollaboratorsCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('description is correct', () {
|
||||
@@ -126,6 +124,7 @@ void main() {
|
||||
|
||||
test('returns ExitCode.usage when app id is missing.', () async {
|
||||
when(() => argResults['app-id']).thenReturn(null);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(null);
|
||||
expect(await runWithOverrides(command.run), ExitCode.usage.code);
|
||||
});
|
||||
|
||||
|
||||
+21
-22
@@ -1,36 +1,39 @@
|
||||
import 'package:args/args.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';
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
void main() {
|
||||
group(ListCollaboratorsCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late Logger logger;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ListCollaboratorsCommand command;
|
||||
|
||||
@@ -38,8 +41,9 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
@@ -47,31 +51,25 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
logger = _MockLogger();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['app-id']).thenReturn(appId);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(
|
||||
() => ListCollaboratorsCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(ListCollaboratorsCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('name is correct', () {
|
||||
@@ -109,6 +107,7 @@ void main() {
|
||||
|
||||
test('returns ExitCode.usage when app id is missing.', () async {
|
||||
when(() => argResults['app-id']).thenReturn(null);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(null);
|
||||
expect(await runWithOverrides(command.run), ExitCode.usage.code);
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
import 'package:shorebird_cli/src/version.dart';
|
||||
import 'package:test/test.dart';
|
||||
@@ -16,14 +16,19 @@ class _MockDoctor extends Mock implements Doctor {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockValidator extends Mock implements Validator {}
|
||||
|
||||
void main() {
|
||||
group('doctor', () {
|
||||
const shorebirdEngineRevision = 'test-revision';
|
||||
|
||||
late ArgResults argResults;
|
||||
late Doctor doctor;
|
||||
late DoctorCommand command;
|
||||
late Logger logger;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late Validator validator;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -32,6 +37,7 @@ void main() {
|
||||
values: {
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -40,10 +46,12 @@ void main() {
|
||||
argResults = _MockArgResults();
|
||||
doctor = _MockDoctor();
|
||||
logger = _MockLogger();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
validator = _MockValidator();
|
||||
|
||||
ShorebirdEnvironment.shorebirdEngineRevision = 'test-revision';
|
||||
|
||||
when(
|
||||
() => shorebirdEnv.shorebirdEngineRevision,
|
||||
).thenReturn(shorebirdEngineRevision);
|
||||
when(() => doctor.allValidators).thenReturn([validator]);
|
||||
when(
|
||||
() => doctor.runValidators(any(), applyFixes: any(named: 'applyFixes')),
|
||||
@@ -60,7 +68,7 @@ void main() {
|
||||
() => logger.info('''
|
||||
|
||||
Shorebird v$packageVersion
|
||||
Shorebird Engine • revision ${ShorebirdEnvironment.shorebirdEngineRevision}
|
||||
Shorebird Engine • revision $shorebirdEngineRevision
|
||||
'''),
|
||||
).called(1);
|
||||
});
|
||||
@@ -79,8 +87,9 @@ Shorebird Engine • revision ${ShorebirdEnvironment.shorebirdEngineRevision}
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.success.code));
|
||||
verify(() => doctor.runValidators([validator], applyFixes: true))
|
||||
.called(1);
|
||||
verify(
|
||||
() => doctor.runValidators([validator], applyFixes: true),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import 'dart:io' hide Platform;
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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/commands/init_command.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/gradlew.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/xcodebuild.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
@@ -21,22 +21,23 @@ import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockDoctor extends Mock implements Doctor {}
|
||||
|
||||
class _MockGradlew extends Mock implements Gradlew {}
|
||||
|
||||
class _MockFile extends Mock implements File {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockXcodeBuild extends Mock implements XcodeBuild {}
|
||||
@@ -47,22 +48,22 @@ void main() {
|
||||
const appId = 'test_app_id';
|
||||
const appName = 'test_app_name';
|
||||
const app = App(id: appId, displayName: appName);
|
||||
const appMetadata = AppMetadata(appId: appId, displayName: appName);
|
||||
const pubspecYamlContent = '''
|
||||
name: $appName
|
||||
version: $version
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"''';
|
||||
|
||||
late http.Client httpClient;
|
||||
late ArgResults argResults;
|
||||
late Auth auth;
|
||||
late Doctor doctor;
|
||||
late Gradlew gradlew;
|
||||
late CodePushClient codePushClient;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late File shorebirdYamlFile;
|
||||
late File pubspecYamlFile;
|
||||
late Logger logger;
|
||||
late Platform platform;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late XcodeBuild xcodeBuild;
|
||||
late InitCommand command;
|
||||
@@ -71,56 +72,59 @@ environment:
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
gradlewRef.overrideWith(() => gradlew),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => process),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
xcodeBuildRef.overrideWith(() => xcodeBuild),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory setUpAppTempDir() {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
Directory(p.join(tempDir.path, 'android')).createSync(recursive: true);
|
||||
Directory(p.join(tempDir.path, 'ios')).createSync(recursive: true);
|
||||
return tempDir;
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
httpClient = _MockHttpClient();
|
||||
argResults = _MockArgResults();
|
||||
auth = _MockAuth();
|
||||
doctor = _MockDoctor();
|
||||
gradlew = _MockGradlew();
|
||||
codePushClient = _MockCodePushClient();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
shorebirdYamlFile = _MockFile();
|
||||
pubspecYamlFile = _MockFile();
|
||||
logger = _MockLogger();
|
||||
platform = _MockPlatform();
|
||||
progress = _MockProgress();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
xcodeBuild = _MockXcodeBuild();
|
||||
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(
|
||||
() => codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((_) async => app);
|
||||
when(
|
||||
() => codePushClient.getApps(),
|
||||
).thenAnswer((_) async => [appMetadata]);
|
||||
when(
|
||||
() => doctor.runValidators(any(), applyFixes: any(named: 'applyFixes')),
|
||||
).thenAnswer((_) async => {});
|
||||
when(() => doctor.allValidators).thenReturn([]);
|
||||
when(
|
||||
() => shorebirdEnv.getShorebirdYamlFile(),
|
||||
).thenReturn(shorebirdYamlFile);
|
||||
when(() => shorebirdEnv.getPubspecYamlFile()).thenReturn(pubspecYamlFile);
|
||||
when(
|
||||
() => pubspecYamlFile.readAsStringSync(),
|
||||
).thenReturn(pubspecYamlContent);
|
||||
when(
|
||||
() => pubspecYamlFile.uri,
|
||||
).thenReturn(File(p.join('pubspec.yaml')).uri);
|
||||
when(
|
||||
() => logger.prompt(any(), defaultValue: any(named: 'defaultValue')),
|
||||
).thenReturn(appName);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(() => gradlew.productFlavors(any())).thenAnswer((_) async => {});
|
||||
when(() => platform.isMacOS).thenReturn(true);
|
||||
when(() => shorebirdEnv.hasPubspecYaml).thenReturn(true);
|
||||
when(() => shorebirdEnv.hasShorebirdYaml).thenReturn(false);
|
||||
when(() => shorebirdEnv.pubspecContainsShorebirdYaml).thenReturn(false);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
@@ -130,16 +134,7 @@ environment:
|
||||
() => xcodeBuild.list(any()),
|
||||
).thenAnswer((_) async => const XcodeProjectBuildInfo());
|
||||
|
||||
command = runWithOverrides(
|
||||
() => InitCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(InitCommand.new)..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('exits when validation fails', () async {
|
||||
@@ -161,11 +156,8 @@ environment:
|
||||
});
|
||||
|
||||
test('throws no input error when pubspec.yaml is not found.', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
when(() => shorebirdEnv.hasPubspecYaml).thenReturn(false);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => logger.err(
|
||||
'''
|
||||
@@ -178,30 +170,18 @@ Please make sure you are running "shorebird init" from the root of your Flutter
|
||||
});
|
||||
|
||||
test('throws software error when pubspec.yaml is malformed.', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(p.join(tempDir.path, 'pubspec.yaml')).createSync();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exception = Exception('oops');
|
||||
when(() => shorebirdEnv.hasPubspecYaml).thenThrow(exception);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => logger.err(
|
||||
any(that: contains('Error parsing "pubspec.yaml":')),
|
||||
),
|
||||
() => logger.err('Error parsing "pubspec.yaml": $exception'),
|
||||
).called(1);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
});
|
||||
|
||||
test('throws software error when shorebird.yaml already exists', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).createSync();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
when(() => shorebirdEnv.hasShorebirdYaml).thenReturn(true);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => logger.err(
|
||||
'''
|
||||
@@ -213,16 +193,9 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
});
|
||||
|
||||
test('--force overwrites existing shorebird.yaml', () async {
|
||||
when(() => shorebirdEnv.hasShorebirdYaml).thenReturn(true);
|
||||
when(() => argResults['force']).thenReturn(true);
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).createSync();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verifyNever(
|
||||
() => logger.err(
|
||||
'''
|
||||
@@ -231,23 +204,17 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
),
|
||||
);
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('app_id: $appId'),
|
||||
);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(that: contains('app_id: $appId')),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('fails when an error occurs while extracting flavors', () async {
|
||||
final exception = Exception('oops');
|
||||
when(() => gradlew.productFlavors(any())).thenThrow(exception);
|
||||
final tempDir = setUpAppTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(() => logger.progress('Detecting product flavors')).called(1);
|
||||
verify(
|
||||
() => logger.err(
|
||||
@@ -260,17 +227,10 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
|
||||
test('throws software error when error occurs creating app.', () async {
|
||||
final error = Exception('oops');
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
when(
|
||||
() => codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenThrow(error);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => logger.prompt(any(), defaultValue: any(named: 'defaultValue')),
|
||||
).called(1);
|
||||
@@ -285,9 +245,6 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
|
||||
test('throws software error when unable to detect schemes', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
Directory(p.join(tempDir.path, 'ios')).createSync(recursive: true);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
@@ -304,18 +261,16 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
|
||||
test('creates shorebird for an android-only app', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('app_id: $appId'),
|
||||
);
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(that: contains('app_id: $appId')),
|
||||
),
|
||||
).called(1);
|
||||
verifyNever(() => xcodeBuild.list(any()));
|
||||
});
|
||||
|
||||
@@ -324,9 +279,6 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
when(
|
||||
() => gradlew.productFlavors(any()),
|
||||
).thenThrow(MissingAndroidProjectException(tempDir.path));
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
File(
|
||||
p.join(
|
||||
tempDir.path,
|
||||
@@ -341,11 +293,12 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('app_id: $appId'),
|
||||
);
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(that: contains('app_id: $appId')),
|
||||
),
|
||||
).called(1);
|
||||
verifyNever(() => xcodeBuild.list(any()));
|
||||
});
|
||||
|
||||
@@ -353,19 +306,15 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
const appIds = ['test-appId-1', 'test-appId-2'];
|
||||
var index = 0;
|
||||
when(
|
||||
() =>
|
||||
codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((invocation) async {
|
||||
final displayName = invocation.namedArguments[#displayName] as String;
|
||||
return App(id: appIds[index++], displayName: displayName);
|
||||
final appName = invocation.namedArguments[#appName] as String?;
|
||||
return App(id: appIds[index++], displayName: appName ?? '-');
|
||||
});
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
when(
|
||||
() => gradlew.productFlavors(any()),
|
||||
).thenThrow(MissingAndroidProjectException(tempDir.path));
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
final schemesPath = p.join(
|
||||
tempDir.path,
|
||||
'ios',
|
||||
@@ -373,46 +322,45 @@ If you want to reinitialize Shorebird, please run "shorebird init --force".''',
|
||||
'xcshareddata',
|
||||
'xcschemes',
|
||||
);
|
||||
File(p.join(schemesPath, 'Runner.xcscheme'))
|
||||
.createSync(recursive: true);
|
||||
File(p.join(schemesPath, 'internal.xcscheme'))
|
||||
.createSync(recursive: true);
|
||||
File(p.join(schemesPath, 'stable.xcscheme'))
|
||||
.createSync(recursive: true);
|
||||
File(
|
||||
p.join(schemesPath, 'Runner.xcscheme'),
|
||||
).createSync(recursive: true);
|
||||
File(
|
||||
p.join(schemesPath, 'internal.xcscheme'),
|
||||
).createSync(recursive: true);
|
||||
File(
|
||||
p.join(schemesPath, 'stable.xcscheme'),
|
||||
).createSync(recursive: true);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('''
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: contains('''
|
||||
app_id: ${appIds[0]}
|
||||
flavors:
|
||||
internal: ${appIds[0]}
|
||||
stable: ${appIds[1]}'''),
|
||||
);
|
||||
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
verifyInOrder([
|
||||
() => codePushClient.createApp(displayName: '$appName (internal)'),
|
||||
() => codePushClient.createApp(displayName: '$appName (stable)'),
|
||||
() => codePushClientWrapper.createApp(appName: '$appName (internal)'),
|
||||
() => codePushClientWrapper.createApp(appName: '$appName (stable)'),
|
||||
]);
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
verifyNever(() => xcodeBuild.list(any()));
|
||||
});
|
||||
});
|
||||
|
||||
test('creates shorebird.yaml for an app without flavors', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('app_id: $appId'),
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(that: contains('app_id: $appId')),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -438,26 +386,19 @@ flavors:
|
||||
},
|
||||
);
|
||||
when(
|
||||
() =>
|
||||
codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((invocation) async {
|
||||
final displayName = invocation.namedArguments[#displayName] as String;
|
||||
return App(id: appIds[index++], displayName: displayName);
|
||||
final appName = invocation.namedArguments[#appName] as String?;
|
||||
return App(id: appIds[index++], displayName: appName ?? '--');
|
||||
});
|
||||
final tempDir = setUpAppTempDir();
|
||||
when(
|
||||
() => xcodeBuild.list(any()),
|
||||
).thenThrow(MissingIOSProjectException(tempDir.path));
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('''
|
||||
).thenThrow(const MissingIOSProjectException(''));
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: contains('''
|
||||
app_id: ${appIds[0]}
|
||||
flavors:
|
||||
development: ${appIds[0]}
|
||||
@@ -466,20 +407,27 @@ flavors:
|
||||
productionInternal: ${appIds[3]}
|
||||
staging: ${appIds[4]}
|
||||
stagingInternal: ${appIds[5]}'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
verifyInOrder([
|
||||
() => codePushClient.createApp(displayName: '$appName (development)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (developmentInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (development)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (production)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (productionInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (developmentInternal)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (staging)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (stagingInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (production)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (productionInternal)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (staging)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (stagingInternal)',
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -507,26 +455,19 @@ flavors:
|
||||
),
|
||||
);
|
||||
when(
|
||||
() =>
|
||||
codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((invocation) async {
|
||||
final displayName = invocation.namedArguments[#displayName] as String;
|
||||
return App(id: appIds[index++], displayName: displayName);
|
||||
final appName = invocation.namedArguments[#appName] as String?;
|
||||
return App(id: appIds[index++], displayName: appName ?? '-');
|
||||
});
|
||||
final tempDir = setUpAppTempDir();
|
||||
when(
|
||||
() => gradlew.productFlavors(any()),
|
||||
).thenThrow(MissingAndroidProjectException(tempDir.path));
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('''
|
||||
).thenThrow(const MissingAndroidProjectException(''));
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: contains('''
|
||||
app_id: ${appIds[0]}
|
||||
flavors:
|
||||
development: ${appIds[0]}
|
||||
@@ -535,20 +476,27 @@ flavors:
|
||||
productionInternal: ${appIds[3]}
|
||||
staging: ${appIds[4]}
|
||||
stagingInternal: ${appIds[5]}'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
verifyInOrder([
|
||||
() => codePushClient.createApp(displayName: '$appName (development)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (developmentInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (development)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (production)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (productionInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (developmentInternal)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (staging)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (stagingInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (production)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (productionInternal)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (staging)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (stagingInternal)',
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -578,23 +526,16 @@ flavors:
|
||||
);
|
||||
when(() => gradlew.productFlavors(any())).thenAnswer((_) async => {});
|
||||
when(
|
||||
() =>
|
||||
codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((invocation) async {
|
||||
final displayName = invocation.namedArguments[#displayName] as String;
|
||||
return App(id: appIds[index++], displayName: displayName);
|
||||
final appName = invocation.namedArguments[#appName] as String?;
|
||||
return App(id: appIds[index++], displayName: appName ?? '--');
|
||||
});
|
||||
final tempDir = setUpAppTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('''
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: contains('''
|
||||
app_id: ${appIds[0]}
|
||||
flavors:
|
||||
development: ${appIds[1]}
|
||||
@@ -603,20 +544,27 @@ flavors:
|
||||
productionInternal: ${appIds[4]}
|
||||
staging: ${appIds[5]}
|
||||
stagingInternal: ${appIds[6]}'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
verifyInOrder([
|
||||
() => codePushClient.createApp(displayName: '$appName (development)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (developmentInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (development)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (production)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (productionInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (developmentInternal)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (staging)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (stagingInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (production)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (productionInternal)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (staging)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (stagingInternal)',
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -646,23 +594,16 @@ flavors:
|
||||
},
|
||||
);
|
||||
when(
|
||||
() =>
|
||||
codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((invocation) async {
|
||||
final displayName = invocation.namedArguments[#displayName] as String;
|
||||
return App(id: appIds[index++], displayName: displayName);
|
||||
final appName = invocation.namedArguments[#appName] as String?;
|
||||
return App(id: appIds[index++], displayName: appName ?? '-');
|
||||
});
|
||||
final tempDir = setUpAppTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('''
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: contains('''
|
||||
app_id: ${appIds[0]}
|
||||
flavors:
|
||||
development: ${appIds[1]}
|
||||
@@ -671,20 +612,27 @@ flavors:
|
||||
productionInternal: ${appIds[4]}
|
||||
staging: ${appIds[5]}
|
||||
stagingInternal: ${appIds[6]}'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
verifyInOrder([
|
||||
() => codePushClient.createApp(displayName: '$appName (development)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (developmentInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (development)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (production)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (productionInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (developmentInternal)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (staging)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (stagingInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (production)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (productionInternal)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (staging)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (stagingInternal)',
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -714,23 +662,16 @@ flavors:
|
||||
(_) async => const XcodeProjectBuildInfo(schemes: variants),
|
||||
);
|
||||
when(
|
||||
() =>
|
||||
codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((invocation) async {
|
||||
final displayName = invocation.namedArguments[#displayName] as String;
|
||||
return App(id: appIds[index++], displayName: displayName);
|
||||
final appName = invocation.namedArguments[#appName] as String?;
|
||||
return App(id: appIds[index++], displayName: appName ?? '-');
|
||||
});
|
||||
final tempDir = setUpAppTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('''
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: contains('''
|
||||
app_id: ${appIds[0]}
|
||||
flavors:
|
||||
development: ${appIds[0]}
|
||||
@@ -739,20 +680,27 @@ flavors:
|
||||
productionInternal: ${appIds[3]}
|
||||
staging: ${appIds[4]}
|
||||
stagingInternal: ${appIds[5]}'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
verifyInOrder([
|
||||
() => codePushClient.createApp(displayName: '$appName (development)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (developmentInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (development)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (production)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (productionInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (developmentInternal)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (staging)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (stagingInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (production)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (productionInternal)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (staging)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (stagingInternal)',
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -790,23 +738,16 @@ flavors:
|
||||
(_) async => const XcodeProjectBuildInfo(schemes: iosVariants),
|
||||
);
|
||||
when(
|
||||
() =>
|
||||
codePushClient.createApp(displayName: any(named: 'displayName')),
|
||||
() => codePushClientWrapper.createApp(appName: any(named: 'appName')),
|
||||
).thenAnswer((invocation) async {
|
||||
final displayName = invocation.namedArguments[#displayName] as String;
|
||||
return App(id: appIds[index++], displayName: displayName);
|
||||
final appName = invocation.namedArguments[#appName] as String?;
|
||||
return App(id: appIds[index++], displayName: appName ?? '-');
|
||||
});
|
||||
final tempDir = setUpAppTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('''
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: contains('''
|
||||
app_id: test-appId-1
|
||||
flavors:
|
||||
dev: test-appId-1
|
||||
@@ -817,123 +758,114 @@ flavors:
|
||||
developmentInternal: test-appId-6
|
||||
staging: test-appId-7
|
||||
stagingInternal: test-appId-8'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
verifyInOrder([
|
||||
() => codePushClient.createApp(displayName: '$appName (dev)'),
|
||||
() => codePushClient.createApp(displayName: '$appName (devInternal)'),
|
||||
() => codePushClient.createApp(displayName: '$appName (production)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (productionInternal)',
|
||||
() => codePushClientWrapper.createApp(appName: '$appName (dev)'),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (devInternal)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (development)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (developmentInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (production)',
|
||||
),
|
||||
() => codePushClient.createApp(displayName: '$appName (staging)'),
|
||||
() => codePushClient.createApp(
|
||||
displayName: '$appName (stagingInternal)',
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (productionInternal)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (development)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (developmentInternal)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (staging)',
|
||||
),
|
||||
() => codePushClientWrapper.createApp(
|
||||
appName: '$appName (stagingInternal)',
|
||||
),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('detects existing shorebird.yaml in pubspec.yaml assets', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('''
|
||||
when(() => pubspecYamlFile.readAsStringSync()).thenReturn('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml
|
||||
''');
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'shorebird.yaml')).readAsStringSync(),
|
||||
contains('app_id: $appId'),
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => shorebirdYamlFile.writeAsStringSync(
|
||||
any(that: contains('app_id: $appId')),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('creates flutter.assets and adds shorebird.yaml', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'pubspec.yaml')).readAsStringSync(),
|
||||
equals('''
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => pubspecYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: equals('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml
|
||||
'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('creates assets and adds shorebird.yaml', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(p.join(tempDir.path, 'pubspec.yaml')).writeAsStringSync('''
|
||||
when(() => pubspecYamlFile.readAsStringSync()).thenReturn('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
''');
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'pubspec.yaml')).readAsStringSync(),
|
||||
equals('''
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => pubspecYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: equals('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml
|
||||
uses-material-design: true
|
||||
'''),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('adds shorebird.yaml to assets', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(p.join(tempDir.path, 'pubspec.yaml')).writeAsStringSync('''
|
||||
when(() => pubspecYamlFile.readAsStringSync()).thenReturn('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
assets:
|
||||
- some/asset.txt
|
||||
''');
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(
|
||||
File(p.join(tempDir.path, 'pubspec.yaml')).readAsStringSync(),
|
||||
equals('''
|
||||
await runWithOverrides(command.run);
|
||||
verify(
|
||||
() => pubspecYamlFile.writeAsStringSync(
|
||||
any(
|
||||
that: equals('''
|
||||
$pubspecYamlContent
|
||||
flutter:
|
||||
assets:
|
||||
- some/asset.txt
|
||||
- shorebird.yaml
|
||||
'''),
|
||||
);
|
||||
),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('fixes fixable validation errors', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
await runWithOverrides(command.run);
|
||||
verify(() => doctor.runValidators(any(), applyFixes: true)).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,12 +12,14 @@ import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/cache.dart' show Cache, cacheRef;
|
||||
import 'package:shorebird_cli/src/code_push_client_wrapper.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_build_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
@@ -44,16 +46,22 @@ class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
|
||||
void main() {
|
||||
group(PatchAarCommand, () {
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const buildNumber = '1.0';
|
||||
const versionName = '1.2.3';
|
||||
const versionCode = '1';
|
||||
@@ -63,6 +71,7 @@ void main() {
|
||||
const channelName = 'stable';
|
||||
const appDisplayName = 'Test App';
|
||||
const appMetadata = AppMetadata(appId: appId, displayName: appDisplayName);
|
||||
const androidPackageName = 'com.example.my_flutter_module';
|
||||
const releaseArtifact = ReleaseArtifact(
|
||||
id: 0,
|
||||
releaseId: 0,
|
||||
@@ -89,45 +98,24 @@ void main() {
|
||||
displayName: '1.2.3+1',
|
||||
platformStatuses: {},
|
||||
);
|
||||
const noModulePubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.0
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
const pubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.0
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
module:
|
||||
androidX: true
|
||||
androidPackage: com.example.my_flutter_module
|
||||
iosBundleIdentifier: com.example.myFlutterModule
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
late AarDiffer aarDiffer;
|
||||
late ArgResults argResults;
|
||||
late Auth auth;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late Directory shorebirdRoot;
|
||||
late Directory flutterDirectory;
|
||||
late Platform platform;
|
||||
late Progress progress;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late ShorebirdProcessResult patchProcessResult;
|
||||
late http.Client httpClient;
|
||||
late Cache cache;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late PatchAarCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -141,23 +129,16 @@ flutter:
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory setUpTempDir({bool includeModule = true}) {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(
|
||||
includeModule ? pubspecYamlContent : noModulePubspecYamlContent,
|
||||
);
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: $appId');
|
||||
return tempDir;
|
||||
}
|
||||
Directory setUpTempDir() => Directory.systemTemp.createTempSync();
|
||||
|
||||
void setUpTempArtifacts(Directory dir) {
|
||||
final aarDir = p.join(
|
||||
@@ -199,30 +180,30 @@ flutter:
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
shorebirdRoot = Directory.systemTemp.createTempSync();
|
||||
flutterDirectory = Directory(
|
||||
p.join(shorebirdRoot.path, 'bin', 'cache', 'flutter'),
|
||||
);
|
||||
platform = _MockPlatform();
|
||||
progress = _MockProgress();
|
||||
logger = _MockLogger();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
patchProcessResult = _MockProcessResult();
|
||||
httpClient = _MockHttpClient();
|
||||
cache = _MockCache();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
|
||||
registerFallbackValue(ReleasePlatform.android);
|
||||
|
||||
when(() => platform.environment).thenReturn({});
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
when(() => shorebirdEnv.flutterDirectory).thenReturn(flutterDirectory);
|
||||
when(
|
||||
() => shorebirdEnv.androidPackageName,
|
||||
).thenReturn(androidPackageName);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
@@ -230,14 +211,6 @@ flutter:
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterBuildProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
any(that: endsWith('patch')),
|
||||
@@ -253,10 +226,12 @@ flutter:
|
||||
return patchProcessResult;
|
||||
});
|
||||
|
||||
when(() => aarDiffer.changedFiles(any(), any()))
|
||||
.thenReturn(FileSetDiff.empty());
|
||||
when(() => aarDiffer.containsPotentiallyBreakingAssetDiffs(any()))
|
||||
.thenReturn(false);
|
||||
when(
|
||||
() => aarDiffer.changedFiles(any(), any()),
|
||||
).thenReturn(FileSetDiff.empty());
|
||||
when(
|
||||
() => aarDiffer.containsPotentiallyBreakingAssetDiffs(any()),
|
||||
).thenReturn(false);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults['channel']).thenReturn(channelName);
|
||||
when(() => argResults['dry-run']).thenReturn(false);
|
||||
@@ -273,14 +248,6 @@ flutter:
|
||||
when(
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
|
||||
when(
|
||||
() => flutterRevisionProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
|
||||
when(() => patchProcessResult.exitCode).thenReturn(ExitCode.success.code);
|
||||
when(() => httpClient.send(any())).thenAnswer(
|
||||
(_) async => http.StreamedResponse(const Stream.empty(), HttpStatus.ok),
|
||||
@@ -335,6 +302,9 @@ flutter:
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
|
||||
command = runWithOverrides(
|
||||
() => PatchAarCommand(
|
||||
@@ -370,26 +340,15 @@ flutter:
|
||||
});
|
||||
|
||||
test('exits with 78 if no module entry exists in pubspec.yaml', () async {
|
||||
final tempDir = setUpTempDir(includeModule: false);
|
||||
|
||||
final result = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(result, ExitCode.config.code);
|
||||
when(() => shorebirdEnv.androidPackageName).thenReturn(null);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.config.code);
|
||||
});
|
||||
|
||||
test('exits with code 70 when building fails', () async {
|
||||
when(() => flutterBuildProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterBuildProcessResult.stderr).thenReturn('oops');
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, equals(ExitCode.software.code));
|
||||
});
|
||||
|
||||
@@ -398,11 +357,7 @@ flutter:
|
||||
'both --dry-run and --force are specified', () async {
|
||||
when(() => argResults['dry-run']).thenReturn(true);
|
||||
when(() => argResults['force']).thenReturn(true);
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, equals(ExitCode.usage.code));
|
||||
});
|
||||
|
||||
@@ -469,9 +424,10 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
);
|
||||
|
||||
test('errors when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -479,21 +435,17 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'errors when shorebird flutter revision '
|
||||
'does not match release revision', () async {
|
||||
const otherRevision = 'other-revision';
|
||||
when(() => flutterRevisionProcessResult.stdout).thenReturn(otherRevision);
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => otherRevision);
|
||||
final tempDir = setUpTempDir();
|
||||
final flutterDir =
|
||||
runWithOverrides(() => ShorebirdEnvironment.flutterDirectory.path);
|
||||
setUpTempArtifacts(tempDir);
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -504,21 +456,11 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => logger.err('''
|
||||
Flutter revision mismatch.
|
||||
|
||||
The release you are trying to patch was built with a different version of Flutter.
|
||||
|
||||
Release Flutter Revision: $flutterRevision
|
||||
Current Flutter Revision: $otherRevision
|
||||
'''),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info('''
|
||||
Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release aar')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd $flutterDir')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
|
||||
@@ -14,14 +14,16 @@ import 'package:shorebird_cli/src/bundletool.dart';
|
||||
import 'package:shorebird_cli/src/cache.dart' show Cache, cacheRef;
|
||||
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/config/config.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/java.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_build_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.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';
|
||||
@@ -55,6 +57,8 @@ class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdFlutterValidator extends Mock
|
||||
implements ShorebirdFlutterValidator {}
|
||||
|
||||
@@ -62,12 +66,16 @@ class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
|
||||
void main() {
|
||||
group(PatchAndroidCommand, () {
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const versionName = '1.2.3';
|
||||
const versionCode = '1';
|
||||
const version = '$versionName+$versionCode';
|
||||
@@ -117,20 +125,22 @@ flutter:
|
||||
late Auth auth;
|
||||
late Bundletool bundletool;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late Directory flutterDirectory;
|
||||
late Directory shorebirdRoot;
|
||||
late Doctor doctor;
|
||||
late Java java;
|
||||
late Platform platform;
|
||||
late Progress progress;
|
||||
late Logger logger;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late ShorebirdProcessResult patchProcessResult;
|
||||
late http.Client httpClient;
|
||||
late Cache cache;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late PatchAndroidCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -145,9 +155,13 @@ flutter:
|
||||
engineConfigRef.overrideWith(() => const EngineConfig.empty()),
|
||||
javaRef.overrideWith(() => java),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -198,17 +212,21 @@ flutter:
|
||||
doctor = _MockDoctor();
|
||||
java = _MockJava();
|
||||
shorebirdRoot = Directory.systemTemp.createTempSync();
|
||||
flutterDirectory = Directory(
|
||||
p.join(shorebirdRoot.path, 'bin', 'cache', 'flutter'),
|
||||
);
|
||||
platform = _MockPlatform();
|
||||
progress = _MockProgress();
|
||||
logger = _MockLogger();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
patchProcessResult = _MockProcessResult();
|
||||
httpClient = _MockHttpClient();
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
cache = _MockCache();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
command = runWithOverrides(
|
||||
() => PatchAndroidCommand(
|
||||
aabDiffer: aabDiffer,
|
||||
@@ -216,16 +234,9 @@ flutter:
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
when(() => shorebirdEnv.flutterDirectory).thenReturn(flutterDirectory);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
@@ -233,14 +244,6 @@ flutter:
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterBuildProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
any(that: endsWith('patch')),
|
||||
@@ -255,17 +258,23 @@ flutter:
|
||||
..writeAsStringSync('diff');
|
||||
return patchProcessResult;
|
||||
});
|
||||
when(() => patchProcessResult.exitCode).thenReturn(ExitCode.success.code);
|
||||
|
||||
when(() => aabDiffer.changedFiles(any(), any()))
|
||||
.thenReturn(FileSetDiff.empty());
|
||||
when(() => aabDiffer.assetsFileSetDiff(any()))
|
||||
.thenReturn(FileSetDiff.empty());
|
||||
when(() => aabDiffer.nativeFileSetDiff(any()))
|
||||
.thenReturn(FileSetDiff.empty());
|
||||
when(() => aabDiffer.containsPotentiallyBreakingAssetDiffs(any()))
|
||||
.thenReturn(false);
|
||||
when(() => aabDiffer.containsPotentiallyBreakingNativeDiffs(any()))
|
||||
.thenReturn(false);
|
||||
when(
|
||||
() => aabDiffer.changedFiles(any(), any()),
|
||||
).thenReturn(FileSetDiff.empty());
|
||||
when(
|
||||
() => aabDiffer.assetsFileSetDiff(any()),
|
||||
).thenReturn(FileSetDiff.empty());
|
||||
when(
|
||||
() => aabDiffer.nativeFileSetDiff(any()),
|
||||
).thenReturn(FileSetDiff.empty());
|
||||
when(
|
||||
() => aabDiffer.containsPotentiallyBreakingAssetDiffs(any()),
|
||||
).thenReturn(false);
|
||||
when(
|
||||
() => aabDiffer.containsPotentiallyBreakingNativeDiffs(any()),
|
||||
).thenReturn(false);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults['arch']).thenReturn(arch);
|
||||
when(() => argResults['channel']).thenReturn(channelName);
|
||||
@@ -281,13 +290,6 @@ flutter:
|
||||
when(
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(() => patchProcessResult.exitCode).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
when(() => httpClient.send(any())).thenAnswer(
|
||||
(_) async => http.StreamedResponse(const Stream.empty(), HttpStatus.ok),
|
||||
);
|
||||
@@ -354,6 +356,9 @@ flutter:
|
||||
validators: any(named: 'validators'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
@@ -483,9 +488,10 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
);
|
||||
|
||||
test('errors when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -493,45 +499,32 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'errors when shorebird flutter revision '
|
||||
'does not match release revision', () async {
|
||||
const otherRevision = 'other-revision';
|
||||
when(() => flutterRevisionProcessResult.stdout).thenReturn(otherRevision);
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => otherRevision);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
final shorebirdFlutterPath = runWithOverrides(
|
||||
() => ShorebirdEnvironment.flutterDirectory.path,
|
||||
);
|
||||
verify(
|
||||
() => logger.err('''
|
||||
Flutter revision mismatch.
|
||||
|
||||
The release you are trying to patch was built with a different version of Flutter.
|
||||
|
||||
Release Flutter Revision: $flutterRevision
|
||||
Current Flutter Revision: $otherRevision
|
||||
'''),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info('''
|
||||
Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release')}
|
||||
${lightCyan.wrap('shorebird release aar')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd $shorebirdFlutterPath')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
@@ -846,7 +839,6 @@ https://github.com/shorebirdtech/shorebird/issues/472
|
||||
).called(1);
|
||||
verify(() => logger.success('\n✅ Published Patch!')).called(1);
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
// expect(capturedHostedUri, isNull);
|
||||
});
|
||||
|
||||
test(
|
||||
|
||||
@@ -12,12 +12,14 @@ 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/commands/patch/patch.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.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';
|
||||
@@ -48,6 +50,8 @@ class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdFlutterValidator extends Mock
|
||||
implements ShorebirdFlutterValidator {}
|
||||
|
||||
@@ -55,11 +59,15 @@ class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
|
||||
void main() {
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const versionName = '1.2.3';
|
||||
const versionCode = '1';
|
||||
const version = '$versionName+$versionCode';
|
||||
@@ -101,6 +109,9 @@ flutter:
|
||||
late ArgResults argResults;
|
||||
late Auth auth;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late Directory flutterDirectory;
|
||||
late Directory shorebirdRoot;
|
||||
late File genSnapshotFile;
|
||||
late Doctor doctor;
|
||||
late Ipa ipa;
|
||||
late IpaReader ipaReader;
|
||||
@@ -109,11 +120,12 @@ flutter:
|
||||
late Platform platform;
|
||||
late ShorebirdProcessResult aotBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late http.Client httpClient;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late PatchIosCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -126,7 +138,11 @@ flutter:
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -178,6 +194,21 @@ flutter:
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
doctor = _MockDoctor();
|
||||
shorebirdRoot = Directory.systemTemp.createTempSync();
|
||||
flutterDirectory = Directory(
|
||||
p.join(shorebirdRoot.path, 'bin', 'cache', 'flutter'),
|
||||
);
|
||||
genSnapshotFile = File(
|
||||
p.join(
|
||||
flutterDirectory.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
'engine',
|
||||
'ios-release',
|
||||
'gen_snapshot_arm64',
|
||||
),
|
||||
);
|
||||
ipaReader = _MockIpaReader();
|
||||
ipa = _MockIpa();
|
||||
progress = _MockProgress();
|
||||
@@ -185,11 +216,12 @@ flutter:
|
||||
platform = _MockPlatform();
|
||||
aotBuildProcessResult = _MockProcessResult();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
httpClient = _MockHttpClient();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
|
||||
when(() => argResults['arch']).thenReturn(arch);
|
||||
when(() => argResults['dry-run']).thenReturn(false);
|
||||
@@ -223,33 +255,16 @@ flutter:
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(() => platform.operatingSystem).thenReturn(Platform.macOS);
|
||||
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)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
when(() => flutterRevisionProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
when(() => shorebirdEnv.flutterDirectory).thenReturn(flutterDirectory);
|
||||
when(() => shorebirdEnv.genSnapshotFile).thenReturn(genSnapshotFile);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
() => aotBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
@@ -272,6 +287,9 @@ flutter:
|
||||
supportedOperatingSystems: any(named: 'supportedOperatingSystems'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
|
||||
command = runWithOverrides(() => PatchIosCommand(ipaReader: ipaReader))
|
||||
..testArgResults = argResults;
|
||||
@@ -478,9 +496,10 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
);
|
||||
|
||||
test('errors when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -488,45 +507,32 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'errors when shorebird flutter revision '
|
||||
'does not match release revision', () async {
|
||||
const otherRevision = 'other-revision';
|
||||
when(() => flutterRevisionProcessResult.stdout).thenReturn(otherRevision);
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => otherRevision);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
final shorebirdFlutterPath = runWithOverrides(
|
||||
() => ShorebirdEnvironment.flutterDirectory.path,
|
||||
);
|
||||
verify(
|
||||
() => logger.err('''
|
||||
Flutter revision mismatch.
|
||||
|
||||
The release you are trying to patch was built with a different version of Flutter.
|
||||
|
||||
Release Flutter Revision: $flutterRevision
|
||||
Current Flutter Revision: $otherRevision
|
||||
'''),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info('''
|
||||
Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release')}
|
||||
${lightCyan.wrap('shorebird release aar')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd $shorebirdFlutterPath')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
|
||||
+57
-53
@@ -9,12 +9,14 @@ 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/commands/patch/patch.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.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';
|
||||
@@ -36,6 +38,8 @@ class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdFlutterValidator extends Mock
|
||||
implements ShorebirdFlutterValidator {}
|
||||
|
||||
@@ -43,10 +47,14 @@ class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
void main() {
|
||||
group(PatchIosFrameworkCommand, () {
|
||||
const appDisplayName = 'Test App';
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const versionName = '1.2.3';
|
||||
const versionCode = '1';
|
||||
const version = '$versionName+$versionCode';
|
||||
@@ -74,6 +82,8 @@ flutter:
|
||||
late ArgResults argResults;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late Directory shorebirdRoot;
|
||||
late Directory flutterDirectory;
|
||||
late File genSnapshotFile;
|
||||
late Doctor doctor;
|
||||
late Platform platform;
|
||||
late Auth auth;
|
||||
@@ -81,10 +91,11 @@ flutter:
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult aotBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late PatchIosFrameworkCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -97,7 +108,11 @@ flutter:
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -142,15 +157,30 @@ flutter:
|
||||
doctor = _MockDoctor();
|
||||
platform = _MockPlatform();
|
||||
shorebirdRoot = Directory.systemTemp.createTempSync();
|
||||
flutterDirectory = Directory(
|
||||
p.join(shorebirdRoot.path, 'bin', 'cache', 'flutter'),
|
||||
);
|
||||
genSnapshotFile = File(
|
||||
p.join(
|
||||
flutterDirectory.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
'engine',
|
||||
'ios-release',
|
||||
'gen_snapshot_arm64',
|
||||
),
|
||||
);
|
||||
auth = _MockAuth();
|
||||
progress = _MockProgress();
|
||||
logger = _MockLogger();
|
||||
aotBuildProcessResult = _MockProcessResult();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
@@ -166,14 +196,6 @@ flutter:
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).thenAnswer((_) async => aotBuildProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
when(() => argResults['force']).thenReturn(false);
|
||||
when(() => argResults['release-version']).thenReturn(version);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
@@ -183,25 +205,16 @@ flutter:
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(() => logger.confirm(any())).thenReturn(true);
|
||||
when(() => platform.operatingSystem).thenReturn(Platform.macOS);
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
when(() => aotBuildProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
when(() => flutterBuildProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
when(() => flutterRevisionProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
when(() => shorebirdEnv.flutterDirectory).thenReturn(flutterDirectory);
|
||||
when(() => shorebirdEnv.genSnapshotFile).thenReturn(genSnapshotFile);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
() => aotBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => codePushClientWrapper.getApp(appId: any(named: 'appId')),
|
||||
).thenAnswer((_) async => appMetadata);
|
||||
@@ -228,6 +241,9 @@ flutter:
|
||||
supportedOperatingSystems: any(named: 'supportedOperatingSystems'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
|
||||
command = runWithOverrides(PatchIosFrameworkCommand.new)
|
||||
..testArgResults = argResults;
|
||||
@@ -350,9 +366,10 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
});
|
||||
|
||||
test('errors when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -360,45 +377,32 @@ Please re-run the release command for this version or create a new release.'''),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'errors when shorebird flutter revision '
|
||||
'does not match release revision', () async {
|
||||
const otherRevision = 'other-revision';
|
||||
when(() => flutterRevisionProcessResult.stdout).thenReturn(otherRevision);
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => otherRevision);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
final shorebirdFlutterPath = runWithOverrides(
|
||||
() => ShorebirdEnvironment.flutterDirectory.path,
|
||||
);
|
||||
verify(
|
||||
() => logger.err('''
|
||||
Flutter revision mismatch.
|
||||
|
||||
The release you are trying to patch was built with a different version of Flutter.
|
||||
|
||||
Release Flutter Revision: $flutterRevision
|
||||
Current Flutter Revision: $otherRevision
|
||||
'''),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info('''
|
||||
Either create a new release using:
|
||||
${lightCyan.wrap('shorebird release')}
|
||||
${lightCyan.wrap('shorebird release aar')}
|
||||
|
||||
Or downgrade your Flutter version and try again using:
|
||||
${lightCyan.wrap('cd $shorebirdFlutterPath')}
|
||||
${lightCyan.wrap('cd ${shorebirdEnv.flutterDirectory.path}')}
|
||||
${lightCyan.wrap('git checkout ${release.flutterRevision}')}
|
||||
|
||||
Shorebird plans to support this automatically, let us know if it's important to you:
|
||||
|
||||
@@ -10,12 +10,15 @@ 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/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/java.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_build_mixin.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
@@ -40,8 +43,13 @@ class _MockCodePushClientWrapper extends Mock
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
class _FakeRelease extends Fake implements Release {}
|
||||
|
||||
class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
@@ -50,6 +58,8 @@ void main() {
|
||||
group(ReleaseAarCommand, () {
|
||||
const appDisplayName = 'Test App';
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const androidPackageName = 'com.example.my_flutter_module';
|
||||
const appMetadata = AppMetadata(appId: appId, displayName: appDisplayName);
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const versionName = '1.2.3';
|
||||
@@ -65,29 +75,6 @@ void main() {
|
||||
);
|
||||
const releasePlatform = ReleasePlatform.android;
|
||||
const buildNumber = '1.0';
|
||||
const noModulePubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.0
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
const pubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.0
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
module:
|
||||
androidX: true
|
||||
androidPackage: com.example.my_flutter_module
|
||||
iosBundleIdentifier: com.example.myFlutterModule
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
@@ -99,9 +86,10 @@ flutter:
|
||||
late Progress progress;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late ReleaseAarCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -115,25 +103,17 @@ flutter:
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory setUpTempDir({bool includeModule = true}) {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(
|
||||
includeModule ? pubspecYamlContent : noModulePubspecYamlContent,
|
||||
);
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: $appId');
|
||||
return tempDir;
|
||||
}
|
||||
|
||||
void setUpTempArtifacts(Directory dir) {
|
||||
Directory setUpTempArtifacts() {
|
||||
final dir = Directory.systemTemp.createTempSync();
|
||||
final aarDir = p.join(
|
||||
dir.path,
|
||||
'build',
|
||||
@@ -159,6 +139,7 @@ flutter:
|
||||
File(artifactPath).createSync(recursive: true);
|
||||
}
|
||||
File(aarPath).createSync(recursive: true);
|
||||
return dir;
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
@@ -178,10 +159,11 @@ flutter:
|
||||
progress = _MockProgress();
|
||||
logger = _MockLogger();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdRoot = Directory.systemTemp.createTempSync();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => argResults['build-number']).thenReturn(buildNumber);
|
||||
@@ -191,26 +173,15 @@ flutter:
|
||||
when(() => logger.confirm(any())).thenReturn(true);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
when(() => flutterBuildProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
when(
|
||||
() => shorebirdEnv.androidPackageName,
|
||||
).thenReturn(androidPackageName);
|
||||
|
||||
when(
|
||||
() => flutterRevisionProcessResult.exitCode,
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
@@ -221,14 +192,6 @@ flutter:
|
||||
).thenAnswer((invocation) async {
|
||||
return flutterBuildProcessResult;
|
||||
});
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
|
||||
when(
|
||||
() => codePushClientWrapper.getApp(appId: any(named: 'appId')),
|
||||
@@ -278,6 +241,9 @@ flutter:
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
|
||||
command = runWithOverrides(
|
||||
() => ReleaseAarCommand(unzipFn: (_, __) async {}),
|
||||
@@ -308,24 +274,10 @@ flutter:
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with 78 if no pubspec.yaml exists', () async {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
|
||||
final result = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(result, ExitCode.config.code);
|
||||
});
|
||||
|
||||
test('exits with 78 if no module entry exists in pubspec.yaml', () async {
|
||||
final tempDir = setUpTempDir(includeModule: false);
|
||||
when(() => shorebirdEnv.androidPackageName).thenReturn(null);
|
||||
|
||||
final result = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, ExitCode.config.code);
|
||||
});
|
||||
@@ -333,13 +285,7 @@ flutter:
|
||||
test('exits with code 70 when building aar fails', () async {
|
||||
when(() => flutterBuildProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterBuildProcessResult.stderr).thenReturn('oops');
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final result = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final result = await runWithOverrides(command.run);
|
||||
expect(result, equals(ExitCode.software.code));
|
||||
verify(
|
||||
() => shorebirdProcess.run(
|
||||
@@ -354,8 +300,9 @@ flutter:
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail(any(that: contains('Failed to build'))))
|
||||
.called(1);
|
||||
verify(
|
||||
() => progress.fail(any(that: contains('Failed to build'))),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('aborts when user opts out', () async {
|
||||
@@ -366,7 +313,7 @@ flutter:
|
||||
defaultValue: any(named: 'defaultValue'),
|
||||
),
|
||||
).thenAnswer((_) => '1.0.0');
|
||||
final tempDir = setUpTempDir();
|
||||
final tempDir = setUpTempArtifacts();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
@@ -376,32 +323,22 @@ flutter:
|
||||
});
|
||||
|
||||
test('throws error when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test('does not prompt for confirmation when --force is used', () async {
|
||||
when(() => argResults['force']).thenReturn(true);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
|
||||
final tempDir = setUpTempArtifacts();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(() => logger.success('\n✅ Published Release!')).called(1);
|
||||
verifyNever(
|
||||
@@ -410,14 +347,11 @@ flutter:
|
||||
});
|
||||
|
||||
test('succeeds when release is successful', () async {
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
|
||||
final tempDir = setUpTempArtifacts();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(() => logger.success('\n✅ Published Release!')).called(1);
|
||||
verify(
|
||||
@@ -458,14 +392,11 @@ flutter:
|
||||
releaseVersion: any(named: 'releaseVersion'),
|
||||
),
|
||||
).thenAnswer((_) async => release);
|
||||
final tempDir = setUpTempDir();
|
||||
setUpTempArtifacts(tempDir);
|
||||
|
||||
final tempDir = setUpTempArtifacts();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verifyNever(
|
||||
() => codePushClientWrapper.createRelease(
|
||||
|
||||
+43
-129
@@ -12,12 +12,15 @@ import 'package:shorebird_cli/src/bundletool.dart';
|
||||
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/config/config.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/java.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.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';
|
||||
@@ -50,8 +53,13 @@ class _MockShorebirdFlutterValidator extends Mock
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
class _MockJava extends Mock implements Java {}
|
||||
|
||||
class _FakeRelease extends Fake implements Release {}
|
||||
@@ -61,6 +69,7 @@ class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
void main() {
|
||||
group(ReleaseAndroidCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const versionName = '1.2.3';
|
||||
const versionCode = '1';
|
||||
@@ -78,16 +87,6 @@ void main() {
|
||||
platformStatuses: {},
|
||||
);
|
||||
|
||||
const pubspecYamlContent = '''
|
||||
name: example
|
||||
version: $version
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
const javaHome = 'test-java-home';
|
||||
|
||||
late ArgResults argResults;
|
||||
@@ -103,10 +102,11 @@ flutter:
|
||||
late Progress progress;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late ReleaseAndroidCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -123,22 +123,15 @@ flutter:
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory setUpTempDir() {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: $appId');
|
||||
return tempDir;
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(ReleasePlatform.android);
|
||||
registerFallbackValue(ReleaseStatus.draft);
|
||||
@@ -160,21 +153,15 @@ flutter:
|
||||
progress = _MockProgress();
|
||||
logger = _MockLogger();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
@@ -182,14 +169,7 @@ flutter:
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterBuildProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults['arch']).thenReturn(arch);
|
||||
when(() => argResults['platform']).thenReturn(releasePlatform);
|
||||
@@ -208,12 +188,6 @@ flutter:
|
||||
when(
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
when(
|
||||
() => codePushClientWrapper.getApp(appId: any(named: 'appId')),
|
||||
).thenAnswer((_) async => appMetadata);
|
||||
@@ -273,6 +247,9 @@ flutter:
|
||||
supportedOperatingSystems: any(named: 'supportedOperatingSystems'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
|
||||
command = runWithOverrides(ReleaseAndroidCommand.new)
|
||||
..testArgResults = argResults;
|
||||
@@ -307,13 +284,7 @@ flutter:
|
||||
test('exits with code 70 when building fails', () async {
|
||||
when(() => flutterBuildProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterBuildProcessResult.stderr).thenReturn('oops');
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, equals(ExitCode.software.code));
|
||||
});
|
||||
|
||||
@@ -322,13 +293,7 @@ flutter:
|
||||
'Failed to extract version name from app bundle: oops',
|
||||
);
|
||||
when(() => bundletool.getVersionName(any())).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
@@ -338,13 +303,7 @@ flutter:
|
||||
'Failed to extract version code from app bundle: oops',
|
||||
);
|
||||
when(() => bundletool.getVersionCode(any())).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
@@ -357,13 +316,7 @@ flutter:
|
||||
defaultValue: any(named: 'defaultValue'),
|
||||
),
|
||||
).thenAnswer((_) => '1.0.0');
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(() => logger.info('Aborting.')).called(1);
|
||||
verifyNever(
|
||||
@@ -377,22 +330,13 @@ flutter:
|
||||
});
|
||||
|
||||
test('throws error when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
@@ -400,13 +344,7 @@ flutter:
|
||||
'when --release-version and --force are used', () async {
|
||||
when(() => argResults['force']).thenReturn(true);
|
||||
when(() => argResults['release-version']).thenReturn(version);
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(() => logger.success('\n✅ Published Release!')).called(1);
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verifyNever(
|
||||
@@ -415,13 +353,7 @@ flutter:
|
||||
});
|
||||
|
||||
test('succeeds when release is successful', () async {
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(() => logger.success('\n✅ Published Release!')).called(1);
|
||||
verify(
|
||||
() => codePushClientWrapper.createAndroidReleaseArtifacts(
|
||||
@@ -445,13 +377,7 @@ flutter:
|
||||
|
||||
test('succeeds when release is successful (with apk)', () async {
|
||||
when(() => argResults['artifact']).thenReturn('apk');
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
verify(() => logger.success('\n✅ Published Release!')).called(1);
|
||||
verify(
|
||||
() => codePushClientWrapper.createAndroidReleaseArtifacts(
|
||||
@@ -480,18 +406,12 @@ flutter:
|
||||
final target = p.join('lib', 'main_development.dart');
|
||||
when(() => argResults['flavor']).thenReturn(flavor);
|
||||
when(() => argResults['target']).thenReturn(target);
|
||||
final tempDir = setUpTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('''
|
||||
app_id: productionAppId
|
||||
flavors:
|
||||
development: $appId''');
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
const shorebirdYaml = ShorebirdYaml(
|
||||
appId: 'productionAppId',
|
||||
flavors: {flavor: appId},
|
||||
);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
verify(() => logger.success('\n✅ Published Release!')).called(1);
|
||||
verify(
|
||||
@@ -523,13 +443,7 @@ flavors:
|
||||
releaseVersion: any(named: 'releaseVersion'),
|
||||
),
|
||||
).thenAnswer((_) async => release);
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verifyNever(
|
||||
() => codePushClientWrapper.createRelease(
|
||||
|
||||
@@ -11,11 +11,14 @@ 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/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.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';
|
||||
@@ -46,8 +49,13 @@ class _MockShorebirdFlutterValidator extends Mock
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
class _FakeRelease extends Fake implements Release {}
|
||||
|
||||
class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
@@ -55,6 +63,7 @@ class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
void main() {
|
||||
group(ReleaseIosCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const versionName = '1.2.3';
|
||||
const versionCode = '1';
|
||||
@@ -102,10 +111,11 @@ flutter:
|
||||
late Progress progress;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late ReleaseIosCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -118,7 +128,11 @@ flutter:
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -159,21 +173,14 @@ flutter:
|
||||
progress = _MockProgress();
|
||||
logger = _MockLogger();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
@@ -181,14 +188,6 @@ flutter:
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterBuildProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults['arch']).thenReturn(arch);
|
||||
when(() => argResults['platform']).thenReturn(releasePlatform);
|
||||
@@ -204,12 +203,6 @@ flutter:
|
||||
when(
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
when(
|
||||
() => codePushClientWrapper.getApp(appId: any(named: 'appId')),
|
||||
).thenAnswer((_) async => appMetadata);
|
||||
@@ -259,6 +252,9 @@ flutter:
|
||||
supportedOperatingSystems: any(named: 'supportedOperatingSystems'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
|
||||
command = runWithOverrides(() => ReleaseIosCommand(ipaReader: ipaReader))
|
||||
..testArgResults = argResults;
|
||||
@@ -455,9 +451,10 @@ error: exportArchive: No signing certificate "iOS Distribution" found
|
||||
});
|
||||
|
||||
test('throws error when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -465,11 +462,7 @@ error: exportArchive: No signing certificate "iOS Distribution" found
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
|
||||
+27
-34
@@ -9,11 +9,14 @@ 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/commands/release/release.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.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';
|
||||
@@ -40,8 +43,13 @@ class _MockShorebirdFlutterValidator extends Mock
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
class _FakeRelease extends Fake implements Release {}
|
||||
|
||||
class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
@@ -49,6 +57,7 @@ class _FakeShorebirdProcess extends Fake implements ShorebirdProcess {}
|
||||
void main() {
|
||||
group(ReleaseIosFrameworkCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const versionName = '1.2.3';
|
||||
const versionCode = '1';
|
||||
@@ -83,10 +92,11 @@ flutter:
|
||||
late Progress progress;
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult flutterBuildProcessResult;
|
||||
late ShorebirdProcessResult flutterRevisionProcessResult;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late ReleaseIosFrameworkCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -99,7 +109,11 @@ flutter:
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -132,21 +146,14 @@ flutter:
|
||||
progress = _MockProgress();
|
||||
logger = _MockLogger();
|
||||
flutterBuildProcessResult = _MockProcessResult();
|
||||
flutterRevisionProcessResult = _MockProcessResult();
|
||||
flutterValidator = _MockShorebirdFlutterValidator();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
|
||||
when(() => platform.script).thenReturn(
|
||||
Uri.file(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'shorebird.snapshot',
|
||||
),
|
||||
),
|
||||
);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(shorebirdRoot);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
@@ -154,14 +161,6 @@ flutter:
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterBuildProcessResult);
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'git',
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
workingDirectory: any(named: 'workingDirectory'),
|
||||
),
|
||||
).thenAnswer((_) async => flutterRevisionProcessResult);
|
||||
when(() => argResults['release-version']).thenReturn(version);
|
||||
when(() => argResults['force']).thenReturn(false);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
@@ -170,12 +169,6 @@ flutter:
|
||||
when(
|
||||
() => flutterBuildProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.exitCode,
|
||||
).thenReturn(ExitCode.success.code);
|
||||
when(
|
||||
() => flutterRevisionProcessResult.stdout,
|
||||
).thenReturn(flutterRevision);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(() => logger.confirm(any())).thenReturn(true);
|
||||
when(() => platform.operatingSystem).thenReturn(Platform.macOS);
|
||||
@@ -225,6 +218,9 @@ flutter:
|
||||
supportedOperatingSystems: any(named: 'supportedOperatingSystems'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenAnswer((_) async => flutterRevision);
|
||||
|
||||
command = runWithOverrides(ReleaseIosFrameworkCommand.new)
|
||||
..testArgResults = argResults;
|
||||
@@ -319,9 +315,10 @@ flutter:
|
||||
});
|
||||
|
||||
test('throws error when unable to detect flutter revision', () async {
|
||||
const error = 'oops';
|
||||
when(() => flutterRevisionProcessResult.exitCode).thenReturn(1);
|
||||
when(() => flutterRevisionProcessResult.stderr).thenReturn(error);
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => shorebirdVersionManager.fetchCurrentGitHash(),
|
||||
).thenThrow(exception);
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
@@ -329,11 +326,7 @@ flutter:
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(
|
||||
() => progress.fail(
|
||||
'Exception: Unable to determine flutter revision: $error',
|
||||
),
|
||||
).called(1);
|
||||
verify(() => progress.fail('$exception')).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
|
||||
+33
-94
@@ -1,55 +1,45 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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: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/commands/releases/releases.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
void main() {
|
||||
group(DeleteReleasesCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
const releaseId = 3;
|
||||
const versionNumber = '1.0.0';
|
||||
|
||||
const pubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.1
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late Logger logger;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late DeleteReleasesCommand command;
|
||||
|
||||
@@ -57,38 +47,28 @@ flutter:
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory setUpTempDir() {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: $appId');
|
||||
return tempDir;
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
logger = _MockLogger();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
progress = _MockProgress();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['version']).thenReturn(versionNumber);
|
||||
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => codePushClient.getReleases(appId: any(named: 'appId')))
|
||||
.thenAnswer(
|
||||
(_) async => [
|
||||
@@ -129,16 +109,8 @@ flutter:
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(
|
||||
() => DeleteReleasesCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(DeleteReleasesCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('returns correct description', () {
|
||||
@@ -172,11 +144,7 @@ flutter:
|
||||
when(() => argResults['version']).thenReturn(null);
|
||||
when(() => logger.prompt(any())).thenReturn(versionNumber);
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
await runWithOverrides(command.run);
|
||||
|
||||
verify(
|
||||
() => logger.prompt(
|
||||
@@ -187,11 +155,7 @@ flutter:
|
||||
|
||||
test('does not prompt for version if user provides it with a flag',
|
||||
() async {
|
||||
final tempDir = setUpTempDir();
|
||||
await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
await runWithOverrides(command.run);
|
||||
verifyNever(() => logger.prompt(any()));
|
||||
});
|
||||
|
||||
@@ -200,11 +164,7 @@ flutter:
|
||||
() => codePushClient.getReleases(appId: any(named: 'appId')),
|
||||
).thenThrow(Exception('oops'));
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
});
|
||||
@@ -212,11 +172,7 @@ flutter:
|
||||
test('aborts when user does not confirm', () async {
|
||||
when(() => logger.confirm(any())).thenReturn(false);
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verifyNever(
|
||||
@@ -231,11 +187,7 @@ flutter:
|
||||
test('returns software error when release is not found', () async {
|
||||
when(() => argResults['version']).thenReturn('asdf');
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(() => logger.err('No release found for version "asdf"')).called(1);
|
||||
@@ -255,11 +207,7 @@ flutter:
|
||||
),
|
||||
).thenThrow(Exception('oops'));
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
verify(() => progress.fail(any(that: contains('oops')))).called(1);
|
||||
@@ -276,11 +224,7 @@ flutter:
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
final tempDir = setUpTempDir();
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(
|
||||
@@ -294,13 +238,11 @@ flutter:
|
||||
test('uses correct app_id when flavor is specified', () async {
|
||||
const flavor = 'development';
|
||||
when(() => argResults['flavor']).thenReturn(flavor);
|
||||
final tempDir = setUpTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('''
|
||||
app_id: productionAppId
|
||||
flavors:
|
||||
$flavor: $appId''');
|
||||
const shorebirdYaml = ShorebirdYaml(
|
||||
appId: 'productionAppId',
|
||||
flavors: {flavor: appId},
|
||||
);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(
|
||||
() => codePushClient.deleteRelease(
|
||||
appId: any(named: 'appId'),
|
||||
@@ -308,10 +250,7 @@ flavors:
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(() => codePushClient.getReleases(appId: appId)).called(1);
|
||||
|
||||
@@ -1,86 +1,67 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
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: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/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/config/config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
class _MockCodePushClientWrapper extends Mock
|
||||
implements CodePushClientWrapper {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdValidator extends Mock implements ShorebirdValidator {}
|
||||
|
||||
void main() {
|
||||
group(ListReleasesCommand, () {
|
||||
const appId = 'test-app-id';
|
||||
const shorebirdYaml = ShorebirdYaml(appId: appId);
|
||||
const flutterRevision = '83305b5088e6fe327fb3334a73ff190828d85713';
|
||||
|
||||
late ArgResults argResults;
|
||||
late Auth auth;
|
||||
late http.Client httpClient;
|
||||
late CodePushClientWrapper codePushClientWrapper;
|
||||
late CodePushClient codePushClient;
|
||||
late Logger logger;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late ListReleasesCommand command;
|
||||
|
||||
const pubspecYamlContent = '''
|
||||
name: example
|
||||
version: 1.0.1
|
||||
environment:
|
||||
sdk: ">=2.19.0 <3.0.0"
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''';
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
codePushClientWrapperRef.overrideWith(() => codePushClientWrapper),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Directory setUpTempDir() {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync(pubspecYamlContent);
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: $appId');
|
||||
return tempDir;
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
auth = _MockAuth();
|
||||
codePushClientWrapper = _MockCodePushClientWrapper();
|
||||
codePushClient = _MockCodePushClient();
|
||||
httpClient = _MockHttpClient();
|
||||
logger = _MockLogger();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
|
||||
when(
|
||||
() => codePushClientWrapper.codePushClient,
|
||||
).thenReturn(codePushClient);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
@@ -88,13 +69,8 @@ flutter:
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(
|
||||
() => ListReleasesCommand(
|
||||
buildCodePushClient: ({required httpClient, hostedUri}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(ListReleasesCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('description is correct', () {
|
||||
@@ -125,25 +101,18 @@ flutter:
|
||||
when(
|
||||
() => codePushClient.getReleases(appId: any(named: 'appId')),
|
||||
).thenThrow(Exception());
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.software.code);
|
||||
});
|
||||
|
||||
test('returns ExitCode.success when releases is empty', () async {
|
||||
when(() => codePushClient.getReleases(appId: appId))
|
||||
.thenAnswer((_) async => []);
|
||||
final tempDir = setUpTempDir();
|
||||
when(
|
||||
() => codePushClient.getReleases(appId: appId),
|
||||
).thenAnswer((_) async => []);
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(() => logger.info('(empty)')).called(1);
|
||||
@@ -152,13 +121,11 @@ flutter:
|
||||
test('uses correct app_id when flavor is specified', () async {
|
||||
const flavor = 'development';
|
||||
when(() => argResults['flavor']).thenReturn(flavor);
|
||||
final tempDir = setUpTempDir();
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('''
|
||||
app_id: productionAppId
|
||||
flavors:
|
||||
$flavor: $appId''');
|
||||
const shorebirdYaml = ShorebirdYaml(
|
||||
appId: 'productionAppId',
|
||||
flavors: {flavor: appId},
|
||||
);
|
||||
when(() => shorebirdEnv.getShorebirdYaml()).thenReturn(shorebirdYaml);
|
||||
when(() => codePushClient.getReleases(appId: appId)).thenAnswer(
|
||||
(_) async => [
|
||||
const Release(
|
||||
@@ -172,10 +139,7 @@ flavors:
|
||||
],
|
||||
);
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(
|
||||
@@ -190,8 +154,6 @@ flavors:
|
||||
|
||||
test('returns ExitCode.success and prints releases when releases exist',
|
||||
() async {
|
||||
final tempDir = setUpTempDir();
|
||||
|
||||
when(() => codePushClient.getReleases(appId: appId)).thenAnswer(
|
||||
(_) async => [
|
||||
const Release(
|
||||
@@ -213,10 +175,7 @@ flavors:
|
||||
],
|
||||
);
|
||||
|
||||
final exitCode = await IOOverrides.runZoned(
|
||||
() => runWithOverrides(command.run),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, ExitCode.success.code);
|
||||
verify(
|
||||
|
||||
@@ -3,26 +3,19 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.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';
|
||||
import 'package:shorebird_cli/src/commands/run_command.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.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';
|
||||
|
||||
class _MockArgResults extends Mock implements ArgResults {}
|
||||
|
||||
class _MockHttpClient extends Mock implements http.Client {}
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockDoctor extends Mock implements Doctor {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
@@ -31,8 +24,6 @@ class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockProcess extends Mock implements Process {}
|
||||
|
||||
class _MockCodePushClient extends Mock implements CodePushClient {}
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockIOSink extends Mock implements IOSink {}
|
||||
@@ -44,12 +35,9 @@ class _MockValidator extends Mock implements Validator {}
|
||||
void main() {
|
||||
group(RunCommand, () {
|
||||
late ArgResults argResults;
|
||||
late http.Client httpClient;
|
||||
late Auth auth;
|
||||
late Doctor doctor;
|
||||
late Logger logger;
|
||||
late Process process;
|
||||
late CodePushClient codePushClient;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late IOSink ioSink;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
@@ -60,7 +48,6 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
authRef.overrideWith(() => auth),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
@@ -75,13 +62,10 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = _MockArgResults();
|
||||
httpClient = _MockHttpClient();
|
||||
auth = _MockAuth();
|
||||
doctor = _MockDoctor();
|
||||
logger = _MockLogger();
|
||||
process = _MockProcess();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
codePushClient = _MockCodePushClient();
|
||||
ioSink = _MockIOSink();
|
||||
shorebirdValidator = _MockShorebirdValidator();
|
||||
validator = _MockValidator();
|
||||
@@ -94,8 +78,6 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async => process);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => auth.isAuthenticated).thenReturn(true);
|
||||
when(() => auth.client).thenReturn(httpClient);
|
||||
when(() => doctor.allValidators).thenReturn([validator]);
|
||||
when(() => logger.progress(any())).thenReturn(_MockProgress());
|
||||
when(() => ioSink.addStream(any())).thenAnswer((_) async {});
|
||||
@@ -106,16 +88,7 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(
|
||||
() => RunCommand(
|
||||
buildCodePushClient: ({
|
||||
required http.Client httpClient,
|
||||
Uri? hostedUri,
|
||||
}) {
|
||||
return codePushClient;
|
||||
},
|
||||
),
|
||||
)..testArgResults = argResults;
|
||||
command = runWithOverrides(RunCommand.new)..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('command is hidden', () {
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_version_manager.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
@@ -17,6 +18,8 @@ class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdVersionManager extends Mock
|
||||
implements ShorebirdVersionManager {}
|
||||
|
||||
@@ -28,6 +31,7 @@ void main() {
|
||||
late Logger logger;
|
||||
late ShorebirdProcessResult pruneFlutterOriginResult;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdVersionManager shorebirdVersionManager;
|
||||
late UpgradeCommand command;
|
||||
|
||||
@@ -37,8 +41,10 @@ void main() {
|
||||
values: {
|
||||
loggerRef.overrideWith(() => logger),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdVersionManagerRef
|
||||
.overrideWith(() => shorebirdVersionManager),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdVersionManagerRef.overrideWith(
|
||||
() => shorebirdVersionManager,
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -50,9 +56,13 @@ void main() {
|
||||
logger = _MockLogger();
|
||||
pruneFlutterOriginResult = _MockProcessResult();
|
||||
shorebirdProcess = _MockShorebirdProcess();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdVersionManager = _MockShorebirdVersionManager();
|
||||
command = runWithOverrides(UpgradeCommand.new);
|
||||
|
||||
when(
|
||||
() => shorebirdEnv.flutterDirectory,
|
||||
).thenReturn(Directory('flutter'));
|
||||
when(
|
||||
shorebirdVersionManager.fetchCurrentGitHash,
|
||||
).thenAnswer((_) async => currentShorebirdRevision);
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:shorebird_cli/src/ios_deploy.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
@@ -27,6 +28,8 @@ class _MockIOSink extends Mock implements IOSink {}
|
||||
|
||||
class _MockProcessSignal extends Mock implements ProcessSignal {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
void main() {
|
||||
group(IOSDeploy, () {
|
||||
late Logger logger;
|
||||
@@ -35,6 +38,7 @@ void main() {
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late Process process;
|
||||
late IOSink ioSink;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late IOSDeploy iosDeploy;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -44,6 +48,7 @@ void main() {
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -55,14 +60,15 @@ void main() {
|
||||
process = _MockProcess();
|
||||
progress = _MockProgress();
|
||||
ioSink = _MockIOSink();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
iosDeploy = IOSDeploy();
|
||||
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
|
||||
final shorebirdScriptFile = File(
|
||||
p.join(tempDir.path, 'bin', 'cache', 'shorebird.snapshot'),
|
||||
)..create(recursive: true);
|
||||
when(() => platform.script).thenReturn(shorebirdScriptFile.uri);
|
||||
when(() => shorebirdEnv.shorebirdRoot).thenReturn(tempDir);
|
||||
when(() => shorebirdEnv.flutterDirectory).thenReturn(
|
||||
Directory(p.join(tempDir.path, 'bin', 'cache', 'flutter')),
|
||||
);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(
|
||||
() => shorebirdProcess.start(any(), any()),
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:pubspec_parse/pubspec_parse.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
void main() {
|
||||
group(ShorebirdEnv, () {
|
||||
late Platform platform;
|
||||
late Directory shorebirdRoot;
|
||||
late Uri platformScript;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
|
||||
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();
|
||||
shorebirdEnv = runWithOverrides(ShorebirdEnv.new);
|
||||
|
||||
when(() => platform.environment).thenReturn(const {});
|
||||
when(() => platform.script).thenReturn(platformScript);
|
||||
});
|
||||
|
||||
group('flutterBinaryFile', () {
|
||||
test('returns correct path', () {
|
||||
expect(
|
||||
runWithOverrides(() => shorebirdEnv.flutterBinaryFile.path),
|
||||
equals(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'flutter',
|
||||
'bin',
|
||||
'flutter',
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('genSnapshotFile', () {
|
||||
test('returns correct path', () {
|
||||
expect(
|
||||
runWithOverrides(() => shorebirdEnv.genSnapshotFile.path),
|
||||
equals(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'flutter',
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
'engine',
|
||||
'ios-release',
|
||||
'gen_snapshot_arm64',
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('getPubspecYamlFile', () {
|
||||
test('returns correct file', () {
|
||||
final tempDir = Directory('temp');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() {
|
||||
return runWithOverrides(
|
||||
() => shorebirdEnv.getPubspecYamlFile().path,
|
||||
);
|
||||
},
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
equals(p.join(tempDir.path, 'pubspec.yaml')),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('getPubspecYaml', () {
|
||||
test('returns null when pubspec.yaml does not exist', () {
|
||||
final tempDir = Directory('temp');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.getPubspecYaml()),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isNull,
|
||||
);
|
||||
});
|
||||
|
||||
test('returns value when pubspec.yaml exists', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('name: test');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.getPubspecYaml()),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isA<Pubspec>().having((p) => p.name, 'name', 'test'),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('hasPubspecYaml', () {
|
||||
test('returns false when pubspec.yaml does not exist', () {
|
||||
final tempDir = Directory('temp');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.hasPubspecYaml),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('returns true when pubspec.yaml does exist', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('name: test');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.hasPubspecYaml),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('hasShorebirdYaml', () {
|
||||
test('returns false when shorebird.yaml does not exist', () {
|
||||
final tempDir = Directory('temp');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.hasShorebirdYaml),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('returns true when shorebird.yaml does exist', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: test-app-id');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.hasShorebirdYaml),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('pubspecContainsShorebirdYaml', () {
|
||||
test(
|
||||
'returns false when pubspec.yaml does not '
|
||||
'contain shorebird.yaml in assets', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('name: test');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(
|
||||
() => shorebirdEnv.pubspecContainsShorebirdYaml,
|
||||
),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'returns true when pubspec.yaml does '
|
||||
'contain shorebird.yaml in assets', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('''
|
||||
name: test
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml
|
||||
''');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(
|
||||
() => shorebirdEnv.pubspecContainsShorebirdYaml,
|
||||
),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('androidPackageName', () {
|
||||
test('returns null when pubspec.yaml does not contain android module',
|
||||
() {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('name: test');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.androidPackageName),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isNull,
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'returns correct package name when '
|
||||
'pubspec.yaml contains android module', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('''
|
||||
name: test
|
||||
flutter:
|
||||
module:
|
||||
androidPackage: test-package
|
||||
''');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.androidPackageName),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
equals('test-package'),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('isShorebirdInitialized', () {
|
||||
test('returns false when shorebird.yaml does not exist', () {
|
||||
final tempDir = Directory('temp');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.isShorebirdInitialized),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'returns false when shorebird.yaml exists '
|
||||
'but pubspec does not contain shorebird.yaml', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: test-app-id');
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('name: test');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.isShorebirdInitialized),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'returns false when shorebird.yaml does not exist '
|
||||
'but pubspec contains shorebird.yaml', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('''
|
||||
name: test
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.isShorebirdInitialized),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'returns true when shorebird.yaml exists '
|
||||
'and pubspec contains shorebird.yaml', () {
|
||||
final tempDir = Directory.systemTemp.createTempSync();
|
||||
File(
|
||||
p.join(tempDir.path, 'shorebird.yaml'),
|
||||
).writeAsStringSync('app_id: test-app-id');
|
||||
File(
|
||||
p.join(tempDir.path, 'pubspec.yaml'),
|
||||
).writeAsStringSync('''
|
||||
name: test
|
||||
flutter:
|
||||
assets:
|
||||
- shorebird.yaml''');
|
||||
expect(
|
||||
IOOverrides.runZoned(
|
||||
() => runWithOverrides(() => shorebirdEnv.isShorebirdInitialized),
|
||||
getCurrentDirectory: () => tempDir,
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('flutterRevision', () {
|
||||
test('returns correct revision', () {
|
||||
const revision = 'test-revision';
|
||||
File(p.join(shorebirdRoot.path, 'bin', 'internal', 'flutter.version'))
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(revision, flush: true);
|
||||
expect(
|
||||
runWithOverrides(() => shorebirdEnv.flutterRevision),
|
||||
equals(revision),
|
||||
);
|
||||
});
|
||||
|
||||
test('trims revision file content', () {
|
||||
const revision = '''
|
||||
|
||||
test-revision
|
||||
|
||||
\r\n
|
||||
''';
|
||||
File(p.join(shorebirdRoot.path, 'bin', 'internal', 'flutter.version'))
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(revision, flush: true);
|
||||
|
||||
expect(
|
||||
runWithOverrides(() => shorebirdEnv.flutterRevision),
|
||||
'test-revision',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('shorebirdEngineRevision', () {
|
||||
test('returns correct revision', () {
|
||||
const revision = 'test-revision';
|
||||
File(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'flutter',
|
||||
'bin',
|
||||
'internal',
|
||||
'engine.version',
|
||||
),
|
||||
)
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(revision, flush: true);
|
||||
expect(
|
||||
runWithOverrides(() => shorebirdEnv.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(() => shorebirdEnv.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(() => shorebirdEnv.hostedUri),
|
||||
getCurrentDirectory: () => directory,
|
||||
),
|
||||
equals(Uri.parse('https://example.com')),
|
||||
);
|
||||
});
|
||||
|
||||
test('returns null when there is no env override or shorebird.yaml', () {
|
||||
expect(runWithOverrides(() => shorebirdEnv.hostedUri), isNull);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,122 +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/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
void main() {
|
||||
group('ShorebirdEnvironment', () {
|
||||
late Platform platform;
|
||||
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();
|
||||
|
||||
when(() => platform.environment).thenReturn(const {});
|
||||
when(() => platform.script).thenReturn(platformScript);
|
||||
});
|
||||
|
||||
group('flutterRevision', () {
|
||||
test('returns correct revision', () {
|
||||
const revision = 'test-revision';
|
||||
File(p.join(shorebirdRoot.path, 'bin', 'internal', 'flutter.version'))
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(revision, flush: true);
|
||||
expect(
|
||||
runWithOverrides(() => ShorebirdEnvironment.flutterRevision),
|
||||
equals(revision),
|
||||
);
|
||||
});
|
||||
|
||||
test('trims revision file content', () {
|
||||
const revision = '''
|
||||
|
||||
test-revision
|
||||
|
||||
\r\n
|
||||
''';
|
||||
File(p.join(shorebirdRoot.path, 'bin', 'internal', 'flutter.version'))
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(revision, flush: true);
|
||||
|
||||
expect(
|
||||
runWithOverrides(() => ShorebirdEnvironment.flutterRevision),
|
||||
'test-revision',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('shorebirdEngineRevision', () {
|
||||
test('returns correct revision', () {
|
||||
const revision = 'test-revision';
|
||||
File(
|
||||
p.join(
|
||||
shorebirdRoot.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'flutter',
|
||||
'bin',
|
||||
'internal',
|
||||
'engine.version',
|
||||
),
|
||||
)
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(revision, flush: true);
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -2,7 +2,9 @@ import 'dart:io';
|
||||
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockProcess extends Mock implements Process {}
|
||||
@@ -11,6 +13,8 @@ class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
class _MockProcessWrapper extends Mock implements ProcessWrapper {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
void main() {
|
||||
group('ShorebirdProcess', () {
|
||||
const flutterStorageBaseUrlEnv = {
|
||||
@@ -20,16 +24,32 @@ void main() {
|
||||
late ProcessWrapper processWrapper;
|
||||
late Process startProcess;
|
||||
late ShorebirdProcessResult runProcessResult;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
() => body(),
|
||||
values: {
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
processWrapper = _MockProcessWrapper();
|
||||
runProcessResult = _MockProcessResult();
|
||||
startProcess = _MockProcess();
|
||||
shorebirdProcess = ShorebirdProcess(
|
||||
processWrapper: processWrapper,
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
shorebirdProcess = runWithOverrides(
|
||||
() => ShorebirdProcess(processWrapper: processWrapper),
|
||||
);
|
||||
|
||||
when(() => shorebirdEnv.flutterBinaryFile).thenReturn(
|
||||
File(
|
||||
p.join('bin', 'cache', 'flutter', 'bin', 'flutter'),
|
||||
),
|
||||
);
|
||||
when(
|
||||
() => processWrapper.run(
|
||||
any(),
|
||||
@@ -78,11 +98,13 @@ void main() {
|
||||
});
|
||||
|
||||
test('replaces "flutter" with our local flutter', () async {
|
||||
await shorebirdProcess.run(
|
||||
'flutter',
|
||||
['--version'],
|
||||
runInShell: true,
|
||||
workingDirectory: '~',
|
||||
await runWithOverrides(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
['--version'],
|
||||
runInShell: true,
|
||||
workingDirectory: '~',
|
||||
),
|
||||
);
|
||||
|
||||
verify(
|
||||
@@ -178,7 +200,7 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
await shorebirdProcess.run('flutter', []);
|
||||
await runWithOverrides(() => shorebirdProcess.run('flutter', []));
|
||||
|
||||
verify(
|
||||
() => processWrapper.run(
|
||||
@@ -209,7 +231,9 @@ void main() {
|
||||
});
|
||||
|
||||
test('replaces "flutter" with our local flutter', () async {
|
||||
await shorebirdProcess.start('flutter', ['run'], runInShell: true);
|
||||
await runWithOverrides(
|
||||
() => shorebirdProcess.start('flutter', ['run'], runInShell: true),
|
||||
);
|
||||
|
||||
verify(
|
||||
() => processWrapper.start(
|
||||
@@ -247,11 +271,13 @@ void main() {
|
||||
});
|
||||
|
||||
test('Updates environment if useVendedFlutter is true', () async {
|
||||
await shorebirdProcess.start(
|
||||
'flutter',
|
||||
['--version'],
|
||||
runInShell: true,
|
||||
environment: {'ENV_VAR': 'asdfasdf'},
|
||||
await runWithOverrides(
|
||||
() => shorebirdProcess.start(
|
||||
'flutter',
|
||||
['--version'],
|
||||
runInShell: true,
|
||||
environment: {'ENV_VAR': 'asdfasdf'},
|
||||
),
|
||||
);
|
||||
|
||||
verify(
|
||||
|
||||
@@ -5,6 +5,7 @@ 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/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
import 'package:test/test.dart';
|
||||
@@ -15,6 +16,8 @@ class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockValidator extends Mock implements Validator {}
|
||||
|
||||
void main() {
|
||||
@@ -23,6 +26,7 @@ void main() {
|
||||
late Logger logger;
|
||||
late Platform platform;
|
||||
late Validator validator;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -32,6 +36,7 @@ void main() {
|
||||
authRef.overrideWith(() => auth),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
platformRef.overrideWith(() => platform),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -40,6 +45,7 @@ void main() {
|
||||
auth = _MockAuth();
|
||||
logger = _MockLogger();
|
||||
platform = _MockPlatform();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
validator = _MockValidator();
|
||||
shorebirdValidator = runWithOverrides(ShorebirdValidator.new);
|
||||
});
|
||||
@@ -103,6 +109,7 @@ void main() {
|
||||
test(
|
||||
'throws ShorebirdNotInitializedException '
|
||||
'when shorebird has not been initialized', () async {
|
||||
when(() => shorebirdEnv.isShorebirdInitialized).thenReturn(false);
|
||||
await expectLater(
|
||||
runWithOverrides(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:platform/platform.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/platform.dart';
|
||||
import 'package:shorebird_cli/src/process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_environment.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
@@ -14,6 +14,8 @@ class _MockProcessResult extends Mock implements ShorebirdProcessResult {}
|
||||
|
||||
class _MockPlatform extends Mock implements Platform {}
|
||||
|
||||
class _MockShorebirdEnv extends Mock implements ShorebirdEnv {}
|
||||
|
||||
class _MockShorebirdProcess extends Mock implements ShorebirdProcess {}
|
||||
|
||||
void main() {
|
||||
@@ -40,6 +42,7 @@ Tools • Dart 2.19.6 • DevTools 2.20.1
|
||||
late ShorebirdProcessResult shorebirdFlutterVersionProcessResult;
|
||||
late ShorebirdProcessResult gitStatusProcessResult;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late Platform platform;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
@@ -48,6 +51,7 @@ Tools • Dart 2.19.6 • DevTools 2.20.1
|
||||
values: {
|
||||
platformRef.overrideWith(() => platform),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -68,8 +72,12 @@ Tools • Dart 2.19.6 • DevTools 2.20.1
|
||||
setUp(() {
|
||||
tempDir = setupTempDirectory();
|
||||
platform = _MockPlatform();
|
||||
shorebirdEnv = _MockShorebirdEnv();
|
||||
|
||||
ShorebirdEnvironment.flutterRevision = flutterRevision;
|
||||
when(() => shorebirdEnv.flutterRevision).thenReturn(flutterRevision);
|
||||
when(
|
||||
() => shorebirdEnv.flutterDirectory,
|
||||
).thenReturn(flutterDirectory(tempDir));
|
||||
when(() => platform.script).thenReturn(shorebirdScriptFile(tempDir).uri);
|
||||
when(() => platform.environment).thenReturn({});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user