From 955c8ba87f1d98299474c536fa0ae75577625afc Mon Sep 17 00:00:00 2001 From: Erick Date: Thu, 25 Apr 2024 13:49:53 -0300 Subject: [PATCH] fix: patch multi dimensional flavor patch and improve release (#1968) Co-authored-by: Bryan Oltman --- .../src/commands/build/build_apk_command.dart | 6 +- .../build/build_app_bundle_command.dart | 6 +- .../commands/patch/patch_android_command.dart | 27 ++---- .../release/release_android_command.dart | 33 ++----- .../lib/src/shorebird_android_artifacts.dart | 4 +- .../lib/src/shorebird_build_mixin.dart | 59 ++++++++++--- .../build/build_apk_command_test.dart | 18 ++++ .../build/build_app_bundle_command_test.dart | 15 ++++ .../patch/patch_android_command_test.dart | 13 +++ .../release/release_android_command_test.dart | 52 +++++++++-- .../src/shorebird_android_artifacts_test.dart | 88 ++++++++++++++----- 11 files changed, 226 insertions(+), 95 deletions(-) diff --git a/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart b/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart index 13508e26..f3ffefd8 100644 --- a/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart +++ b/packages/shorebird_cli/lib/src/commands/build/build_apk_command.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:mason_logger/mason_logger.dart'; import 'package:path/path.dart' as p; import 'package:shorebird_cli/src/command.dart'; @@ -51,8 +49,8 @@ class BuildApkCommand extends ShorebirdCommand with ShorebirdBuildMixin { final buildProgress = logger.progress('Building apk'); try { await buildApk(flavor: flavor, target: target); - } on ProcessException catch (error) { - buildProgress.fail('Failed to build: ${error.message}'); + } on BuildException catch (error) { + buildProgress.fail(error.message); return ExitCode.software.code; } diff --git a/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart b/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart index ee60daa0..e1c4c749 100644 --- a/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart +++ b/packages/shorebird_cli/lib/src/commands/build/build_app_bundle_command.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:mason_logger/mason_logger.dart'; import 'package:path/path.dart' as p; import 'package:shorebird_cli/src/command.dart'; @@ -51,8 +49,8 @@ class BuildAppBundleCommand extends ShorebirdCommand with ShorebirdBuildMixin { final buildProgress = logger.progress('Building appbundle'); try { await buildAppBundle(flavor: flavor, target: target); - } on ProcessException catch (error) { - buildProgress.fail('Failed to build: ${error.message}'); + } on BuildException catch (error) { + buildProgress.fail(error.message); return ExitCode.software.code; } diff --git a/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart b/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart index a42f7005..355c0dc5 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/patch_android_command.dart @@ -116,18 +116,9 @@ If this option is not provided, the version number will be determined from the p final app = await codePushClientWrapper.getApp(appId: appId); var hasBuiltWithActiveFlutter = false; + late File aabFile; final projectRoot = shorebirdEnv.getShorebirdProjectRoot()!; - final bundleDirPath = p.join( - projectRoot.path, - 'build', - 'app', - 'outputs', - 'bundle', - ); - final bundlePath = flavor != null - ? p.join(bundleDirPath, '${flavor}Release', 'app-$flavor-release.aab') - : p.join(bundleDirPath, 'release', 'app-release.aab'); final String releaseVersion; final argReleaseVersion = results['release-version'] as String?; @@ -142,10 +133,10 @@ If this option is not provided, the version number will be determined from the p 'Building patch with Flutter $flutterVersionString', ); try { - await buildAppBundle(flavor: flavor, target: target); + aabFile = await buildAppBundle(flavor: flavor, target: target); buildProgress.complete(); - } on ProcessException catch (error) { - buildProgress.fail('Failed to build: ${error.message}'); + } on BuildException catch (error) { + buildProgress.fail(error.message); return ExitCode.software.code; } @@ -156,7 +147,7 @@ If this option is not provided, the version number will be determined from the p ); try { - releaseVersion = await extractReleaseVersionFromAppBundle(bundlePath); + releaseVersion = await extractReleaseVersionFromAppBundle(aabFile.path); detectReleaseVersionProgress.complete( 'Detected release version $releaseVersion', ); @@ -202,10 +193,10 @@ Please re-run the release command for this version or create a new release.'''); currentFlutterRevision != release.flutterRevision) { final buildProgress = logger.progress('Building patch'); try { - await buildAppBundle(flavor: flavor, target: target); + aabFile = await buildAppBundle(flavor: flavor, target: target); buildProgress.complete(); - } on ProcessException catch (error) { - buildProgress.fail('Failed to build: ${error.message}'); + } on BuildException catch (error) { + buildProgress.fail(error.message); return ExitCode.software.code; } } @@ -276,7 +267,7 @@ Looked in: try { diffStatus = await patchDiffChecker.confirmUnpatchableDiffsIfNecessary( - localArtifact: File(bundlePath), + localArtifact: aabFile, releaseArtifact: releaseAabArtifactFile, archiveDiffer: _archiveDiffer, allowAssetChanges: allowAssetDiffs, diff --git a/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart b/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart index c0b2707d..4190fb93 100644 --- a/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart +++ b/packages/shorebird_cli/lib/src/commands/release/release_android_command.dart @@ -11,7 +11,6 @@ import 'package:shorebird_cli/src/extensions/arg_results.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/platform/platform.dart'; -import 'package:shorebird_cli/src/shorebird_android_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_build_mixin.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; @@ -171,21 +170,24 @@ Use `shorebird flutter versions list` to list available versions. 'Building release with Flutter $flutterVersionString', ); + late final File apkFile; + final File aabFile; + try { - await buildAppBundle( + aabFile = await buildAppBundle( flavor: flavor, target: target, targetPlatforms: architectures, ); if (generateApk) { - await buildApk( + apkFile = await buildApk( flavor: flavor, target: target, targetPlatforms: architectures, ); } - } on ProcessException catch (error) { - buildProgress.fail('Failed to build: ${error.message}'); + } on BuildException catch (error) { + buildProgress.fail(error.message); return ExitCode.software.code; } buildProgress.complete(); @@ -195,27 +197,6 @@ Use `shorebird flutter versions list` to list available versions. final appId = shorebirdYaml.getAppId(flavor: flavor); final app = await codePushClientWrapper.getApp(appId: appId); - late final File apkFile; - final File aabFile; - try { - aabFile = shorebirdAndroidArtifacts.findAab( - project: projectRoot, - flavor: flavor, - ); - if (generateApk) { - apkFile = shorebirdAndroidArtifacts.findApk( - project: projectRoot, - flavor: flavor, - ); - } - } on ArtifactNotFoundException catch (error) { - logger.err(error.toString()); - return ExitCode.software.code; - } on MultipleArtifactsFoundException catch (error) { - logger.err(error.toString()); - return ExitCode.software.code; - } - final String releaseVersion; final detectReleaseVersionProgress = logger.progress( 'Detecting release version', diff --git a/packages/shorebird_cli/lib/src/shorebird_android_artifacts.dart b/packages/shorebird_cli/lib/src/shorebird_android_artifacts.dart index 86867e0e..397b8fb6 100644 --- a/packages/shorebird_cli/lib/src/shorebird_android_artifacts.dart +++ b/packages/shorebird_cli/lib/src/shorebird_android_artifacts.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:collection/collection.dart'; import 'package:path/path.dart' as p; import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/command.dart'; @@ -16,8 +17,9 @@ class MultipleArtifactsFoundException implements Exception { @override String toString() { + final artifacts = foundArtifacts.sortedBy((e) => e.path); return 'Multiple artifacts found in $buildDir: ' - '${foundArtifacts.map((e) => e.path)}'; + '${artifacts.map((e) => e.path)}'; } } diff --git a/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart index f17aff07..ddac7e0f 100644 --- a/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart @@ -5,7 +5,9 @@ import 'package:shorebird_cli/src/command.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_android_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_artifacts.dart'; +import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; /// Used to wrap code that invokes `flutter build` with Shorebird's fork of @@ -24,12 +26,12 @@ class BuildException implements Exception { } mixin ShorebirdBuildMixin on ShorebirdCommand { - Future buildAppBundle({ + Future buildAppBundle({ String? flavor, String? target, Iterable? targetPlatforms, }) async { - return _runShorebirdBuildCommand(() async { + await _runShorebirdBuildCommand(() async { const executable = 'flutter'; final targetPlatformArgs = targetPlatforms?.targetPlatformArg; final arguments = [ @@ -49,14 +51,29 @@ mixin ShorebirdBuildMixin on ShorebirdCommand { ); if (result.exitCode != ExitCode.success.code) { - throw ProcessException( - 'flutter', - arguments, - result.stderr.toString(), - result.exitCode, + throw BuildException( + 'Failed to build: ${result.stderr}', ); } }); + + final projectRoot = shorebirdEnv.getShorebirdProjectRoot()!; + try { + return shorebirdAndroidArtifacts.findAab( + project: projectRoot, + flavor: flavor, + ); + } on MultipleArtifactsFoundException catch (error) { + throw BuildException( + 'Build succeeded, but it generated multiple AABs in the ' + 'build directory. ${error.foundArtifacts.map((e) => e.path)}', + ); + } on ArtifactNotFoundException catch (error) { + throw BuildException( + 'Build succeeded, but could not find the AAB in the build directory. ' + 'Expected to find ${error.artifactName}', + ); + } } Future buildAar({ @@ -93,13 +110,13 @@ mixin ShorebirdBuildMixin on ShorebirdCommand { }); } - Future buildApk({ + Future buildApk({ String? flavor, String? target, Iterable? targetPlatforms, bool splitPerAbi = false, }) async { - return _runShorebirdBuildCommand(() async { + await _runShorebirdBuildCommand(() async { const executable = 'flutter'; final targetPlatformArgs = targetPlatforms?.targetPlatformArg; final arguments = [ @@ -124,14 +141,28 @@ mixin ShorebirdBuildMixin on ShorebirdCommand { ); if (result.exitCode != ExitCode.success.code) { - throw ProcessException( - 'flutter', - arguments, - result.stderr.toString(), - result.exitCode, + throw BuildException( + 'Failed to build: ${result.stderr}', ); } }); + final projectRoot = shorebirdEnv.getShorebirdProjectRoot()!; + try { + return shorebirdAndroidArtifacts.findApk( + project: projectRoot, + flavor: flavor, + ); + } on MultipleArtifactsFoundException catch (error) { + throw BuildException( + 'Build succeeded, but it generated multiple APKs in the ' + 'build directory. ${error.foundArtifacts.map((e) => e.path)}', + ); + } on ArtifactNotFoundException catch (error) { + throw BuildException( + 'Build succeeded, but could not find the APK in the build directory. ' + 'Expected to find ${error.artifactName}', + ); + } } /// Calls `flutter build ipa`. If [codesign] is false, this will only build diff --git a/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart b/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart index 56c70407..bc2660b0 100644 --- a/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/build/build_apk_command_test.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:args/args.dart'; import 'package:mason_logger/mason_logger.dart'; import 'package:mocktail/mocktail.dart'; @@ -7,6 +9,7 @@ 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/shorebird_android_artifacts.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'; @@ -29,6 +32,7 @@ void main() { late ShorebirdFlutterValidator flutterValidator; late ShorebirdProcess shorebirdProcess; late ShorebirdValidator shorebirdValidator; + late ShorebirdAndroidArtifacts shorebirdAndroidArtifacts; R runWithOverrides(R Function() body) { return runScoped( @@ -40,11 +44,14 @@ void main() { processRef.overrideWith(() => shorebirdProcess), shorebirdEnvRef.overrideWith(() => shorebirdEnv), shorebirdValidatorRef.overrideWith(() => shorebirdValidator), + shorebirdAndroidArtifactsRef + .overrideWith(() => shorebirdAndroidArtifacts), }, ); } setUpAll(() { + registerFallbackValue(Directory('')); registerFallbackValue(FakeShorebirdProcess()); }); @@ -59,6 +66,7 @@ void main() { flutterValidator = MockShorebirdFlutterValidator(); shorebirdEnv = MockShorebirdEnv(); shorebirdValidator = MockShorebirdValidator(); + shorebirdAndroidArtifacts = MockShorebirdAndroidArtifacts(); when( () => shorebirdProcess.run( @@ -83,6 +91,7 @@ void main() { when(() => operatingSystemInterface.which('flutter')) .thenReturn('/path/to/flutter'); when(() => shorebirdEnv.flutterRevision).thenReturn('1234'); + when(shorebirdEnv.getShorebirdProjectRoot).thenReturn(Directory('')); when( () => shorebirdValidator.validatePreconditions( @@ -95,6 +104,15 @@ void main() { () => doctor.androidCommandValidators, ).thenReturn([flutterValidator]); + when( + () => shorebirdAndroidArtifacts.findApk( + project: any(named: 'project'), + flavor: any( + named: 'flavor', + ), + ), + ).thenReturn(File('')); + command = runWithOverrides(BuildApkCommand.new) ..testArgResults = argResults; }); diff --git a/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart b/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart index 06f8291e..2d55217e 100644 --- a/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/build/build_app_bundle_command_test.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:args/args.dart'; import 'package:mason_logger/mason_logger.dart'; import 'package:mocktail/mocktail.dart'; @@ -9,6 +11,7 @@ import 'package:shorebird_cli/src/engine_config.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_android_artifacts.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'; @@ -31,6 +34,7 @@ void main() { late ShorebirdFlutterValidator flutterValidator; late ShorebirdProcess shorebirdProcess; late ShorebirdValidator shorebirdValidator; + late ShorebirdAndroidArtifacts shorebirdAndroidArtifacts; R runWithOverrides(R Function() body) { return runScoped( @@ -43,12 +47,15 @@ void main() { processRef.overrideWith(() => shorebirdProcess), shorebirdEnvRef.overrideWith(() => shorebirdEnv), shorebirdValidatorRef.overrideWith(() => shorebirdValidator), + shorebirdAndroidArtifactsRef + .overrideWith(() => shorebirdAndroidArtifacts), }, ); } setUpAll(() { registerFallbackValue(FakeShorebirdProcess()); + registerFallbackValue(Directory('')); }); setUp(() { @@ -62,6 +69,7 @@ void main() { shorebirdEnv = MockShorebirdEnv(); shorebirdProcess = MockShorebirdProcess(); shorebirdValidator = MockShorebirdValidator(); + shorebirdAndroidArtifacts = MockShorebirdAndroidArtifacts(); when( () => shorebirdProcess.run( @@ -89,6 +97,7 @@ void main() { () => doctor.androidCommandValidators, ).thenReturn([flutterValidator]); when(() => shorebirdEnv.flutterRevision).thenReturn('1234'); + when(shorebirdEnv.getShorebirdProjectRoot).thenReturn(Directory('')); when( () => shorebirdValidator.validatePreconditions( checkUserIsAuthenticated: any(named: 'checkUserIsAuthenticated'), @@ -96,6 +105,12 @@ void main() { validators: any(named: 'validators'), ), ).thenAnswer((_) async {}); + when( + () => shorebirdAndroidArtifacts.findAab( + project: any(named: 'project'), + flavor: any(named: 'flavor'), + ), + ).thenReturn(File('app-release.aab')); command = runWithOverrides(BuildAppBundleCommand.new) ..testArgResults = argResults; diff --git a/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart b/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart index 9b1aa5bb..52ac5a73 100644 --- a/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/patch/patch_android_command_test.dart @@ -24,6 +24,7 @@ import 'package:shorebird_cli/src/os/operating_system_interface.dart'; import 'package:shorebird_cli/src/patch_diff_checker.dart'; import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/platform/platform.dart'; +import 'package:shorebird_cli/src/shorebird_android_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; import 'package:shorebird_cli/src/shorebird_process.dart'; @@ -121,6 +122,7 @@ flutter: late ShorebirdFlutterValidator flutterValidator; late ShorebirdProcess shorebirdProcess; late ShorebirdValidator shorebirdValidator; + late ShorebirdAndroidArtifacts shorebirdAndroidArtifacts; late PatchAndroidCommand command; R runWithOverrides(R Function() body) { @@ -144,6 +146,9 @@ flutter: processRef.overrideWith(() => shorebirdProcess), shorebirdFlutterRef.overrideWith(() => shorebirdFlutter), shorebirdValidatorRef.overrideWith(() => shorebirdValidator), + shorebirdAndroidArtifactsRef.overrideWith( + () => shorebirdAndroidArtifacts, + ), }, ); } @@ -216,6 +221,7 @@ flutter: shorebirdProcess = MockShorebirdProcess(); shorebirdFlutter = MockShorebirdFlutter(); shorebirdValidator = MockShorebirdValidator(); + shorebirdAndroidArtifacts = MockShorebirdAndroidArtifacts(); command = runWithOverrides( () => PatchAndroidCommand(archiveDiffer: archiveDiffer), )..testArgResults = argResults; @@ -393,6 +399,13 @@ flutter: when(() => platform.operatingSystemVersion) .thenReturn(operatingSystemVersion); when(() => shorebirdEnv.canAcceptUserInput).thenReturn(true); + + when( + () => shorebirdAndroidArtifacts.findAab( + project: any(named: 'project'), + flavor: any(named: 'flavor'), + ), + ).thenReturn(File('release.aab')); }); test('has a description', () { diff --git a/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart b/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart index 8e116443..c345f85f 100644 --- a/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/release/release_android_command_test.dart @@ -921,22 +921,32 @@ Note: ${lightCyan.wrap('shorebird patch android --flavor=$flavor --target=$targe verifyNever(() => logger.confirm(any())); }); - test('errors when the app bundle cannot be found', () async { + test('errors when multiple apks are found', () async { shorebirdAndroidArtifacts = MockShorebirdAndroidArtifacts(); + when(() => argResults['artifact']).thenReturn('apk'); when( () => shorebirdAndroidArtifacts.findAab( project: any(named: 'project'), flavor: any(named: 'flavor'), ), + ).thenReturn(File('app-release.aab')); + when( + () => shorebirdAndroidArtifacts.findApk( + project: any(named: 'project'), + flavor: any(named: 'flavor'), + ), ).thenThrow( - ArtifactNotFoundException( - artifactName: 'app-release.aab', + MultipleArtifactsFoundException( + foundArtifacts: [File('a'), File('b')], buildDir: 'buildDir', ), ); final exitCode = await runWithOverrides(command.run); verify( - () => logger.err('Artifact app-release.aab not found in buildDir'), + () => progress.fail( + 'Build succeeded, but it generated multiple APKs in the build ' + 'directory. (a, b)', + ), ).called(1); expect(exitCode, ExitCode.software.code); }); @@ -963,12 +973,37 @@ Note: ${lightCyan.wrap('shorebird patch android --flavor=$flavor --target=$targe ); final exitCode = await runWithOverrides(command.run); verify( - () => logger.err('Artifact app-release.apk not found in buildDir'), + () => progress.fail( + 'Build succeeded, but could not find the APK in the build ' + 'directory. Expected to find app-release.apk', + ), ).called(1); expect(exitCode, ExitCode.software.code); }); - test('errors when multiple artifacts are found', () async { + test('errors when the app bundle cannot be found', () async { + shorebirdAndroidArtifacts = MockShorebirdAndroidArtifacts(); + when( + () => shorebirdAndroidArtifacts.findAab( + project: any(named: 'project'), + flavor: any(named: 'flavor'), + ), + ).thenThrow( + ArtifactNotFoundException( + artifactName: 'app-release.aab', + buildDir: 'buildDir', + ), + ); + final exitCode = await runWithOverrides(command.run); + verify( + () => progress + .fail('Build succeeded, but could not find the AAB in the build ' + 'directory. Expected to find app-release.aab'), + ).called(1); + expect(exitCode, ExitCode.software.code); + }); + + test('errors when multiple aabs are found', () async { shorebirdAndroidArtifacts = MockShorebirdAndroidArtifacts(); when( () => shorebirdAndroidArtifacts.findAab( @@ -983,7 +1018,10 @@ Note: ${lightCyan.wrap('shorebird patch android --flavor=$flavor --target=$targe ); final exitCode = await runWithOverrides(command.run); verify( - () => logger.err('Multiple artifacts found in buildDir: (a, b)'), + () => progress.fail( + 'Build succeeded, but it generated multiple AABs in the build ' + 'directory. (a, b)', + ), ).called(1); expect(exitCode, ExitCode.software.code); }); diff --git a/packages/shorebird_cli/test/src/shorebird_android_artifacts_test.dart b/packages/shorebird_cli/test/src/shorebird_android_artifacts_test.dart index c8980d89..b98d8909 100644 --- a/packages/shorebird_cli/test/src/shorebird_android_artifacts_test.dart +++ b/packages/shorebird_cli/test/src/shorebird_android_artifacts_test.dart @@ -25,19 +25,34 @@ void main() { }); test('throws ArtifactNotFoundException for apks', () { + final buildDir = Directory( + path.join( + project.path, + 'build', + 'app', + 'outputs', + 'flutter-apk', + ), + ); expect( () => shorebirdAndroidArtifacts.findApk( project: project, flavor: null, ), - throwsA(isA()), + throwsA( + isA().having( + (exception) => exception.toString(), + 'message', + equals('Artifact app-release.apk not found in ${buildDir.path}'), + ), + ), ); }); }); group('when build folder exists but not the file', () { test('throws ArtifactNotFoundException for aabs', () { - Directory( + final buildDir = Directory( path.join( project.path, 'build', @@ -46,13 +61,19 @@ void main() { 'bundle', 'release', ), - ).createSync(recursive: true); + )..createSync(recursive: true); expect( () => shorebirdAndroidArtifacts.findAab( project: project, flavor: null, ), - throwsA(isA()), + throwsA( + isA().having( + (exception) => exception.toString(), + 'message', + equals('Artifact app-release.aab not found in ${buildDir.path}'), + ), + ), ); }); @@ -287,20 +308,28 @@ void main() { group('when multiple files are found', () { test('throws MultipleArtifactsFoundException when looking for aab', () { + final buildDir = Directory( + path.join( + project.path, + 'build', + 'app', + 'outputs', + 'bundle', + 'stablePlayStoreRelease', + ), + ); final duplicatedArtifactPath = path.join( - 'build', - 'app', - 'outputs', - 'bundle', - 'stablePlayStoreRelease', + buildDir.path, 'app---stable-playStore-release.aab', ); File( path.join(project.path, duplicatedArtifactPath), ).createSync(recursive: true); - const artifactPath = - 'build/app/outputs/bundle/stablePlayStoreRelease/app-stable-playStore-release.aab'; + final artifactPath = path.join( + buildDir.path, + 'app-stable-playStore-release.aab', + ); File( path.join(project.path, artifactPath), ).createSync(recursive: true); @@ -312,16 +341,29 @@ void main() { project: project, flavor: flavor, ), - throwsA(isA()), + throwsA( + isA().having( + (exception) => exception.toString(), + 'message', + equals('Multiple artifacts found in ${buildDir.path}: ' + '($duplicatedArtifactPath, $artifactPath)'), + ), + ), ); }); test('throws MultipleArtifactsFoundException when looking for apk', () { + final buildDir = Directory( + path.join( + project.path, + 'build', + 'app', + 'outputs', + 'flutter-apk', + ), + ); final duplicatedArtifactPath = path.join( - 'build', - 'app', - 'outputs', - 'flutter-apk', + buildDir.path, 'app----stableplaystore-release.apk', ); File( @@ -329,10 +371,7 @@ void main() { ).createSync(recursive: true); final artifactPath = path.join( - 'build', - 'app', - 'outputs', - 'flutter-apk', + buildDir.path, 'app-stableplaystore-release.apk', ); File( @@ -346,7 +385,14 @@ void main() { project: project, flavor: flavor, ), - throwsA(isA()), + throwsA( + isA().having( + (exception) => exception.toString(), + 'message', + equals('Multiple artifacts found in ${buildDir.path}: ' + '($duplicatedArtifactPath, $artifactPath)'), + ), + ), ); }); });