Refactor how Artifacts are located (#8234)
Artifacts are now located in a central place.
This will enable us to downlaod artifacts when we need them (instead of
downloading them all upfront).
This also makes replacing sky_snapshot with gen_snapshot easier.
diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
new file mode 100644
index 0000000..0aa9ddc
--- /dev/null
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -0,0 +1,264 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'base/context.dart';
+import 'base/file_system.dart';
+import 'base/platform.dart';
+import 'build_info.dart';
+import 'globals.dart';
+
+enum Artifact {
+ chromiumDebugKeyStore,
+ classesDexJar,
+ icudtlDat,
+ libskyShellSo,
+ dartIoEntriesTxt,
+ dartVmEntryPointsTxt,
+ dartVmEntryPointsAndroidTxt,
+ genSnapshot,
+ skyShell,
+ skySnapshot,
+ snapshotDart,
+ flutterFramework,
+}
+
+String _artifactToFileName(Artifact artifact) {
+ switch (artifact) {
+ case Artifact.chromiumDebugKeyStore:
+ return 'chromium-debug.keystore';
+ case Artifact.classesDexJar:
+ return 'classes.dex.jar';
+ case Artifact.icudtlDat:
+ return 'icudtl.dat';
+ case Artifact.libskyShellSo:
+ return 'libsky_shell.so';
+ case Artifact.dartIoEntriesTxt:
+ return 'dart_io_entries.txt';
+ case Artifact.dartVmEntryPointsTxt:
+ return 'dart_vm_entry_points.txt';
+ case Artifact.dartVmEntryPointsAndroidTxt:
+ return 'dart_vm_entry_points_android.txt';
+ case Artifact.genSnapshot:
+ return 'gen_snapshot';
+ case Artifact.skySnapshot:
+ return 'sky_snapshot';
+ case Artifact.skyShell:
+ return 'sky_shell';
+ case Artifact.snapshotDart:
+ return 'snapshot.dart';
+ case Artifact.flutterFramework:
+ return 'Flutter.framework';
+ }
+ assert(false, 'Invalid artifact $artifact.');
+ return null;
+}
+
+// Manages the engine artifacts of Flutter.
+abstract class Artifacts {
+ static Artifacts get instance => context[Artifacts];
+
+ static void useLocalEngine(String engineSrcPath, String engineOutPath) {
+ context.setVariable(Artifacts, new LocalEngineArtifacts(engineSrcPath, engineOutPath));
+ }
+
+ // Returns the requested [artifact] for the [platform] and [mode] combination.
+ String getArtifactPath(Artifact artifact, [TargetPlatform platform, BuildMode mode]);
+
+ // Returns which set of engine artifacts is currently used for the [platform]
+ // and [mode] combination.
+ String getEngineType(TargetPlatform platform, [BuildMode mode]);
+}
+
+/// Manages the engine artifacts downloaded to the local cache.
+class CachedArtifacts extends Artifacts {
+
+ @override
+ String getArtifactPath(Artifact artifact, [TargetPlatform platform, BuildMode mode]) {
+ platform ??= _currentHostPlatform;
+ switch (platform) {
+ case TargetPlatform.android_arm:
+ case TargetPlatform.android_x64:
+ case TargetPlatform.android_x86:
+ return _getAndroidArtifactPath(artifact, platform, mode);
+ case TargetPlatform.ios:
+ return _getIosArtifactPath(artifact, platform, mode);
+ case TargetPlatform.darwin_x64:
+ case TargetPlatform.linux_x64:
+ assert(mode == null, 'Platform $platform does not support different build modes.');
+ return _getHostArtifactPath(artifact, platform);
+ }
+ assert(false, 'Invalid platform $platform.');
+ return null;
+ }
+
+ @override
+ String getEngineType(TargetPlatform platform, [BuildMode mode]){
+ return fs.path.basename(_getEngineArtifactsPath(platform, mode));
+ }
+
+ String _getAndroidArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
+ String engineDir = _getEngineArtifactsPath(platform, mode);
+ switch (artifact) {
+ case Artifact.chromiumDebugKeyStore:
+ case Artifact.classesDexJar:
+ case Artifact.icudtlDat:
+ case Artifact.libskyShellSo:
+ return fs.path.join(engineDir, _artifactToFileName(artifact));
+ case Artifact.dartIoEntriesTxt:
+ case Artifact.dartVmEntryPointsTxt:
+ case Artifact.dartVmEntryPointsAndroidTxt:
+ assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
+ return fs.path.join(engineDir, _artifactToFileName(artifact));
+ case Artifact.genSnapshot:
+ assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
+ String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
+ return fs.path.join(engineDir, hostPlatform, _artifactToFileName(artifact));
+ default:
+ assert(false, 'Artifact $artifact not available for platform $platform.');
+ return null;
+ }
+ }
+
+ String _getIosArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
+ String engineDir = _getEngineArtifactsPath(platform, mode);
+ switch (artifact) {
+ case Artifact.dartIoEntriesTxt:
+ case Artifact.dartVmEntryPointsTxt:
+ case Artifact.genSnapshot:
+ case Artifact.snapshotDart:
+ case Artifact.flutterFramework:
+ return fs.path.join(engineDir, _artifactToFileName(artifact));
+ default:
+ assert(false, 'Artifact $artifact not available for platform $platform.');
+ return null;
+ }
+ }
+
+ String _getHostArtifactPath(Artifact artifact, TargetPlatform platform) {
+ switch (artifact) {
+ case Artifact.skyShell:
+ case Artifact.skySnapshot:
+ case Artifact.icudtlDat:
+ String engineArtifactsPath = cache.getArtifactDirectory('engine').path;
+ String platformDirName = getNameForTargetPlatform(platform);
+ return fs.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact));
+ default:
+ assert(false, 'Artifact $artifact not available for platform $platform.');
+ return null;
+ }
+ }
+
+ String _getEngineArtifactsPath(TargetPlatform platform, [BuildMode mode]) {
+ String engineDir = cache.getArtifactDirectory('engine').path;
+ String platformName = getNameForTargetPlatform(platform);
+ switch (platform) {
+ case TargetPlatform.linux_x64:
+ case TargetPlatform.darwin_x64:
+ assert(mode == null, 'Platform $platform does not support different build modes.');
+ return fs.path.join(engineDir, platformName);
+ case TargetPlatform.ios:
+ case TargetPlatform.android_arm:
+ case TargetPlatform.android_x64:
+ case TargetPlatform.android_x86:
+ assert(mode != null, 'Need to specify a build mode for platform $platform.');
+ String suffix = mode != BuildMode.debug ? '-${getModeName(mode)}' : '';
+ return fs.path.join(engineDir, platformName + suffix);
+ }
+ assert(false, 'Invalid platform $platform.');
+ return null;
+ }
+
+ TargetPlatform get _currentHostPlatform {
+ if (platform.isMacOS)
+ return TargetPlatform.darwin_x64;
+ if (platform.isLinux)
+ return TargetPlatform.linux_x64;
+ throw new UnimplementedError('Host OS not supported.');
+ }
+}
+
+/// Manages the artifacts of a locally built engine.
+class LocalEngineArtifacts extends Artifacts {
+ final String _engineSrcPath;
+ final String engineOutPath; // TODO(goderbauer): This should be private.
+
+ LocalEngineArtifacts(this._engineSrcPath, this.engineOutPath);
+
+ @override
+ String getArtifactPath(Artifact artifact, [TargetPlatform platform, BuildMode mode]) {
+ switch (artifact) {
+ case Artifact.chromiumDebugKeyStore:
+ return fs.path.join(_engineSrcPath, 'build', 'android', 'ant', _artifactToFileName(artifact));
+ case Artifact.dartIoEntriesTxt:
+ return fs.path.join(_engineSrcPath, 'dart', 'runtime', 'bin', _artifactToFileName(artifact));
+ case Artifact.dartVmEntryPointsTxt:
+ return fs.path.join(_engineSrcPath, 'flutter', 'runtime', _artifactToFileName(artifact));
+ case Artifact.dartVmEntryPointsAndroidTxt:
+ return fs.path.join(_engineSrcPath, 'flutter', 'runtime', _artifactToFileName(artifact));
+ case Artifact.snapshotDart:
+ return fs.path.join(_engineSrcPath, 'flutter', 'lib', 'snapshot', _artifactToFileName(artifact));
+ case Artifact.classesDexJar:
+ return fs.path.join(engineOutPath, 'gen', 'flutter', 'shell', 'platform', 'android', 'android', _artifactToFileName(artifact));
+ case Artifact.icudtlDat:
+ return fs.path.join(engineOutPath, _artifactToFileName(artifact));
+ case Artifact.libskyShellSo:
+ String abi = _getAbiDirectory(platform);
+ return fs.path.join(engineOutPath, 'gen', 'flutter', 'shell', 'platform', 'android', 'android', fs.path.join('android', 'libs', abi, _artifactToFileName(artifact)));
+ case Artifact.genSnapshot:
+ return _genSnapshotPath(platform);
+ case Artifact.skyShell:
+ return _skyShellPath(platform);
+ case Artifact.skySnapshot:
+ return _skySnapshotPath();
+ case Artifact.flutterFramework:
+ return fs.path.join(engineOutPath, _artifactToFileName(artifact));
+ }
+ assert(false, 'Invalid artifact $artifact.');
+ return null;
+ }
+
+ @override
+ String getEngineType(TargetPlatform platform, [BuildMode mode]) {
+ return fs.path.basename(engineOutPath);
+ }
+
+ String _genSnapshotPath(TargetPlatform platform) {
+ String clang;
+ if (platform == TargetPlatform.ios) {
+ clang = 'clang_x64';
+ } else {
+ clang = getCurrentHostPlatform() == HostPlatform.darwin_x64 ? 'clang_i386' : 'clang_x86';
+ }
+ return fs.path.join(engineOutPath, clang, _artifactToFileName(Artifact.genSnapshot));
+ }
+
+ String _skySnapshotPath() {
+ String clangPath = fs.path.join(engineOutPath, 'clang_x64', _artifactToFileName(Artifact.skySnapshot));
+ if (fs.isFileSync(clangPath))
+ return clangPath;
+ return fs.path.join(engineOutPath, _artifactToFileName(Artifact.skySnapshot));
+ }
+
+ String _skyShellPath(TargetPlatform platform) {
+ if (getCurrentHostPlatform() == HostPlatform.linux_x64) {
+ return fs.path.join(engineOutPath, _artifactToFileName(Artifact.skyShell));
+ } else if (getCurrentHostPlatform() == HostPlatform.darwin_x64) {
+ return fs.path.join(engineOutPath, 'SkyShell.app', 'Contents', 'MacOS', 'SkyShell');
+ }
+ throw new Exception('Unsupported platform $platform.');
+ }
+
+ String _getAbiDirectory(TargetPlatform platform) {
+ switch (platform) {
+ case TargetPlatform.android_arm:
+ return 'armeabi-v7a';
+ case TargetPlatform.android_x64:
+ return 'x86_64';
+ case TargetPlatform.android_x86:
+ return 'x86';
+ default:
+ throw new Exception('Unsupported platform $platform.');
+ }
+ }
+}