From b7cd3a67a4b53f0f1c46d83bc3b01a3c3abdc381 Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Wed, 6 Dec 2023 12:04:13 -0600 Subject: [PATCH] feat(shorebird_cli): support using linker from local engine (#1550) --- packages/shorebird_cli/bin/shorebird.dart | 4 +- packages/shorebird_cli/lib/src/cache.dart | 8 + .../shorebird_cli/lib/src/command_runner.dart | 11 +- .../src/commands/patch/patch_ios_command.dart | 6 +- .../lib/src/executables/aot_tools.dart | 17 +- .../lib/src/flutter_artifacts.dart | 123 -------------- .../lib/src/shorebird_artifacts.dart | 156 +++++++++++++++++ .../lib/src/shorebird_build_mixin.dart | 6 +- .../shorebird_cli/lib/src/shorebird_env.dart | 5 + .../patch/patch_ios_command_test.dart | 16 +- .../patch_ios_framework_command_test.dart | 12 +- .../test/src/executables/aot_tools_test.dart | 157 +++++++++++++----- packages/shorebird_cli/test/src/mocks.dart | 6 +- ...est.dart => shorebird_artifacts_test.dart} | 66 ++++++-- .../test/src/shorebird_env_test.dart | 19 +++ 15 files changed, 402 insertions(+), 210 deletions(-) delete mode 100644 packages/shorebird_cli/lib/src/flutter_artifacts.dart create mode 100644 packages/shorebird_cli/lib/src/shorebird_artifacts.dart rename packages/shorebird_cli/test/src/{flutter_artifacts_test.dart => shorebird_artifacts_test.dart} (63%) diff --git a/packages/shorebird_cli/bin/shorebird.dart b/packages/shorebird_cli/bin/shorebird.dart index dfb9b032..c212fc56 100644 --- a/packages/shorebird_cli/bin/shorebird.dart +++ b/packages/shorebird_cli/bin/shorebird.dart @@ -10,13 +10,13 @@ import 'package:shorebird_cli/src/code_push_client_wrapper.dart'; import 'package:shorebird_cli/src/command_runner.dart'; import 'package:shorebird_cli/src/doctor.dart'; import 'package:shorebird_cli/src/executables/executables.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; import 'package:shorebird_cli/src/http_client/http_client.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/os/os.dart'; import 'package:shorebird_cli/src/patch_diff_checker.dart'; import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; import 'package:shorebird_cli/src/shorebird_validator.dart'; @@ -39,7 +39,6 @@ Future main(List args) async { devicectlRef, doctorRef, engineConfigRef, - flutterArtifactsRef, gitRef, gradlewRef, httpClientRef, @@ -51,6 +50,7 @@ Future main(List args) async { patchDiffCheckerRef, platformRef, processRef, + shorebirdArtifactsRef, shorebirdEnvRef, shorebirdFlutterRef, shorebirdValidatorRef, diff --git a/packages/shorebird_cli/lib/src/cache.dart b/packages/shorebird_cli/lib/src/cache.dart index 28243a1e..6859138c 100644 --- a/packages/shorebird_cli/lib/src/cache.dart +++ b/packages/shorebird_cli/lib/src/cache.dart @@ -10,6 +10,7 @@ import 'package:shorebird_cli/src/http_client/http_client.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; /// {@template cache_update_failure} @@ -47,6 +48,13 @@ final cacheRef = create(Cache.new); // The [Cache] instance available in the current zone. Cache get cache => read(cacheRef); +/// {@template cache} +/// A class that manages the artifacts cached by Shorebird. +/// This class handles fetching and unpacking artifacts from various sources. +/// +/// To access specific artifacts, it's generally recommended to use +/// [ShorebirdArtifacts] since uses the current Shorebird environment. +/// {@endtemplate} class Cache { Cache({this.extractArchive = _defaultArchiveExtractor}) { registerArtifact(PatchArtifact(cache: this, platform: platform)); diff --git a/packages/shorebird_cli/lib/src/command_runner.dart b/packages/shorebird_cli/lib/src/command_runner.dart index aeb79384..db1ed2a6 100644 --- a/packages/shorebird_cli/lib/src/command_runner.dart +++ b/packages/shorebird_cli/lib/src/command_runner.dart @@ -6,10 +6,10 @@ import 'package:cli_completion/cli_completion.dart'; import 'package:mason_logger/mason_logger.dart'; import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/commands/commands.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/platform.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; import 'package:shorebird_cli/src/shorebird_version.dart'; @@ -87,16 +87,15 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner { localEngine: topLevelResults['local-engine'] as String?, ); final process = ShorebirdProcess(engineConfig: engineConfig); - final flutterArtifacts = engineConfig.localEngineSrcPath != null - ? const FlutterLocalEngineArtifacts() - : const FlutterCachedArtifacts(); - + final shorebirdArtifacts = engineConfig.localEngineSrcPath != null + ? const ShorebirdLocalEngineArtifacts() + : const ShorebirdCachedArtifacts(); return await runScoped>( () => runCommand(topLevelResults), values: { engineConfigRef.overrideWith(() => engineConfig), processRef.overrideWith(() => process), - flutterArtifactsRef.overrideWith(() => flutterArtifacts), + shorebirdArtifactsRef.overrideWith(() => shorebirdArtifacts), }, ) ?? ExitCode.success.code; diff --git a/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart b/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart index ef4c2a5d..ab0dde3b 100644 --- a/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart +++ b/packages/shorebird_cli/lib/src/commands/patch/patch_ios_command.dart @@ -14,12 +14,12 @@ import 'package:shorebird_cli/src/config/config.dart'; import 'package:shorebird_cli/src/deployment_track.dart'; import 'package:shorebird_cli/src/doctor.dart'; import 'package:shorebird_cli/src/executables/executables.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; import 'package:shorebird_cli/src/formatters/file_size_formatter.dart'; import 'package:shorebird_cli/src/ios.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/patch_diff_checker.dart'; import 'package:shorebird_cli/src/shorebird_artifact_mixin.dart'; +import 'package:shorebird_cli/src/shorebird_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'; @@ -392,8 +392,8 @@ ${summary.join('\n')} } final analyzeSnapshot = File( - flutterArtifacts.getArtifactPath( - artifact: FlutterArtifact.analyzeSnapshot, + shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.analyzeSnapshot, ), ); diff --git a/packages/shorebird_cli/lib/src/executables/aot_tools.dart b/packages/shorebird_cli/lib/src/executables/aot_tools.dart index 9d48b36f..ac2dcb22 100644 --- a/packages/shorebird_cli/lib/src/executables/aot_tools.dart +++ b/packages/shorebird_cli/lib/src/executables/aot_tools.dart @@ -2,6 +2,8 @@ import 'package:path/path.dart' as p; import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/cache.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; +import 'package:shorebird_cli/src/shorebird_env.dart'; /// A reference to a [AotTools] instance. final aotToolsRef = create(AotTools.new); @@ -11,18 +13,23 @@ AotTools get aotTools => read(aotToolsRef); /// Wrapper around the shorebird `aot-tools` executable. class AotTools { - static const executableName = 'aot-tools'; - Future _exec( List command, { String? workingDirectory, }) async { await cache.updateAll(); - final executable = p.join( - cache.getArtifactDirectory(executableName).path, - executableName, + final executable = shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.aotTools, ); + if (p.extension(executable) == '.dart') { + return process.run( + shorebirdEnv.dartBinaryFile.path, + [executable, ...command], + workingDirectory: workingDirectory, + ); + } + return process.run(executable, command, workingDirectory: workingDirectory); } diff --git a/packages/shorebird_cli/lib/src/flutter_artifacts.dart b/packages/shorebird_cli/lib/src/flutter_artifacts.dart deleted file mode 100644 index db819671..00000000 --- a/packages/shorebird_cli/lib/src/flutter_artifacts.dart +++ /dev/null @@ -1,123 +0,0 @@ -// ignore_for_file: one_member_abstracts - -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:scoped/scoped.dart'; -import 'package:shorebird_cli/src/process.dart'; -import 'package:shorebird_cli/src/shorebird_env.dart'; - -/// All Flutter artifacts used explicitly by Shorebird. -enum FlutterArtifact { - /// The gen_snapshot executable. - genSnapshot, - - /// The analyze_snapshot executable. - analyzeSnapshot, -} - -/// A reference to a [FlutterArtifacts] instance. -final flutterArtifactsRef = create( - FlutterCachedArtifacts.new, -); - -/// The [FlutterArtifacts] instance available in the current zone. -FlutterArtifacts get flutterArtifacts => read(flutterArtifactsRef); - -/// {@template flutter_artifacts} -/// A class that provides access to Flutter artifacts. -/// {@endtemplate} -abstract class FlutterArtifacts { - /// Returns the path to the given [artifact]. - String getArtifactPath({required FlutterArtifact artifact}); -} - -/// {@template flutter_cached_artifacts} -/// A class that provides access to cached Flutter artifacts. -/// {@endtemplate} -class FlutterCachedArtifacts implements FlutterArtifacts { - /// {@macro flutter_cached_artifacts} - const FlutterCachedArtifacts(); - - @override - String getArtifactPath({ - required FlutterArtifact artifact, - }) { - switch (artifact) { - case FlutterArtifact.genSnapshot: - return _genSnapshotFile.path; - case FlutterArtifact.analyzeSnapshot: - return _analyzeSnapshotFile.path; - } - } - - File get _genSnapshotFile { - return File( - p.join( - shorebirdEnv.flutterDirectory.path, - 'bin', - 'cache', - 'artifacts', - 'engine', - 'ios-release', - 'gen_snapshot_arm64', - ), - ); - } - - File get _analyzeSnapshotFile { - return File( - p.join( - shorebirdEnv.flutterDirectory.path, - 'bin', - 'cache', - 'artifacts', - 'engine', - 'ios-release', - 'analyze_snapshot_arm64', - ), - ); - } -} - -/// {@template flutter_local_engine_artifacts} -/// A class that provides access to locally built Flutter artifacts. -/// {@endtemplate} -class FlutterLocalEngineArtifacts implements FlutterArtifacts { - /// {@macro flutter_local_engine_artifacts} - const FlutterLocalEngineArtifacts(); - - @override - String getArtifactPath({required FlutterArtifact artifact}) { - switch (artifact) { - case FlutterArtifact.genSnapshot: - return _genSnapshotFile.path; - case FlutterArtifact.analyzeSnapshot: - return _analyzeSnapshotFile.path; - } - } - - File get _genSnapshotFile { - return File( - p.join( - engineConfig.localEngineSrcPath!, - 'out', - 'ios_release', - 'clang_x64', - 'gen_snapshot_arm64', - ), - ); - } - - File get _analyzeSnapshotFile { - return File( - p.join( - engineConfig.localEngineSrcPath!, - 'out', - 'ios_release', - 'clang_x64', - 'analyze_snapshot_arm64', - ), - ); - } -} diff --git a/packages/shorebird_cli/lib/src/shorebird_artifacts.dart b/packages/shorebird_cli/lib/src/shorebird_artifacts.dart new file mode 100644 index 00000000..2d9ee3f7 --- /dev/null +++ b/packages/shorebird_cli/lib/src/shorebird_artifacts.dart @@ -0,0 +1,156 @@ +// ignore_for_file: one_member_abstracts + +import 'dart:io'; + +import 'package:path/path.dart' as p; +import 'package:scoped/scoped.dart'; +import 'package:shorebird_cli/src/cache.dart'; +import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_env.dart'; + +/// All Shorebird artifacts used explicitly by Shorebird. +enum ShorebirdArtifact { + /// The analyze_snapshot executable. + analyzeSnapshot, + + /// The aot_tools executable. + aotTools, + + /// The gen_snapshot executable. + genSnapshot, +} + +/// A reference to a [ShorebirdArtifacts] instance. +final shorebirdArtifactsRef = create( + ShorebirdCachedArtifacts.new, +); + +/// The [ShorebirdArtifacts] instance available in the current zone. +ShorebirdArtifacts get shorebirdArtifacts => read(shorebirdArtifactsRef); + +/// {@template shorebird_artifacts} +/// A class that provides access to Shorebird artifacts. +/// {@endtemplate} +abstract class ShorebirdArtifacts { + /// Returns the path to the given [artifact]. + String getArtifactPath({required ShorebirdArtifact artifact}); +} + +/// {@template shorebird_cached_artifacts} +/// A class that provides access to cached Shorebird artifacts. +/// {@endtemplate} +class ShorebirdCachedArtifacts implements ShorebirdArtifacts { + /// {@macro shorebird_cached_artifacts} + const ShorebirdCachedArtifacts(); + + @override + String getArtifactPath({ + required ShorebirdArtifact artifact, + }) { + switch (artifact) { + case ShorebirdArtifact.analyzeSnapshot: + return _analyzeSnapshotFile.path; + case ShorebirdArtifact.aotTools: + return _aotToolsFile.path; + case ShorebirdArtifact.genSnapshot: + return _genSnapshotFile.path; + } + } + + File get _analyzeSnapshotFile { + return File( + p.join( + shorebirdEnv.flutterDirectory.path, + 'bin', + 'cache', + 'artifacts', + 'engine', + 'ios-release', + 'darwin-x64', + 'analyze_snapshot', + ), + ); + } + + File get _aotToolsFile { + const executableName = 'aot-tools'; + return File( + p.join( + cache.getArtifactDirectory(executableName).path, + executableName, + ), + ); + } + + File get _genSnapshotFile { + return File( + p.join( + shorebirdEnv.flutterDirectory.path, + 'bin', + 'cache', + 'artifacts', + 'engine', + 'ios-release', + 'gen_snapshot_arm64', + ), + ); + } +} + +/// {@template shorebird_local_engine_artifacts} +/// A class that provides access to locally built Shorebird artifacts. +/// {@endtemplate} +class ShorebirdLocalEngineArtifacts implements ShorebirdArtifacts { + /// {@macro shorebird_local_engine_artifacts} + const ShorebirdLocalEngineArtifacts(); + + @override + String getArtifactPath({required ShorebirdArtifact artifact}) { + switch (artifact) { + case ShorebirdArtifact.analyzeSnapshot: + return _analyzeSnapshotFile.path; + case ShorebirdArtifact.aotTools: + return _aotToolsFile.path; + case ShorebirdArtifact.genSnapshot: + return _genSnapshotFile.path; + } + } + + File get _analyzeSnapshotFile { + return File( + p.join( + engineConfig.localEngineSrcPath!, + 'out', + 'ios_release', + 'clang_x64', + 'analyze_snapshot_arm64', + ), + ); + } + + File get _aotToolsFile { + return File( + p.join( + engineConfig.localEngineSrcPath!, + 'third_party', + 'dart', + 'pkg', + 'aot_tools', + 'bin', + 'aot_tools.dart', + ), + ); + } + + File get _genSnapshotFile { + return File( + p.join( + engineConfig.localEngineSrcPath!, + 'out', + 'ios_release', + 'clang_x64', + 'gen_snapshot_arm64', + ), + ); + } +} diff --git a/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart b/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart index 56961dc6..8e5ffbb1 100644 --- a/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart +++ b/packages/shorebird_cli/lib/src/shorebird_build_mixin.dart @@ -3,10 +3,10 @@ import 'dart:io'; import 'package:collection/collection.dart'; import 'package:mason_logger/mason_logger.dart'; import 'package:shorebird_cli/src/command.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; import 'package:shorebird_cli/src/logger.dart'; import 'package:shorebird_cli/src/os/operating_system_interface.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; enum Arch { arm64, @@ -347,7 +347,9 @@ Either run `flutter pub get` manually, or follow the steps in ${link(uri: Uri.pa ]; final result = await process.run( - flutterArtifacts.getArtifactPath(artifact: FlutterArtifact.genSnapshot), + shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.genSnapshot, + ), arguments, ); diff --git a/packages/shorebird_cli/lib/src/shorebird_env.dart b/packages/shorebird_cli/lib/src/shorebird_env.dart index a2e7feea..fec6614b 100644 --- a/packages/shorebird_cli/lib/src/shorebird_env.dart +++ b/packages/shorebird_cli/lib/src/shorebird_env.dart @@ -78,6 +78,11 @@ class ShorebirdEnv { return File(p.join(flutterDirectory.path, 'bin', 'flutter')); } + /// The Shorebird-vended Dart binary. + File get dartBinaryFile { + return File(p.join(flutterDirectory.path, 'bin', 'dart')); + } + /// The `shorebird.yaml` file for this project. File getShorebirdYamlFile({required Directory cwd}) { return File(p.join(cwd.path, 'shorebird.yaml')); diff --git a/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart b/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart index 0d98fe9d..92dc5f51 100644 --- a/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/patch/patch_ios_command_test.dart @@ -17,12 +17,12 @@ import 'package:shorebird_cli/src/config/config.dart'; import 'package:shorebird_cli/src/deployment_track.dart'; import 'package:shorebird_cli/src/doctor.dart'; import 'package:shorebird_cli/src/executables/aot_tools.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; import 'package:shorebird_cli/src/logger.dart'; 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/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; import 'package:shorebird_cli/src/shorebird_validator.dart'; @@ -137,7 +137,7 @@ flutter: late File genSnapshotFile; late File analyzeSnapshotFile; late File releaseArtifactFile; - late FlutterArtifacts flutterArtifacts; + late ShorebirdArtifacts shorebirdArtifacts; late Doctor doctor; late IosArchiveDiffer archiveDiffer; late Progress progress; @@ -165,7 +165,7 @@ flutter: authRef.overrideWith(() => auth), codePushClientWrapperRef.overrideWith(() => codePushClientWrapper), doctorRef.overrideWith(() => doctor), - flutterArtifactsRef.overrideWith(() => flutterArtifacts), + shorebirdArtifactsRef.overrideWith(() => shorebirdArtifacts), loggerRef.overrideWith(() => logger), osInterfaceRef.overrideWith(() => operatingSystemInterface), patchDiffCheckerRef.overrideWith(() => patchDiffChecker), @@ -255,7 +255,7 @@ flutter: auth = MockAuth(); codePushClientWrapper = MockCodePushClientWrapper(); doctor = MockDoctor(); - flutterArtifacts = MockFlutterArtifacts(); + shorebirdArtifacts = MockShorebirdArtifacts(); shorebirdRoot = Directory.systemTemp.createTempSync(); projectRoot = Directory.systemTemp.createTempSync(); flutterDirectory = Directory( @@ -371,13 +371,13 @@ flutter: ).thenReturn(projectRoot); when(() => shorebirdEnv.flutterDirectory).thenReturn(flutterDirectory); when( - () => flutterArtifacts.getArtifactPath( - artifact: FlutterArtifact.genSnapshot, + () => shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.genSnapshot, ), ).thenReturn(genSnapshotFile.path); when( - () => flutterArtifacts.getArtifactPath( - artifact: FlutterArtifact.analyzeSnapshot, + () => shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.analyzeSnapshot, ), ).thenReturn(analyzeSnapshotFile.path); when(() => shorebirdEnv.flutterRevision).thenReturn(flutterRevision); diff --git a/packages/shorebird_cli/test/src/commands/patch/patch_ios_framework_command_test.dart b/packages/shorebird_cli/test/src/commands/patch/patch_ios_framework_command_test.dart index 79763d1c..e3fe245c 100644 --- a/packages/shorebird_cli/test/src/commands/patch/patch_ios_framework_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/patch/patch_ios_framework_command_test.dart @@ -14,12 +14,12 @@ import 'package:shorebird_cli/src/commands/patch/patch.dart'; import 'package:shorebird_cli/src/config/config.dart'; import 'package:shorebird_cli/src/deployment_track.dart'; import 'package:shorebird_cli/src/doctor.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; import 'package:shorebird_cli/src/logger.dart'; 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/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; import 'package:shorebird_cli/src/shorebird_validator.dart'; @@ -84,7 +84,7 @@ flutter: late Directory projectRoot; late Directory flutterDirectory; late File genSnapshotFile; - late FlutterArtifacts flutterArtifacts; + late ShorebirdArtifacts shorebirdArtifacts; late Doctor doctor; late IosArchiveDiffer archiveDiffer; late PatchDiffChecker patchDiffChecker; @@ -111,7 +111,7 @@ flutter: authRef.overrideWith(() => auth), codePushClientWrapperRef.overrideWith(() => codePushClientWrapper), doctorRef.overrideWith(() => doctor), - flutterArtifactsRef.overrideWith(() => flutterArtifacts), + shorebirdArtifactsRef.overrideWith(() => shorebirdArtifacts), loggerRef.overrideWith(() => logger), osInterfaceRef.overrideWith(() => operatingSystemInterface), patchDiffCheckerRef.overrideWith(() => patchDiffChecker), @@ -179,7 +179,7 @@ flutter: artifactManager = MockArtifactManager(); codePushClientWrapper = MockCodePushClientWrapper(); doctor = MockDoctor(); - flutterArtifacts = MockFlutterArtifacts(); + shorebirdArtifacts = MockShorebirdArtifacts(); patchDiffChecker = MockPatchDiffChecker(); platform = MockPlatform(); shorebirdRoot = Directory.systemTemp.createTempSync(); @@ -255,8 +255,8 @@ flutter: ).thenReturn(projectRoot); when(() => shorebirdEnv.flutterDirectory).thenReturn(flutterDirectory); when( - () => flutterArtifacts.getArtifactPath( - artifact: FlutterArtifact.genSnapshot, + () => shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.genSnapshot, ), ).thenReturn(genSnapshotFile.path); when(() => shorebirdEnv.flutterRevision).thenReturn(flutterRevision); diff --git a/packages/shorebird_cli/test/src/executables/aot_tools_test.dart b/packages/shorebird_cli/test/src/executables/aot_tools_test.dart index 2f77e39e..47ac2b99 100644 --- a/packages/shorebird_cli/test/src/executables/aot_tools_test.dart +++ b/packages/shorebird_cli/test/src/executables/aot_tools_test.dart @@ -5,6 +5,8 @@ import 'package:scoped/scoped.dart'; import 'package:shorebird_cli/src/cache.dart'; import 'package:shorebird_cli/src/executables/executables.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; +import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:test/test.dart'; import '../mocks.dart'; @@ -12,8 +14,11 @@ import '../mocks.dart'; void main() { group(AotTools, () { late Cache cache; + late ShorebirdArtifacts shorebirdArtifacts; late ShorebirdProcess process; + late ShorebirdEnv shorebirdEnv; late Directory workingDirectory; + late File dartBinaryFile; late AotTools aotTools; R runWithOverrides(R Function() body) { @@ -22,6 +27,8 @@ void main() { values: { cacheRef.overrideWith(() => cache), processRef.overrideWith(() => process), + shorebirdArtifactsRef.overrideWith(() => shorebirdArtifacts), + shorebirdEnvRef.overrideWith(() => shorebirdEnv), }, ); } @@ -29,13 +36,14 @@ void main() { setUp(() { cache = MockCache(); process = MockShorebirdProcess(); - workingDirectory = Directory.systemTemp.createTempSync('aot-tool test'); + shorebirdArtifacts = MockShorebirdArtifacts(); + shorebirdEnv = MockShorebirdEnv(); + dartBinaryFile = File('dart'); + workingDirectory = Directory('aot-tools test'); aotTools = AotTools(); when(() => cache.updateAll()).thenAnswer((_) async {}); - when( - () => cache.getArtifactDirectory(any()), - ).thenReturn(workingDirectory); + when(() => shorebirdEnv.dartBinaryFile).thenReturn(dartBinaryFile); }); group('link', () { @@ -44,6 +52,11 @@ void main() { const analyzeSnapshot = './path/to/analyze_snapshot.aot'; test('throws Exception when process exits with non-zero code', () async { + when( + () => shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.aotTools, + ), + ).thenReturn('aot-tools'); when( () => process.run( any(), @@ -75,43 +88,107 @@ void main() { ); }); - test('completes when linking exits with code: 0', () async { - when( - () => process.run( - any(), - any(), - workingDirectory: any(named: 'workingDirectory'), - ), - ).thenAnswer( - (_) async => const ShorebirdProcessResult( - exitCode: 0, - stdout: '', - stderr: '', - ), - ); - await expectLater( - runWithOverrides( - () => aotTools.link( - base: base, - patch: patch, - analyzeSnapshot: analyzeSnapshot, - workingDirectory: workingDirectory.path, + group('when using cached aot tools', () { + const aotToolsPath = 'aot-tools'; + + setUp(() { + when( + () => shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.aotTools, ), - ), - completes, - ); - verify( - () => process.run( - any(that: endsWith(AotTools.executableName)), - [ - 'link', - '--base=$base', - '--patch=$patch', - '--analyze-snapshot=$analyzeSnapshot', - ], - workingDirectory: any(named: 'workingDirectory'), - ), - ).called(1); + ).thenReturn(aotToolsPath); + }); + + test('completes when linking exits with code 0', () async { + when( + () => process.run( + any(), + any(), + workingDirectory: any(named: 'workingDirectory'), + ), + ).thenAnswer( + (_) async => const ShorebirdProcessResult( + exitCode: 0, + stdout: '', + stderr: '', + ), + ); + await expectLater( + runWithOverrides( + () => aotTools.link( + base: base, + patch: patch, + analyzeSnapshot: analyzeSnapshot, + workingDirectory: workingDirectory.path, + ), + ), + completes, + ); + verify( + () => process.run( + any(that: endsWith('aot-tools')), + [ + 'link', + '--base=$base', + '--patch=$patch', + '--analyze-snapshot=$analyzeSnapshot', + ], + workingDirectory: any(named: 'workingDirectory'), + ), + ).called(1); + }); + }); + + group('when using local aot_tools', () { + const aotToolsPath = 'aot_tools.dart'; + + setUp(() { + when( + () => shorebirdArtifacts.getArtifactPath( + artifact: ShorebirdArtifact.aotTools, + ), + ).thenReturn(aotToolsPath); + }); + + test('completes when linking exits with code 0', () async { + when( + () => process.run( + any(), + any(), + workingDirectory: any(named: 'workingDirectory'), + ), + ).thenAnswer( + (_) async => const ShorebirdProcessResult( + exitCode: 0, + stdout: '', + stderr: '', + ), + ); + await expectLater( + runWithOverrides( + () => aotTools.link( + base: base, + patch: patch, + analyzeSnapshot: analyzeSnapshot, + workingDirectory: workingDirectory.path, + ), + ), + completes, + ); + verify( + () => process.run( + dartBinaryFile.path, + [ + aotToolsPath, + 'link', + '--base=$base', + '--patch=$patch', + '--analyze-snapshot=$analyzeSnapshot', + ], + workingDirectory: any(named: 'workingDirectory'), + ), + ).called(1); + }); }); }); }); diff --git a/packages/shorebird_cli/test/src/mocks.dart b/packages/shorebird_cli/test/src/mocks.dart index fba9148e..badb8f16 100644 --- a/packages/shorebird_cli/test/src/mocks.dart +++ b/packages/shorebird_cli/test/src/mocks.dart @@ -18,10 +18,10 @@ import 'package:shorebird_cli/src/config/config.dart'; import 'package:shorebird_cli/src/doctor.dart'; import 'package:shorebird_cli/src/executables/devicectl/apple_device.dart'; import 'package:shorebird_cli/src/executables/executables.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; import 'package:shorebird_cli/src/os/os.dart'; import 'package:shorebird_cli/src/patch_diff_checker.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:shorebird_cli/src/shorebird_flutter.dart'; import 'package:shorebird_cli/src/shorebird_validator.dart'; @@ -73,8 +73,6 @@ class MockFile extends Mock implements File {} class MockFileSetDiff extends Mock implements FileSetDiff {} -class MockFlutterArtifacts extends Mock implements FlutterArtifacts {} - class MockGit extends Mock implements Git {} class MockGradlew extends Mock implements Gradlew {} @@ -114,6 +112,8 @@ class MockRelease extends Mock implements Release {} class MockReleaseArtifact extends Mock implements ReleaseArtifact {} +class MockShorebirdArtifacts extends Mock implements ShorebirdArtifacts {} + class MockShorebirdEnv extends Mock implements ShorebirdEnv {} class MockShorebirdFlutter extends Mock implements ShorebirdFlutter {} diff --git a/packages/shorebird_cli/test/src/flutter_artifacts_test.dart b/packages/shorebird_cli/test/src/shorebird_artifacts_test.dart similarity index 63% rename from packages/shorebird_cli/test/src/flutter_artifacts_test.dart rename to packages/shorebird_cli/test/src/shorebird_artifacts_test.dart index 794aff72..8c8deead 100644 --- a/packages/shorebird_cli/test/src/flutter_artifacts_test.dart +++ b/packages/shorebird_cli/test/src/shorebird_artifacts_test.dart @@ -3,42 +3,62 @@ import 'dart:io'; import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; import 'package:scoped/scoped.dart'; -import 'package:shorebird_cli/src/flutter_artifacts.dart'; +import 'package:shorebird_cli/src/cache.dart'; import 'package:shorebird_cli/src/process.dart'; +import 'package:shorebird_cli/src/shorebird_artifacts.dart'; import 'package:shorebird_cli/src/shorebird_env.dart'; import 'package:test/test.dart'; import 'mocks.dart'; void main() { - group(FlutterCachedArtifacts, () { + group(ShorebirdCachedArtifacts, () { + late Cache cache; late Directory flutterDirectory; + late Directory artifactDirectory; late ShorebirdEnv shorebirdEnv; - late FlutterCachedArtifacts artifacts; + late ShorebirdCachedArtifacts artifacts; R runWithOverrides(R Function() body) { return runScoped( () => body(), values: { + cacheRef.overrideWith(() => cache), shorebirdEnvRef.overrideWith(() => shorebirdEnv), }, ); } setUp(() { + cache = MockCache(); flutterDirectory = Directory('flutter'); + artifactDirectory = Directory('artifacts'); shorebirdEnv = MockShorebirdEnv(); - artifacts = const FlutterCachedArtifacts(); + artifacts = const ShorebirdCachedArtifacts(); + when( + () => cache.getArtifactDirectory(any()), + ).thenReturn(artifactDirectory); when(() => shorebirdEnv.flutterDirectory).thenReturn(flutterDirectory); }); group('getArtifactPath', () { + test('returns correct path for aot tools', () { + expect( + runWithOverrides( + () => artifacts.getArtifactPath( + artifact: ShorebirdArtifact.aotTools, + ), + ), + equals(p.join(artifactDirectory.path, 'aot-tools')), + ); + }); + test('returns correct path for gen_snapshot', () { expect( runWithOverrides( () => artifacts.getArtifactPath( - artifact: FlutterArtifact.genSnapshot, + artifact: ShorebirdArtifact.genSnapshot, ), ), equals( @@ -59,7 +79,7 @@ void main() { expect( runWithOverrides( () => artifacts.getArtifactPath( - artifact: FlutterArtifact.analyzeSnapshot, + artifact: ShorebirdArtifact.analyzeSnapshot, ), ), equals( @@ -70,7 +90,8 @@ void main() { 'artifacts', 'engine', 'ios-release', - 'analyze_snapshot_arm64', + 'darwin-x64', + 'analyze_snapshot', ), ), ); @@ -78,10 +99,10 @@ void main() { }); }); - group(FlutterLocalEngineArtifacts, () { + group(ShorebirdLocalEngineArtifacts, () { late String localEngineSrcPath; late EngineConfig engineConfig; - late FlutterLocalEngineArtifacts artifacts; + late ShorebirdLocalEngineArtifacts artifacts; R runWithOverrides(R Function() body) { return runScoped( @@ -95,7 +116,7 @@ void main() { setUp(() { localEngineSrcPath = 'local_engine_src_path'; engineConfig = MockEngineConfig(); - artifacts = const FlutterLocalEngineArtifacts(); + artifacts = const ShorebirdLocalEngineArtifacts(); when( () => engineConfig.localEngineSrcPath, @@ -103,11 +124,32 @@ void main() { }); group('getArtifactPath', () { + test('returns correct path for aot tools', () { + expect( + runWithOverrides( + () => artifacts.getArtifactPath( + artifact: ShorebirdArtifact.aotTools, + ), + ), + equals( + p.join( + localEngineSrcPath, + 'third_party', + 'dart', + 'pkg', + 'aot_tools', + 'bin', + 'aot_tools.dart', + ), + ), + ); + }); + test('returns correct path for gen_snapshot', () { expect( runWithOverrides( () => artifacts.getArtifactPath( - artifact: FlutterArtifact.genSnapshot, + artifact: ShorebirdArtifact.genSnapshot, ), ), equals( @@ -126,7 +168,7 @@ void main() { expect( runWithOverrides( () => artifacts.getArtifactPath( - artifact: FlutterArtifact.analyzeSnapshot, + artifact: ShorebirdArtifact.analyzeSnapshot, ), ), equals( diff --git a/packages/shorebird_cli/test/src/shorebird_env_test.dart b/packages/shorebird_cli/test/src/shorebird_env_test.dart index 51130cc2..81666936 100644 --- a/packages/shorebird_cli/test/src/shorebird_env_test.dart +++ b/packages/shorebird_cli/test/src/shorebird_env_test.dart @@ -142,6 +142,25 @@ void main() { }); }); + group('dartBinaryFile', () { + test('returns correct path', () { + expect( + runWithOverrides(() => shorebirdEnv.dartBinaryFile.path), + equals( + p.join( + shorebirdRoot.path, + 'bin', + 'cache', + 'flutter', + flutterRevision, + 'bin', + 'dart', + ), + ), + ); + }); + }); + group('flutterBinaryFile', () { test('returns correct path', () { expect(