From ddd1513dd846db6db6e7dfe7a9beb3191b86217e Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Tue, 25 Jul 2023 09:04:34 -0500 Subject: [PATCH] feat(shorebird_cli): add `IOSDeploy` (#900) --- .../shorebird_cli/lib/src/ios_deploy.dart | 35 ++++++++++++ .../test/src/ios_deploy_test.dart | 56 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 packages/shorebird_cli/lib/src/ios_deploy.dart create mode 100644 packages/shorebird_cli/test/src/ios_deploy_test.dart diff --git a/packages/shorebird_cli/lib/src/ios_deploy.dart b/packages/shorebird_cli/lib/src/ios_deploy.dart new file mode 100644 index 00000000..a5ec072e --- /dev/null +++ b/packages/shorebird_cli/lib/src/ios_deploy.dart @@ -0,0 +1,35 @@ +import 'package:path/path.dart' as p; +import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_environment.dart'; + +/// Wrapper around the `ios-deploy` command cached by the Flutter tool. +/// https://github.com/ios-control/ios-deploy +class IOSDeploy { + /// Installs the .app file at [bundlePath] to the device identified by [deviceId]. + /// + /// Uses ios-deploy and returns the exit code. + /// `ios-deploy --id [deviceId] --bundle [bundlePath]` + Future installApp({ + required String deviceId, + required String bundlePath, + }) async { + final iosDeployExecutable = p.join( + ShorebirdEnvironment.flutterDirectory.path, + 'bin', + 'cache', + 'artifacts', + 'ios-deploy', + 'ios-deploy', + ); + final result = await process.run( + iosDeployExecutable, + [ + '--id', + deviceId, + '--bundle', + bundlePath, + ], + ); + return result.exitCode; + } +} diff --git a/packages/shorebird_cli/test/src/ios_deploy_test.dart b/packages/shorebird_cli/test/src/ios_deploy_test.dart new file mode 100644 index 00000000..31a86326 --- /dev/null +++ b/packages/shorebird_cli/test/src/ios_deploy_test.dart @@ -0,0 +1,56 @@ +import 'package:mocktail/mocktail.dart'; +import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/ios_deploy.dart'; +import 'package:shorebird_cli/src/process.dart'; +import 'package:test/test.dart'; + +class _MockShorebirdProcess extends Mock implements ShorebirdProcess {} + +void main() { + group(IOSDeploy, () { + late ShorebirdProcess process; + late IOSDeploy iosDeploy; + + R runWithOverrides(R Function() body) { + return runScoped( + body, + values: { + processRef.overrideWith(() => process), + }, + ); + } + + setUp(() { + process = _MockShorebirdProcess(); + iosDeploy = IOSDeploy(); + }); + + test('executes correct command', () async { + const processResult = ShorebirdProcessResult( + exitCode: 0, + stdout: '', + stderr: '', + ); + when( + () => process.run(any(), any()), + ).thenAnswer((_) async => processResult); + const deviceId = 'test-device-id'; + const bundlePath = 'test-bundle-path'; + final result = await runWithOverrides( + () => iosDeploy.installApp( + deviceId: deviceId, + bundlePath: bundlePath, + ), + ); + expect(result, equals(processResult.exitCode)); + verify( + () => process.run(any(that: endsWith('ios-deploy')), [ + '--id', + deviceId, + '--bundle', + bundlePath, + ]), + ).called(1); + }); + }); +}