refactor(shorebird_cli): add buildAar to ArtifactBuilder (#2001)
This commit is contained in:
@@ -144,6 +144,36 @@ class ArtifactBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> buildAar({
|
||||
required String buildNumber,
|
||||
Iterable<Arch>? targetPlatforms,
|
||||
List<String> argResultsRest = const [],
|
||||
}) async {
|
||||
return _runShorebirdBuildCommand(() async {
|
||||
const executable = 'flutter';
|
||||
final targetPlatformArgs = targetPlatforms?.targetPlatformArg;
|
||||
final arguments = [
|
||||
'build',
|
||||
'aar',
|
||||
'--no-debug',
|
||||
'--no-profile',
|
||||
'--build-number=$buildNumber',
|
||||
if (targetPlatformArgs != null) '--target-platform=$targetPlatformArgs',
|
||||
...argResultsRest,
|
||||
];
|
||||
|
||||
final result = await process.run(
|
||||
executable,
|
||||
arguments,
|
||||
runInShell: true,
|
||||
);
|
||||
|
||||
if (result.exitCode != ExitCode.success.code) {
|
||||
throw ArtifactBuildException('Failed to build: ${result.stderr}');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// A wrapper around [command] (which runs a `flutter build` command with
|
||||
/// Shorebird's fork of Flutter) with a try/finally that runs
|
||||
/// `flutter pub get` with the system installation of Flutter to reset
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
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/command.dart';
|
||||
import 'package:shorebird_cli/src/logger.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';
|
||||
|
||||
@@ -14,7 +13,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 ShorebirdBuildMixin {
|
||||
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
|
||||
@@ -54,8 +53,8 @@ class BuildAarCommand extends ShorebirdCommand with ShorebirdBuildMixin {
|
||||
final buildNumber = results['build-number'] as String;
|
||||
final buildProgress = logger.progress('Building aar');
|
||||
try {
|
||||
await buildAar(buildNumber: buildNumber);
|
||||
} on ProcessException catch (error) {
|
||||
await artifactBuilder.buildAar(buildNumber: buildNumber);
|
||||
} on ArtifactBuildException catch (error) {
|
||||
buildProgress.fail('Failed to build: ${error.message}');
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
|
||||
@@ -415,5 +415,88 @@ Either run `flutter pub get` manually, or follow the steps in ${link(uri: Uri.pa
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('buildAar', () {
|
||||
const buildNumber = '1.0';
|
||||
|
||||
test('invokes the correct flutter build command', () async {
|
||||
await runWithOverrides(
|
||||
() => builder.buildAar(buildNumber: buildNumber),
|
||||
);
|
||||
|
||||
verify(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
[
|
||||
'build',
|
||||
'aar',
|
||||
'--no-debug',
|
||||
'--no-profile',
|
||||
'--build-number=1.0',
|
||||
],
|
||||
runInShell: any(named: 'runInShell'),
|
||||
environment: any(named: 'environment'),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('forward arguments to flutter build', () async {
|
||||
await runWithOverrides(
|
||||
() => builder.buildAar(
|
||||
buildNumber: buildNumber,
|
||||
targetPlatforms: [Arch.arm64],
|
||||
argResultsRest: ['--foo', 'bar'],
|
||||
),
|
||||
);
|
||||
|
||||
verify(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
[
|
||||
'build',
|
||||
'aar',
|
||||
'--no-debug',
|
||||
'--no-profile',
|
||||
'--build-number=1.0',
|
||||
'--target-platform=android-arm64',
|
||||
'--foo',
|
||||
'bar',
|
||||
],
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
group('after a build', () {
|
||||
group('when the build is successful', () {
|
||||
setUp(() {
|
||||
when(() => buildProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
});
|
||||
|
||||
verifyCorrectFlutterPubGet(
|
||||
() async => runWithOverrides(
|
||||
() => builder.buildAar(buildNumber: buildNumber),
|
||||
),
|
||||
);
|
||||
|
||||
group('when the build fails', () {
|
||||
setUp(() {
|
||||
when(() => buildProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.software.code);
|
||||
});
|
||||
|
||||
verifyCorrectFlutterPubGet(
|
||||
() async => expectLater(
|
||||
() async => runWithOverrides(
|
||||
() => builder.buildAar(buildNumber: buildNumber),
|
||||
),
|
||||
throwsA(isA<ArtifactBuildException>()),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@ 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/artifact_builder.dart';
|
||||
import 'package:shorebird_cli/src/commands/build/build.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:shorebird_cli/src/os/operating_system_interface.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_env.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_process.dart';
|
||||
import 'package:shorebird_cli/src/shorebird_validator.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
@@ -19,13 +18,10 @@ void main() {
|
||||
const androidPackageName = 'com.example.my_flutter_module';
|
||||
|
||||
late ArgResults argResults;
|
||||
late ArtifactBuilder artifactBuilder;
|
||||
late Logger logger;
|
||||
late OperatingSystemInterface operatingSystemInterface;
|
||||
late Progress progress;
|
||||
late ShorebirdEnv shorebirdEnv;
|
||||
late ShorebirdProcess shorebirdProcess;
|
||||
late ShorebirdProcessResult buildProcessResult;
|
||||
late ShorebirdProcessResult flutterPubGetProcessResult;
|
||||
late ShorebirdValidator shorebirdValidator;
|
||||
late BuildAarCommand command;
|
||||
|
||||
@@ -33,9 +29,8 @@ void main() {
|
||||
return runScoped(
|
||||
body,
|
||||
values: {
|
||||
artifactBuilderRef.overrideWith(() => artifactBuilder),
|
||||
loggerRef.overrideWith(() => logger),
|
||||
osInterfaceRef.overrideWith(() => operatingSystemInterface),
|
||||
processRef.overrideWith(() => shorebirdProcess),
|
||||
shorebirdEnvRef.overrideWith(() => shorebirdEnv),
|
||||
shorebirdValidatorRef.overrideWith(() => shorebirdValidator),
|
||||
},
|
||||
@@ -44,41 +39,21 @@ void main() {
|
||||
|
||||
setUp(() {
|
||||
argResults = MockArgResults();
|
||||
artifactBuilder = MockArtifactBuilder();
|
||||
logger = MockLogger();
|
||||
flutterPubGetProcessResult = MockProcessResult();
|
||||
buildProcessResult = MockProcessResult();
|
||||
operatingSystemInterface = MockOperatingSystemInterface();
|
||||
progress = MockProgress();
|
||||
shorebirdEnv = MockShorebirdEnv();
|
||||
shorebirdProcess = MockShorebirdProcess();
|
||||
shorebirdValidator = MockShorebirdValidator();
|
||||
|
||||
when(() => argResults['build-number']).thenReturn(buildNumber);
|
||||
when(() => argResults.rest).thenReturn([]);
|
||||
when(() => logger.progress(any())).thenReturn(progress);
|
||||
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
['--no-version-check', 'pub', 'get', '--offline'],
|
||||
runInShell: any(named: 'runInShell'),
|
||||
useVendedFlutter: false,
|
||||
),
|
||||
).thenAnswer((_) async => flutterPubGetProcessResult);
|
||||
when(() => flutterPubGetProcessResult.exitCode)
|
||||
.thenReturn(ExitCode.success.code);
|
||||
() => artifactBuilder.buildAar(buildNumber: any(named: 'buildNumber')),
|
||||
).thenAnswer((_) async => {});
|
||||
when(
|
||||
() => shorebirdProcess.run(
|
||||
any(),
|
||||
any(),
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).thenAnswer((invocation) async {
|
||||
return buildProcessResult;
|
||||
});
|
||||
|
||||
when(() => operatingSystemInterface.which('flutter'))
|
||||
.thenReturn('/path/to/flutter');
|
||||
() => shorebirdEnv.androidPackageName,
|
||||
).thenReturn(androidPackageName);
|
||||
when(
|
||||
() => shorebirdValidator.validatePreconditions(
|
||||
checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'),
|
||||
@@ -86,11 +61,6 @@ void main() {
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
when(
|
||||
() => shorebirdEnv.androidPackageName,
|
||||
).thenReturn(androidPackageName);
|
||||
when(() => shorebirdEnv.flutterRevision).thenReturn('1234');
|
||||
|
||||
command = runWithOverrides(BuildAarCommand.new)
|
||||
..testArgResults = argResults;
|
||||
});
|
||||
@@ -126,49 +96,27 @@ void main() {
|
||||
});
|
||||
|
||||
test('exits with code 70 when building aar fails', () async {
|
||||
when(() => buildProcessResult.exitCode).thenReturn(1);
|
||||
when(() => buildProcessResult.stderr).thenReturn('oops');
|
||||
when(
|
||||
() => artifactBuilder.buildAar(buildNumber: any(named: 'buildNumber')),
|
||||
).thenThrow(ArtifactBuildException('Failed to build: error'));
|
||||
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.software.code));
|
||||
verify(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
[
|
||||
'build',
|
||||
'aar',
|
||||
'--no-debug',
|
||||
'--no-profile',
|
||||
'--build-number=$buildNumber',
|
||||
],
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).called(1);
|
||||
verify(() => artifactBuilder.buildAar(buildNumber: buildNumber))
|
||||
.called(1);
|
||||
verify(
|
||||
() => progress.fail(any(that: contains('Failed to build'))),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 0 when building aar succeeds', () async {
|
||||
when(() => buildProcessResult.exitCode).thenReturn(ExitCode.success.code);
|
||||
final result = await runWithOverrides(command.run);
|
||||
|
||||
expect(result, equals(ExitCode.success.code));
|
||||
|
||||
verify(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
[
|
||||
'build',
|
||||
'aar',
|
||||
'--no-debug',
|
||||
'--no-profile',
|
||||
'--build-number=$buildNumber',
|
||||
],
|
||||
runInShell: any(named: 'runInShell'),
|
||||
),
|
||||
).called(1);
|
||||
verify(() => artifactBuilder.buildAar(buildNumber: buildNumber))
|
||||
.called(1);
|
||||
verify(
|
||||
() => logger.info(
|
||||
'''
|
||||
@@ -190,20 +138,5 @@ ${lightCyan.wrap(
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('runs flutter pub get with system flutter after successful build',
|
||||
() async {
|
||||
when(() => buildProcessResult.exitCode).thenReturn(ExitCode.success.code);
|
||||
await runWithOverrides(command.run);
|
||||
|
||||
verify(
|
||||
() => shorebirdProcess.run(
|
||||
'flutter',
|
||||
['--no-version-check', 'pub', 'get', '--offline'],
|
||||
runInShell: any(named: 'runInShell'),
|
||||
useVendedFlutter: false,
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user