feat(shorebird_cli): shorebird preview clears app data before installing app (#1364)
This commit is contained in:
@@ -247,6 +247,7 @@ class PreviewCommand extends ShorebirdCommand {
|
||||
|
||||
final startAppProgress = logger.progress('Starting app');
|
||||
try {
|
||||
await adb.clearAppData(package: package, deviceId: deviceId);
|
||||
await adb.startApp(package: package, deviceId: deviceId);
|
||||
startAppProgress.complete();
|
||||
} catch (error) {
|
||||
|
||||
@@ -27,6 +27,21 @@ class Adb {
|
||||
return process.start(adbPath, command.split(' '));
|
||||
}
|
||||
|
||||
/// Clears the app data for the given [package] name.
|
||||
Future<void> clearAppData({required String package, String? deviceId}) async {
|
||||
final args = [
|
||||
if (deviceId != null) ...['-s', deviceId],
|
||||
'shell',
|
||||
'pm',
|
||||
'clear',
|
||||
package,
|
||||
];
|
||||
final result = await _exec(args.join(' '));
|
||||
if (result.exitCode != 0) {
|
||||
throw Exception('Unable to clear app data: ${result.stderr}');
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts the app with the given [package] name.
|
||||
Future<void> startApp({
|
||||
required String package,
|
||||
|
||||
@@ -160,6 +160,7 @@ Or run on an iOS simulator without code signing
|
||||
[
|
||||
'--debug',
|
||||
if (deviceId != null) ...['--id', deviceId],
|
||||
'-r', // uninstall the app before reinstalling and clear app data
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
],
|
||||
|
||||
@@ -247,6 +247,12 @@ void main() {
|
||||
deviceId: any(named: 'deviceId'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => adb.clearAppData(
|
||||
package: any(named: 'package'),
|
||||
deviceId: any(named: 'deviceId'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
when(
|
||||
() => adb.startApp(
|
||||
package: any(named: 'package'),
|
||||
@@ -367,6 +373,23 @@ void main() {
|
||||
verify(() => bundletool.installApks(apks: apksPath())).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 70 when clearing app data fails', () async {
|
||||
when(
|
||||
() => artifactManager.extractZip(
|
||||
zipFile: any(named: 'zipFile'),
|
||||
outputDirectory: any(named: 'outputDirectory'),
|
||||
),
|
||||
).thenAnswer(createShorebirdYaml);
|
||||
|
||||
final exception = Exception('oops');
|
||||
when(
|
||||
() => adb.clearAppData(package: any(named: 'package')),
|
||||
).thenThrow(exception);
|
||||
final result = await runWithOverrides(command.run);
|
||||
expect(result, equals(ExitCode.software.code));
|
||||
verify(() => adb.clearAppData(package: packageName)).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 70 when starting app fails', () async {
|
||||
when(
|
||||
() => artifactManager.extractZip(
|
||||
|
||||
@@ -48,6 +48,71 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
group('clearAppData', () {
|
||||
const package = 'com.example.app';
|
||||
test('throws when unable to locate adb', () async {
|
||||
when(() => androidSdk.adbPath).thenReturn(null);
|
||||
await expectLater(
|
||||
() => runWithOverrides(() => adb.clearAppData(package: package)),
|
||||
throwsA(
|
||||
isA<Exception>().having(
|
||||
(e) => e.toString(),
|
||||
'exception()',
|
||||
contains('Unable to locate adb'),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('throws process exits with non-zero exit code', () async {
|
||||
when(
|
||||
() => process.run(any(), any()),
|
||||
).thenAnswer(
|
||||
(_) async => const ShorebirdProcessResult(
|
||||
exitCode: 1,
|
||||
stdout: '',
|
||||
stderr: 'oops',
|
||||
),
|
||||
);
|
||||
await expectLater(
|
||||
() => runWithOverrides(() => adb.clearAppData(package: package)),
|
||||
throwsA(
|
||||
isA<Exception>().having(
|
||||
(e) => e.toString(),
|
||||
'exception()',
|
||||
contains('Unable to clear app data: oops'),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('completes when process exits with 0', () async {
|
||||
await expectLater(
|
||||
runWithOverrides(() => adb.clearAppData(package: package)),
|
||||
completes,
|
||||
);
|
||||
verify(
|
||||
() => process.run(adbPath, 'shell pm clear $package'.split(' ')),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('forwards deviceId when provided', () async {
|
||||
const deviceId = '1234';
|
||||
await expectLater(
|
||||
runWithOverrides(
|
||||
() => adb.clearAppData(package: package, deviceId: deviceId),
|
||||
),
|
||||
completes,
|
||||
);
|
||||
verify(
|
||||
() => process.run(
|
||||
adbPath,
|
||||
'-s $deviceId shell pm clear $package'.split(' '),
|
||||
),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
|
||||
group('startApp', () {
|
||||
const package = 'com.example.app';
|
||||
test('throws when unable to locate adb', () async {
|
||||
|
||||
@@ -93,6 +93,7 @@ void main() {
|
||||
'--debug',
|
||||
'--id',
|
||||
deviceId,
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -113,6 +114,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -132,6 +134,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -157,6 +160,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -183,6 +187,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -207,6 +212,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -232,6 +238,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -257,6 +264,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -287,6 +295,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -312,6 +321,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
@@ -336,6 +346,7 @@ void main() {
|
||||
verify(
|
||||
() => shorebirdProcess.start(any(that: endsWith('ios-deploy')), [
|
||||
'--debug',
|
||||
'-r',
|
||||
'--bundle',
|
||||
bundlePath,
|
||||
]),
|
||||
|
||||
Reference in New Issue
Block a user