fix: delete shorebird build commands (#2453)
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
export 'build_aar_command.dart';
|
||||
export 'build_apk_command.dart';
|
||||
export 'build_app_bundle_command.dart';
|
||||
export 'build_command.dart';
|
||||
export 'build_ipa_command.dart';
|
||||
@@ -1,87 +0,0 @@
|
||||
// ignore_for_file: public_member_api_docs
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/extensions/arg_results.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_command.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
|
||||
/// {@template build_aar_command}
|
||||
///
|
||||
/// `shorebird build aar`
|
||||
/// Build an Android aar file from your app.
|
||||
/// {@endtemplate}
|
||||
class BuildAarCommand extends ShorebirdCommand {
|
||||
BuildAarCommand() {
|
||||
// We would have a "target" option here, similar to what [BuildApkCommand]
|
||||
// and [BuildAabCommand] have, but target cannot currently be configured in
|
||||
// `flutter build aar` and is always assumed to be lib/main.dart.
|
||||
argParser
|
||||
// `flutter build aar` defaults to a build number of 1.0, so we do the
|
||||
// same.
|
||||
.addOption(
|
||||
'build-number',
|
||||
help: 'The build number of the aar',
|
||||
defaultsTo: '1.0',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String get name => 'aar';
|
||||
|
||||
@override
|
||||
String get description => 'Build an Android AAR file from your module.';
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
try {
|
||||
await shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
);
|
||||
} on PreconditionFailedException catch (e) {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
if (shorebirdEnv.androidPackageName == null) {
|
||||
logger.err('Could not find androidPackage in pubspec.yaml.');
|
||||
return ExitCode.config.code;
|
||||
}
|
||||
|
||||
final buildNumber = results['build-number'] as String;
|
||||
final buildProgress = logger.progress('Building aar');
|
||||
try {
|
||||
await artifactBuilder.buildAar(
|
||||
buildNumber: buildNumber,
|
||||
args: results.forwardedArgs,
|
||||
);
|
||||
} on ArtifactBuildException catch (error) {
|
||||
buildProgress.fail('Failed to build: ${error.message}');
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
buildProgress.complete();
|
||||
|
||||
final aarPath = p.joinAll([
|
||||
'build',
|
||||
'host',
|
||||
'outputs',
|
||||
'repo',
|
||||
...shorebirdEnv.androidPackageName!.split('.'),
|
||||
'flutter_release',
|
||||
buildNumber,
|
||||
'flutter_release-$buildNumber.aar',
|
||||
]);
|
||||
|
||||
logger.info('''
|
||||
📦 Generated an aar at:
|
||||
${lightCyan.wrap(aarPath)}''');
|
||||
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/extensions/arg_results.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_command.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
|
||||
/// {@template build_apk_command}
|
||||
///
|
||||
/// `shorebird build apk`
|
||||
/// Build an Android APK file from your app.
|
||||
/// {@endtemplate}
|
||||
class BuildApkCommand extends ShorebirdCommand {
|
||||
/// {@macro build_apk_command}
|
||||
BuildApkCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
'target',
|
||||
abbr: 't',
|
||||
help: 'The main entrypoint file of the application.',
|
||||
)
|
||||
..addOption(
|
||||
'flavor',
|
||||
help: 'The product flavor to use when building the app.',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String get description => 'Build an Android APK file from your app.';
|
||||
|
||||
@override
|
||||
String get name => 'apk';
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
try {
|
||||
await shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
validators: doctor.androidCommandValidators,
|
||||
);
|
||||
} on PreconditionFailedException catch (e) {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final flavor = results['flavor'] as String?;
|
||||
final target = results['target'] as String?;
|
||||
final buildProgress = logger.progress('Building apk');
|
||||
try {
|
||||
await artifactBuilder.buildApk(
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
args: results.forwardedArgs,
|
||||
);
|
||||
} on ArtifactBuildException catch (error) {
|
||||
buildProgress.fail(error.message);
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
buildProgress.complete();
|
||||
|
||||
final apkDirPath = p.join('build', 'app', 'outputs', 'apk');
|
||||
final apkPath = flavor != null
|
||||
? p.join(apkDirPath, flavor, 'release', 'app-$flavor-release.apk')
|
||||
: p.join(apkDirPath, 'release', 'app-release.apk');
|
||||
|
||||
logger.info('''
|
||||
📦 Generated an apk at:
|
||||
${lightCyan.wrap(apkPath)}''');
|
||||
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/extensions/arg_results.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_command.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
|
||||
/// {@template build_app_bundle_command}
|
||||
///
|
||||
/// `shorebird build appbundle`
|
||||
/// Build an Android App Bundle file from your app.
|
||||
/// {@endtemplate}
|
||||
class BuildAppBundleCommand extends ShorebirdCommand {
|
||||
/// {@macro build_app_bundle_command}
|
||||
BuildAppBundleCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
'target',
|
||||
abbr: 't',
|
||||
help: 'The main entrypoint file of the application.',
|
||||
)
|
||||
..addOption(
|
||||
'flavor',
|
||||
help: 'The product flavor to use when building the app.',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String get description => 'Build an Android App Bundle file from your app.';
|
||||
|
||||
@override
|
||||
String get name => 'appbundle';
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
try {
|
||||
await shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
validators: doctor.androidCommandValidators,
|
||||
);
|
||||
} on PreconditionFailedException catch (e) {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final flavor = results['flavor'] as String?;
|
||||
final target = results['target'] as String?;
|
||||
final buildProgress = logger.progress('Building appbundle');
|
||||
try {
|
||||
await artifactBuilder.buildAppBundle(
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
args: results.forwardedArgs,
|
||||
);
|
||||
} on ArtifactBuildException catch (error) {
|
||||
buildProgress.fail(error.message);
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
final bundleDirPath = p.join('build', 'app', 'outputs', 'bundle');
|
||||
final bundlePath = flavor != null
|
||||
? p.join(bundleDirPath, '${flavor}Release', 'app-$flavor-release.aab')
|
||||
: p.join(bundleDirPath, 'release', 'app-release.aab');
|
||||
|
||||
buildProgress.complete();
|
||||
logger.info('''
|
||||
📦 Generated an app bundle at:
|
||||
${lightCyan.wrap(bundlePath)}''');
|
||||
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_command.dart';
|
||||
|
||||
/// {@template build_command}
|
||||
/// `shorebird build`
|
||||
/// Build a new release of your application.
|
||||
/// {@endtemplate}
|
||||
class BuildCommand extends ShorebirdCommand {
|
||||
/// {@macro build_command}
|
||||
BuildCommand() {
|
||||
addSubcommand(BuildAarCommand());
|
||||
addSubcommand(BuildApkCommand());
|
||||
addSubcommand(BuildAppBundleCommand());
|
||||
addSubcommand(BuildIpaCommand());
|
||||
}
|
||||
|
||||
@override
|
||||
String get description => 'Build a new release of your application.';
|
||||
|
||||
@override
|
||||
String get name => 'build';
|
||||
|
||||
@override
|
||||
bool get hidden => true;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/extensions/arg_results.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_command.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
|
||||
/// {@template build_ipa_command}
|
||||
/// `shorebird build ipa`
|
||||
/// Builds an .xcarchive and optionally .ipa for an iOS app to be generated for
|
||||
/// App Store submission.
|
||||
/// {@endtemplate}
|
||||
class BuildIpaCommand extends ShorebirdCommand {
|
||||
/// {@macro build_ipa_command}
|
||||
BuildIpaCommand() {
|
||||
argParser
|
||||
..addOption(
|
||||
'target',
|
||||
abbr: 't',
|
||||
help: 'The main entrypoint file of the application.',
|
||||
)
|
||||
..addOption(
|
||||
'flavor',
|
||||
help: 'The product flavor to use when building the app.',
|
||||
)
|
||||
..addFlag(
|
||||
'codesign',
|
||||
help:
|
||||
'''Codesign the application bundle (only available on device builds).''',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String get description =>
|
||||
'''Builds an .xcarchive and optionally .ipa for an iOS app to be generated for App Store submission.''';
|
||||
|
||||
@override
|
||||
String get name => 'ipa';
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
try {
|
||||
await shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
validators: doctor.iosCommandValidators,
|
||||
);
|
||||
} on PreconditionFailedException catch (e) {
|
||||
return e.exitCode.code;
|
||||
}
|
||||
|
||||
final flavor = results['flavor'] as String?;
|
||||
final target = results['target'] as String?;
|
||||
final codesign = results['codesign'] as bool;
|
||||
|
||||
if (!codesign) {
|
||||
logger.warn('''
|
||||
Codesigning is disabled. You must manually codesign before deploying to devices.''');
|
||||
}
|
||||
|
||||
final buildProgress = logger.progress('Building ipa');
|
||||
try {
|
||||
await artifactBuilder.buildIpa(
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
codesign: codesign,
|
||||
args: results.forwardedArgs,
|
||||
);
|
||||
} on ArtifactBuildException catch (error) {
|
||||
buildProgress.fail('Failed to build: ${error.message}');
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
buildProgress.complete();
|
||||
|
||||
final xcarchivePath = p.join('build', 'ios', 'archive', 'Runner.xcarchive');
|
||||
|
||||
logger.info('''
|
||||
📦 Generated an xcode archive at:
|
||||
${lightCyan.wrap(xcarchivePath)}''');
|
||||
|
||||
if (!codesign) {
|
||||
logger.info(
|
||||
'Codesigning disabled via "--no-codesign". Skipping ipa generation.',
|
||||
);
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
|
||||
final ipaPath = p.join('build', 'ios', 'ipa', 'Runner.ipa');
|
||||
|
||||
logger.info('''
|
||||
📦 Generated an ipa at:
|
||||
${lightCyan.wrap(ipaPath)}''');
|
||||
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
export 'build/build_command.dart';
|
||||
export 'cache/cache.dart';
|
||||
export 'doctor_command.dart';
|
||||
export 'flutter/flutter.dart';
|
||||
|
||||
@@ -67,7 +67,6 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner<int> {
|
||||
help: 'The build of the local engine to use as the host platform.',
|
||||
);
|
||||
|
||||
addCommand(BuildCommand());
|
||||
addCommand(CacheCommand());
|
||||
addCommand(DoctorCommand());
|
||||
addCommand(FlutterCommand());
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
import 'package:args/args.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:scoped_deps/scoped_deps.dart';
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.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:test/test.dart';
|
||||
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
group(BuildAarCommand, () {
|
||||
const buildNumber = '1.0';
|
||||
const androidPackageName = 'com.example.my_flutter_module';
|
||||
|
||||
late ArgResults argResults;
|
||||
late ArtifactBuilder artifactBuilder;
|
||||
late ShorebirdLogger logger;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late BuildAarCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
artifactBuilderRef.overrideWith(() => artifactBuilder),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
argResults = MockArgResults();
|
||||
artifactBuilder = MockArtifactBuilder();
|
||||
logger = MockShorebirdLogger();
|
||||
progress = MockProgress();
|
||||
shorebirdEnv = MockShorebirdEnv();
|
||||
shorebirdValidator = MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['build-number']).thenReturn(buildNumber);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults.wasParsed(any())).thenReturn(false);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
when(
|
||||
() => artifactBuilder.buildAar(
|
||||
buildNumber: any(named: 'buildNumber'),
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenAnswer((_) async => {});
|
||||
when(
|
||||
() => shorebirdEnv.androidPackageName,
|
||||
).thenReturn(androidPackageName);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(BuildAarCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
expect(command.description, isNotEmpty);
|
||||
});
|
||||
|
||||
test('exits when validation fails', () async {
|
||||
final exception = ValidationFailedException();
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
),
|
||||
).thenThrow(exception);
|
||||
await expectLater(
|
||||
runWithOverrides(command.run),
|
||||
completion(equals(exception.exitCode.code)),
|
||||
);
|
||||
verify(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with 78 if no module entry exists in pubspec.yaml', () async {
|
||||
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(
|
||||
() => artifactBuilder.buildAar(
|
||||
buildNumber: any(named: 'buildNumber'),
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenThrow(ArtifactBuildException('Failed to build: error'));
|
||||
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.software.code));
|
||||
verify(
|
||||
() => artifactBuilder.buildAar(buildNumber: buildNumber, args: []),
|
||||
).called(1);
|
||||
verify(
|
||||
() => progress.fail(any(that: contains('Failed to build'))),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
group('when platform was specified via arg results rest', () {
|
||||
setUp(() {
|
||||
when(() => argResults.rest).thenReturn(['android', '--verbose']);
|
||||
});
|
||||
|
||||
test('exits with code 0 when building aar succeeds', () async {
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildAar(
|
||||
buildNumber: buildNumber,
|
||||
args: ['--verbose'],
|
||||
),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an aar at:
|
||||
${lightCyan.wrap(
|
||||
p.join(
|
||||
'build',
|
||||
'host',
|
||||
'outputs',
|
||||
'repo',
|
||||
'com',
|
||||
'example',
|
||||
'my_flutter_module',
|
||||
'flutter_release',
|
||||
buildNumber,
|
||||
'flutter_release-$buildNumber.aar',
|
||||
),
|
||||
)}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
test('exits with code 0 when building aar succeeds', () async {
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildAar(buildNumber: buildNumber, args: []),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an aar at:
|
||||
${lightCyan.wrap(
|
||||
p.join(
|
||||
'build',
|
||||
'host',
|
||||
'outputs',
|
||||
'repo',
|
||||
'com',
|
||||
'example',
|
||||
'my_flutter_module',
|
||||
'flutter_release',
|
||||
buildNumber,
|
||||
'flutter_release-$buildNumber.aar',
|
||||
),
|
||||
)}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:scoped_deps/scoped_deps.dart';
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../fakes.dart';
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
group(BuildApkCommand, () {
|
||||
late ArgResults argResults;
|
||||
late ArtifactBuilder artifactBuilder;
|
||||
late Doctor doctor;
|
||||
late ShorebirdLogger logger;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late BuildApkCommand command;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
artifactBuilderRef.overrideWith(() => artifactBuilder),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(Directory(''));
|
||||
registerFallbackValue(FakeShorebirdProcess());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
argResults = MockArgResults();
|
||||
artifactBuilder = MockArtifactBuilder();
|
||||
doctor = MockDoctor();
|
||||
logger = MockShorebirdLogger();
|
||||
flutterValidator = MockShorebirdFlutterValidator();
|
||||
shorebirdValidator = MockShorebirdValidator();
|
||||
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults.wasParsed(any())).thenReturn(false);
|
||||
when(() => logger.progress(any())).thenReturn(MockProgress());
|
||||
when(() => logger.info(any())).thenReturn(null);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => doctor.androidCommandValidators,
|
||||
).thenReturn([flutterValidator]);
|
||||
|
||||
when(
|
||||
() => artifactBuilder.buildApk(
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenAnswer((_) async => File(''));
|
||||
|
||||
command = runWithOverrides(BuildApkCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
expect(command.description, isNotEmpty);
|
||||
});
|
||||
|
||||
test('exits when validation fails', () async {
|
||||
final exception = ValidationFailedException();
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
),
|
||||
).thenThrow(exception);
|
||||
await expectLater(
|
||||
runWithOverrides(command.run),
|
||||
completion(equals(exception.exitCode.code)),
|
||||
);
|
||||
verify(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
validators: [flutterValidator],
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 70 when building apk fails', () async {
|
||||
when(
|
||||
() => artifactBuilder.buildApk(
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenThrow(ArtifactBuildException('oops'));
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.software.code));
|
||||
verify(
|
||||
() => artifactBuilder.buildApk(args: []),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
group('when platform was specified via arg results rest', () {
|
||||
setUp(() {
|
||||
when(() => argResults.rest).thenReturn(['android', '--verbose']);
|
||||
});
|
||||
|
||||
test('exits with code 0 when building apk succeeds', () async {
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildApk(args: ['--verbose']),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an apk at:
|
||||
${lightCyan.wrap(p.join('build', 'app', 'outputs', 'apk', 'release', 'app-release.apk'))}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
test('exits with code 0 when building apk succeeds', () async {
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildApk(args: []),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an apk at:
|
||||
${lightCyan.wrap(p.join('build', 'app', 'outputs', 'apk', 'release', 'app-release.apk'))}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'exits with code 0 when building apk succeeds '
|
||||
'with flavor and target', () async {
|
||||
const flavor = 'development';
|
||||
final target = p.join('lib', 'main_development.dart');
|
||||
when(() => argResults['flavor']).thenReturn(flavor);
|
||||
when(() => argResults['target']).thenReturn(target);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildApk(
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
args: [],
|
||||
),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an apk at:
|
||||
${lightCyan.wrap(p.join('build', 'app', 'outputs', 'apk', flavor, 'release', 'app-$flavor-release.apk'))}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:scoped_deps/scoped_deps.dart';
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/engine_config.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/platform/platform.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:shorebird_cli/src/validators/validators.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../fakes.dart';
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
group(BuildAppBundleCommand, () {
|
||||
late ArgResults argResults;
|
||||
late ArtifactBuilder artifactBuilder;
|
||||
late Doctor doctor;
|
||||
late ShorebirdLogger logger;
|
||||
late BuildAppBundleCommand command;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
artifactBuilderRef.overrideWith(() => artifactBuilder),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
engineConfigRef.overrideWith(() => const EngineConfig.empty()),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FakeShorebirdProcess());
|
||||
registerFallbackValue(Directory(''));
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
argResults = MockArgResults();
|
||||
artifactBuilder = MockArtifactBuilder();
|
||||
doctor = MockDoctor();
|
||||
logger = MockShorebirdLogger();
|
||||
flutterValidator = MockShorebirdFlutterValidator();
|
||||
shorebirdValidator = MockShorebirdValidator();
|
||||
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults.wasParsed(any())).thenReturn(false);
|
||||
when(() => logger.progress(any())).thenReturn(MockProgress());
|
||||
when(() => logger.info(any())).thenReturn(null);
|
||||
when(
|
||||
() => doctor.androidCommandValidators,
|
||||
).thenReturn([flutterValidator]);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => artifactBuilder.buildAppBundle(
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenAnswer((_) async => File(''));
|
||||
|
||||
command = runWithOverrides(BuildAppBundleCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
expect(command.description, isNotEmpty);
|
||||
});
|
||||
|
||||
test('exits when validation fails', () async {
|
||||
final exception = ValidationFailedException();
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
),
|
||||
).thenThrow(exception);
|
||||
await expectLater(
|
||||
runWithOverrides(command.run),
|
||||
completion(equals(exception.exitCode.code)),
|
||||
);
|
||||
verify(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
validators: [flutterValidator],
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 70 when building appbundle fails', () async {
|
||||
when(
|
||||
() => artifactBuilder.buildAppBundle(
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenThrow(
|
||||
ArtifactBuildException('Failed to build: oops'),
|
||||
);
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.software.code));
|
||||
verify(
|
||||
() => artifactBuilder.buildAppBundle(args: []),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
group('when platform was specified via arg results rest', () {
|
||||
setUp(() {
|
||||
when(() => argResults.rest).thenReturn(['android', '--verbose']);
|
||||
});
|
||||
|
||||
test('exits with code 0 when building appbundle succeeds', () async {
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
verify(
|
||||
() => artifactBuilder.buildAppBundle(
|
||||
args: ['--verbose'],
|
||||
),
|
||||
).called(1);
|
||||
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an app bundle at:
|
||||
${lightCyan.wrap(p.join('build', 'app', 'outputs', 'bundle', 'release', 'app-release.aab'))}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
test('exits with code 0 when building appbundle succeeds', () async {
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
verify(
|
||||
() => artifactBuilder.buildAppBundle(
|
||||
args: [],
|
||||
),
|
||||
).called(1);
|
||||
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an app bundle at:
|
||||
${lightCyan.wrap(p.join('build', 'app', 'outputs', 'bundle', 'release', 'app-release.aab'))}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test(
|
||||
'exits with code 0 when building appbundle succeeds '
|
||||
'with flavor and target', () async {
|
||||
const flavor = 'development';
|
||||
final target = p.join('lib', 'main_development.dart');
|
||||
when(() => argResults['flavor']).thenReturn(flavor);
|
||||
when(() => argResults['target']).thenReturn(target);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
verify(
|
||||
() => artifactBuilder.buildAppBundle(
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
args: [],
|
||||
),
|
||||
).called(1);
|
||||
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an app bundle at:
|
||||
${lightCyan.wrap(p.join('build', 'app', 'outputs', 'bundle', '${flavor}Release', 'app-$flavor-release.aab'))}''',
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('local-engine and architectures', () async {
|
||||
expect(
|
||||
runWithOverrides(() => AndroidArch.availableAndroidArchs.length),
|
||||
greaterThan(1),
|
||||
);
|
||||
|
||||
expect(
|
||||
runScoped(
|
||||
() => AndroidArch.availableAndroidArchs.length,
|
||||
values: {
|
||||
engineConfigRef.overrideWith(
|
||||
() => const EngineConfig(
|
||||
localEngine: 'android_release_arm64',
|
||||
localEngineSrcPath: 'path/to/engine/src',
|
||||
localEngineHost: 'host_release',
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
equals(1),
|
||||
);
|
||||
|
||||
// We only support a few release configs for now.
|
||||
expect(
|
||||
() => runScoped(
|
||||
() => AndroidArch.availableAndroidArchs.length,
|
||||
values: {
|
||||
engineConfigRef.overrideWith(
|
||||
() => const EngineConfig(
|
||||
localEngine: 'android_debug_unopt',
|
||||
localEngineSrcPath: 'path/to/engine/src',
|
||||
localEngineHost: 'host_debug_unopt',
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
throwsException,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('build', () {
|
||||
late BuildCommand command;
|
||||
|
||||
setUp(() {
|
||||
command = BuildCommand();
|
||||
});
|
||||
|
||||
test('has a description', () async {
|
||||
expect(command.description, isNotEmpty);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:scoped_deps/scoped_deps.dart';
|
||||
import 'package:shorebird_cli/src/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/doctor.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/os/operating_system_interface.dart';
|
||||
import 'package:shorebird_cli/src/platform/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';
|
||||
|
||||
import '../../fakes.dart';
|
||||
import '../../mocks.dart';
|
||||
|
||||
void main() {
|
||||
group(BuildIpaCommand, () {
|
||||
late ArgResults argResults;
|
||||
late ArtifactBuilder artifactBuilder;
|
||||
late Doctor doctor;
|
||||
late Ios ios;
|
||||
late ShorebirdLogger logger;
|
||||
late OperatingSystemInterface operatingSystemInterface;
|
||||
late BuildIpaCommand command;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdFlutterValidator flutterValidator;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
|
||||
R runWithOverrides<R>(R Function() body) {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
artifactBuilderRef.overrideWith(() => artifactBuilder),
|
||||
doctorRef.overrideWith(() => doctor),
|
||||
iosRef.overrideWith(() => ios),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
osInterfaceRef.overrideWith(() => operatingSystemInterface),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FakeShorebirdProcess());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
artifactBuilder = MockArtifactBuilder();
|
||||
argResults = MockArgResults();
|
||||
doctor = MockDoctor();
|
||||
ios = MockIos();
|
||||
logger = MockShorebirdLogger();
|
||||
operatingSystemInterface = MockOperatingSystemInterface();
|
||||
flutterValidator = MockShorebirdFlutterValidator();
|
||||
shorebirdEnv = MockShorebirdEnv();
|
||||
shorebirdValidator = MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['codesign']).thenReturn(true);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => argResults.wasParsed(any())).thenReturn(false);
|
||||
when(
|
||||
() => artifactBuilder.buildIpa(
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
codesign: any(named: 'codesign'),
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenAnswer((_) async => IpaBuildResult(kernelFile: File('')));
|
||||
when(() => ios.createExportOptionsPlist()).thenReturn(File('.'));
|
||||
when(() => logger.progress(any())).thenReturn(MockProgress());
|
||||
when(() => logger.info(any())).thenReturn(null);
|
||||
when(() => operatingSystemInterface.which('flutter'))
|
||||
.thenReturn('/path/to/flutter');
|
||||
when(() => doctor.iosCommandValidators).thenReturn([flutterValidator]);
|
||||
when(() => shorebirdEnv.flutterRevision).thenReturn('1234');
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
command = runWithOverrides(BuildIpaCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
|
||||
test('has a description', () {
|
||||
expect(command.description, isNotEmpty);
|
||||
});
|
||||
|
||||
test('exits when validation fails', () async {
|
||||
final exception = ValidationFailedException();
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
checkShorebirdInitialized: any(named: 'checkShorebirdInitialized'),
|
||||
validators: any(named: 'validators'),
|
||||
),
|
||||
).thenThrow(exception);
|
||||
await expectLater(
|
||||
runWithOverrides(command.run),
|
||||
completion(equals(exception.exitCode.code)),
|
||||
);
|
||||
verify(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: true,
|
||||
checkShorebirdInitialized: true,
|
||||
validators: [flutterValidator],
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 70 when building ipa fails', () async {
|
||||
when(
|
||||
() => artifactBuilder.buildIpa(
|
||||
flavor: any(named: 'flavor'),
|
||||
target: any(named: 'target'),
|
||||
codesign: any(named: 'codesign'),
|
||||
args: any(named: 'args'),
|
||||
),
|
||||
).thenThrow(ArtifactBuildException('oops'));
|
||||
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.software.code));
|
||||
verify(
|
||||
() => artifactBuilder.buildIpa(
|
||||
args: [],
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
group('when platform was specified via arg results rest', () {
|
||||
setUp(() {
|
||||
when(() => argResults.rest).thenReturn(['ios', '--verbose']);
|
||||
});
|
||||
|
||||
test('exits with code 0 when building ipa succeeds', () async {
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildIpa(args: ['--verbose']),
|
||||
).called(1);
|
||||
|
||||
verifyInOrder([
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an xcode archive at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'archive', 'Runner.xcarchive'))}''',
|
||||
),
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an ipa at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'ipa', 'Runner.ipa'))}''',
|
||||
),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('exits with code 0 when building ipa succeeds', () async {
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
|
||||
verify(() => artifactBuilder.buildIpa(args: [])).called(1);
|
||||
|
||||
verifyInOrder([
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an xcode archive at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'archive', 'Runner.xcarchive'))}''',
|
||||
),
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an ipa at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'ipa', 'Runner.ipa'))}''',
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
test(
|
||||
'exits with code 0 when building ipa succeeds '
|
||||
'with flavor and target', () async {
|
||||
const flavor = 'development';
|
||||
final target = p.join('lib', 'main_development.dart');
|
||||
when(() => argResults['flavor']).thenReturn(flavor);
|
||||
when(() => argResults['target']).thenReturn(target);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildIpa(
|
||||
flavor: flavor,
|
||||
target: target,
|
||||
args: [],
|
||||
),
|
||||
).called(1);
|
||||
|
||||
verifyInOrder([
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an xcode archive at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'archive', 'Runner.xcarchive'))}''',
|
||||
),
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an ipa at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'ipa', 'Runner.ipa'))}''',
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
test(
|
||||
'exits with code 0 when building ipa succeeds '
|
||||
'with --no-codesign', () async {
|
||||
when(() => argResults['codesign']).thenReturn(false);
|
||||
final exitCode = await runWithOverrides(command.run);
|
||||
|
||||
expect(exitCode, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => artifactBuilder.buildIpa(codesign: false, args: []),
|
||||
).called(1);
|
||||
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an xcode archive at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'archive', 'Runner.xcarchive'))}''',
|
||||
),
|
||||
).called(1);
|
||||
|
||||
verifyNever(
|
||||
() => logger.info(
|
||||
'''
|
||||
📦 Generated an ipa at:
|
||||
${lightCyan.wrap(p.join('build', 'ios', 'ipa', 'Runner.ipa'))}''',
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user