fix: patch multi dimensional flavor patch and improve release (#1968)
Co-authored-by: Bryan Oltman <bryan@shorebird.dev>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<void> buildAppBundle({
|
||||
Future<File> buildAppBundle({
|
||||
String? flavor,
|
||||
String? target,
|
||||
Iterable<Arch>? 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<void> buildAar({
|
||||
@@ -93,13 +110,13 @@ mixin ShorebirdBuildMixin on ShorebirdCommand {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> buildApk({
|
||||
Future<File> buildApk({
|
||||
String? flavor,
|
||||
String? target,
|
||||
Iterable<Arch>? 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
|
||||
|
||||
@@ -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>(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;
|
||||
});
|
||||
|
||||
@@ -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>(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;
|
||||
|
||||
@@ -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>(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', () {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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<ArtifactNotFoundException>()),
|
||||
throwsA(
|
||||
isA<ArtifactNotFoundException>().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<ArtifactNotFoundException>()),
|
||||
throwsA(
|
||||
isA<ArtifactNotFoundException>().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<MultipleArtifactsFoundException>()),
|
||||
throwsA(
|
||||
isA<MultipleArtifactsFoundException>().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<MultipleArtifactsFoundException>()),
|
||||
throwsA(
|
||||
isA<MultipleArtifactsFoundException>().having(
|
||||
(exception) => exception.toString(),
|
||||
'message',
|
||||
equals('Multiple artifacts found in ${buildDir.path}: '
|
||||
'($duplicatedArtifactPath, $artifactPath)'),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user