[flutter_tools] Remove context from Artifacts class (#48776)

diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index e9d7c46..5e3c2e9 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -3,10 +3,13 @@
 // found in the LICENSE file.
 
 import 'package:meta/meta.dart';
+import 'package:platform/platform.dart';
+import 'package:process/process.dart';
 
 import 'base/file_system.dart';
 import 'base/utils.dart';
 import 'build_info.dart';
+import 'cache.dart';
 import 'dart/sdk.dart';
 import 'globals.dart' as globals;
 
@@ -156,7 +159,15 @@
 // Manages the engine artifacts of Flutter.
 abstract class Artifacts {
   static LocalEngineArtifacts getLocalEngine(String engineSrcPath, EngineBuildPaths engineBuildPaths) {
-    return LocalEngineArtifacts(engineSrcPath, engineBuildPaths.targetEngine, engineBuildPaths.hostEngine);
+    return LocalEngineArtifacts(
+      engineSrcPath,
+      engineBuildPaths.targetEngine,
+      engineBuildPaths.hostEngine,
+      cache: globals.cache,
+      fileSystem: globals.fs,
+      processManager: globals.processManager,
+      platform: globals.platform,
+    );
   }
 
   // Returns the requested [artifact] for the [platform] and [mode] combination.
@@ -167,21 +178,20 @@
   String getEngineType(TargetPlatform platform, [ BuildMode mode ]);
 }
 
-TargetPlatform get _currentHostPlatform {
-  if (globals.platform.isMacOS) {
-    return TargetPlatform.darwin_x64;
-  }
-  if (globals.platform.isLinux) {
-    return TargetPlatform.linux_x64;
-  }
-  if (globals.platform.isWindows) {
-    return TargetPlatform.windows_x64;
-  }
-  throw UnimplementedError('Host OS not supported.');
-}
 
 /// Manages the engine artifacts downloaded to the local cache.
 class CachedArtifacts extends Artifacts {
+  CachedArtifacts({
+    @required FileSystem fileSystem,
+    @required Platform platform,
+    @required Cache cache,
+  }) : _fileSystem = fileSystem,
+       _platform = platform,
+       _cache = cache;
+
+  final FileSystem _fileSystem;
+  final Platform _platform;
+  final Cache _cache;
 
   @override
   String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode }) {
@@ -203,13 +213,13 @@
       case TargetPlatform.tester:
       case TargetPlatform.web_javascript:
       default: // could be null, but that can't be specified as a case.
-        return _getHostArtifactPath(artifact, platform ?? _currentHostPlatform, mode);
+        return _getHostArtifactPath(artifact, platform ?? _currentHostPlatform(_platform), mode);
     }
   }
 
   @override
   String getEngineType(TargetPlatform platform, [ BuildMode mode ]) {
-    return globals.fs.path.basename(_getEngineArtifactsPath(platform, mode));
+    return _fileSystem.path.basename(_getEngineArtifactsPath(platform, mode));
   }
 
   String _getDarwinArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
@@ -217,9 +227,9 @@
     // and not the gen_snapshot for darwin as a target platform.
     if (platform != null && artifact == Artifact.genSnapshot) {
       final String engineDir = _getEngineArtifactsPath(platform, mode);
-      return globals.fs.path.join(engineDir, _artifactToFileName(artifact));
+      return _fileSystem.path.join(engineDir, _artifactToFileName(artifact));
     }
-    return _getHostArtifactPath(artifact, platform ?? _currentHostPlatform, mode);
+    return _getHostArtifactPath(artifact, platform ?? _currentHostPlatform(_platform), mode);
   }
 
   String _getAndroidArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
@@ -227,11 +237,11 @@
     switch (artifact) {
       case Artifact.frontendServerSnapshotForEngineDartSdk:
         assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
-        return globals.fs.path.join(engineDir, _artifactToFileName(artifact));
+        return _fileSystem.path.join(engineDir, _artifactToFileName(artifact));
       case Artifact.genSnapshot:
         assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
         final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
-        return globals.fs.path.join(engineDir, hostPlatform, _artifactToFileName(artifact));
+        return _fileSystem.path.join(engineDir, hostPlatform, _artifactToFileName(artifact));
       default:
         return _getHostArtifactPath(artifact, platform, mode);
     }
@@ -245,31 +255,31 @@
       case Artifact.frontendServerSnapshotForEngineDartSdk:
         final String artifactFileName = _artifactToFileName(artifact);
         final String engineDir = _getEngineArtifactsPath(platform, mode);
-        return globals.fs.path.join(engineDir, artifactFileName);
+        return _fileSystem.path.join(engineDir, artifactFileName);
       case Artifact.ideviceId:
       case Artifact.ideviceinfo:
       case Artifact.idevicescreenshot:
       case Artifact.idevicesyslog:
       case Artifact.idevicename:
         final String artifactFileName = _artifactToFileName(artifact);
-        return globals.cache.getArtifactDirectory('libimobiledevice').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('libimobiledevice').childFile(artifactFileName).path;
       case Artifact.iosDeploy:
         final String artifactFileName = _artifactToFileName(artifact);
-        return globals.cache.getArtifactDirectory('ios-deploy').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('ios-deploy').childFile(artifactFileName).path;
       case Artifact.ideviceinstaller:
         final String artifactFileName = _artifactToFileName(artifact);
-        return globals.cache.getArtifactDirectory('ideviceinstaller').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('ideviceinstaller').childFile(artifactFileName).path;
       case Artifact.iproxy:
         final String artifactFileName = _artifactToFileName(artifact);
-        return globals.cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
       default:
         return _getHostArtifactPath(artifact, platform, mode);
     }
   }
 
   String _getFuchsiaArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
-    final String root = globals.fs.path.join(
-      globals.cache.getArtifactDirectory('flutter_runner').path,
+    final String root = _fileSystem.path.join(
+      _cache.getArtifactDirectory('flutter_runner').path,
       'flutter',
       fuchsiaArchForTargetPlatform(platform),
       mode.isRelease ? 'release' : mode.toString(),
@@ -278,32 +288,32 @@
     switch (artifact) {
       case Artifact.genSnapshot:
         final String genSnapshot = mode.isRelease ? 'gen_snapshot_product' : 'gen_snapshot';
-        return globals.fs.path.join(root, runtime, 'dart_binaries', genSnapshot);
+        return _fileSystem.path.join(root, runtime, 'dart_binaries', genSnapshot);
       case Artifact.flutterPatchedSdkPath:
         const String artifactFileName = 'flutter_runner_patched_sdk';
-        return globals.fs.path.join(root, runtime, artifactFileName);
+        return _fileSystem.path.join(root, runtime, artifactFileName);
       case Artifact.platformKernelDill:
         final String artifactFileName = _artifactToFileName(artifact, platform, mode);
-        return globals.fs.path.join(root, runtime, 'flutter_runner_patched_sdk', artifactFileName);
+        return _fileSystem.path.join(root, runtime, 'flutter_runner_patched_sdk', artifactFileName);
       case Artifact.fuchsiaKernelCompiler:
         final String artifactFileName = _artifactToFileName(artifact, platform, mode);
-        return globals.fs.path.join(root, runtime, 'dart_binaries', artifactFileName);
+        return _fileSystem.path.join(root, runtime, 'dart_binaries', artifactFileName);
       case Artifact.fuchsiaFlutterRunner:
         final String artifactFileName = _artifactToFileName(artifact, platform, mode);
-        return globals.fs.path.join(root, runtime, artifactFileName);
+        return _fileSystem.path.join(root, runtime, artifactFileName);
       default:
         return _getHostArtifactPath(artifact, platform, mode);
     }
   }
 
   String _getFlutterPatchedSdkPath(BuildMode mode) {
-    final String engineArtifactsPath = globals.cache.getArtifactDirectory('engine').path;
-    return globals.fs.path.join(engineArtifactsPath, 'common',
+    final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
+    return _fileSystem.path.join(engineArtifactsPath, 'common',
         mode == BuildMode.release ? 'flutter_patched_sdk_product' : 'flutter_patched_sdk');
   }
 
   String _getFlutterWebSdkPath() {
-    return globals.cache.getWebSdkDirectory().path;
+    return _cache.getWebSdkDirectory().path;
   }
 
   String _getHostArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
@@ -317,29 +327,29 @@
       case Artifact.vmSnapshotData:
       case Artifact.isolateSnapshotData:
       case Artifact.frontendServerSnapshotForEngineDartSdk:
-        final String engineArtifactsPath = globals.cache.getArtifactDirectory('engine').path;
+        final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
         final String platformDirName = getNameForTargetPlatform(platform);
-        return globals.fs.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
+        return _fileSystem.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
       case Artifact.engineDartSdkPath:
         return dartSdkPath;
       case Artifact.engineDartBinary:
-        return globals.fs.path.join(dartSdkPath, 'bin', _artifactToFileName(artifact, platform));
+        return _fileSystem.path.join(dartSdkPath, 'bin', _artifactToFileName(artifact, platform));
       case Artifact.platformKernelDill:
-        return globals.fs.path.join(_getFlutterPatchedSdkPath(mode), _artifactToFileName(artifact));
+        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), _artifactToFileName(artifact));
       case Artifact.platformLibrariesJson:
-        return globals.fs.path.join(_getFlutterPatchedSdkPath(mode), 'lib', _artifactToFileName(artifact));
+        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), 'lib', _artifactToFileName(artifact));
       case Artifact.flutterPatchedSdkPath:
         return _getFlutterPatchedSdkPath(mode);
       case Artifact.flutterWebSdk:
         return _getFlutterWebSdkPath();
       case Artifact.webPlatformKernelDill:
-        return globals.fs.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
+        return _fileSystem.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
       case Artifact.dart2jsSnapshot:
-        return globals.fs.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
+        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
       case Artifact.dartdevcSnapshot:
-        return globals.fs.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
+        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
       case Artifact.kernelWorkerSnapshot:
-        return globals.fs.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
+        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
       case Artifact.flutterMacOSFramework:
       case Artifact.linuxDesktopPath:
       case Artifact.windowsDesktopPath:
@@ -351,11 +361,11 @@
         if (mode == BuildMode.profile || mode == BuildMode.release) {
           platformDirName = '$platformDirName-${getNameForBuildMode(mode)}';
         }
-        final String engineArtifactsPath = globals.cache.getArtifactDirectory('engine').path;
-        return globals.fs.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
+        final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
+        return _fileSystem.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
       case Artifact.skyEnginePath:
-        final Directory dartPackageDirectory = globals.cache.getCacheDir('pkg');
-        return globals.fs.path.join(dartPackageDirectory.path,  _artifactToFileName(artifact));
+        final Directory dartPackageDirectory = _cache.getCacheDir('pkg');
+        return _fileSystem.path.join(dartPackageDirectory.path,  _artifactToFileName(artifact));
       default:
         assert(false, 'Artifact $artifact not available for platform $platform.');
         return null;
@@ -363,7 +373,7 @@
   }
 
   String _getEngineArtifactsPath(TargetPlatform platform, [ BuildMode mode ]) {
-    final String engineDir = globals.cache.getArtifactDirectory('engine').path;
+    final String engineDir = _cache.getArtifactDirectory('engine').path;
     final String platformName = getNameForTargetPlatform(platform);
     switch (platform) {
       case TargetPlatform.linux_x64:
@@ -373,16 +383,16 @@
         // under a separate directory from the host artifacts.
         // https://github.com/flutter/flutter/issues/38935
         if (mode == BuildMode.debug || mode == null) {
-          return globals.fs.path.join(engineDir, platformName);
+          return _fileSystem.path.join(engineDir, platformName);
         }
         final String suffix = mode != BuildMode.debug ? '-${snakeCase(getModeName(mode), '-')}' : '';
-        return globals.fs.path.join(engineDir, platformName + suffix);
+        return _fileSystem.path.join(engineDir, platformName + suffix);
       case TargetPlatform.fuchsia_arm64:
       case TargetPlatform.fuchsia_x64:
       case TargetPlatform.tester:
       case TargetPlatform.web_javascript:
         assert(mode == null, 'Platform $platform does not support different build modes.');
-        return globals.fs.path.join(engineDir, platformName);
+        return _fileSystem.path.join(engineDir, platformName);
       case TargetPlatform.ios:
       case TargetPlatform.android_arm:
       case TargetPlatform.android_arm64:
@@ -390,7 +400,7 @@
       case TargetPlatform.android_x86:
         assert(mode != null, 'Need to specify a build mode for platform $platform.');
         final String suffix = mode != BuildMode.debug ? '-${snakeCase(getModeName(mode), '-')}' : '';
-        return globals.fs.path.join(engineDir, platformName + suffix);
+        return _fileSystem.path.join(engineDir, platformName + suffix);
       case TargetPlatform.android:
         assert(false, 'cannot use TargetPlatform.android to look up artifacts');
         return null;
@@ -400,93 +410,134 @@
   }
 }
 
+TargetPlatform _currentHostPlatform(Platform platform) {
+  if (platform.isMacOS) {
+    return TargetPlatform.darwin_x64;
+  }
+  if (platform.isLinux) {
+    return TargetPlatform.linux_x64;
+  }
+  if (platform.isWindows) {
+    return TargetPlatform.windows_x64;
+  }
+  throw UnimplementedError('Host OS not supported.');
+}
+
+HostPlatform _currentHostPlatformAsHost(Platform platform) {
+  if (platform.isMacOS) {
+    return HostPlatform.darwin_x64;
+  }
+  if (platform.isLinux) {
+    return HostPlatform.linux_x64;
+  }
+  if (platform.isWindows) {
+    return HostPlatform.windows_x64;
+  }
+  throw UnimplementedError('Host OS not supported.');
+}
+
 /// Manages the artifacts of a locally built engine.
 class LocalEngineArtifacts extends Artifacts {
-  LocalEngineArtifacts(this._engineSrcPath, this.engineOutPath, this._hostEngineOutPath);
+  LocalEngineArtifacts(
+    this._engineSrcPath,
+    this.engineOutPath,
+    this._hostEngineOutPath, {
+    @required FileSystem fileSystem,
+    @required Cache cache,
+    @required ProcessManager processManager,
+    @required Platform platform,
+  }) : _fileSystem = fileSystem,
+       _cache = cache,
+       _processManager = processManager,
+       _platform = platform;
 
   final String _engineSrcPath;
   final String engineOutPath; // TODO(goderbauer): This should be private.
   final String _hostEngineOutPath;
+  final FileSystem _fileSystem;
+  final Cache _cache;
+  final ProcessManager _processManager;
+  final Platform _platform;
 
   @override
   String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode }) {
-    platform ??= _currentHostPlatform;
+    platform ??= _currentHostPlatform(_platform);
     final String artifactFileName = _artifactToFileName(artifact, platform, mode);
     switch (artifact) {
       case Artifact.snapshotDart:
-        return globals.fs.path.join(_engineSrcPath, 'flutter', 'lib', 'snapshot', artifactFileName);
+        return _fileSystem.path.join(_engineSrcPath, 'flutter', 'lib', 'snapshot', artifactFileName);
       case Artifact.genSnapshot:
         return _genSnapshotPath();
       case Artifact.flutterTester:
         return _flutterTesterPath(platform);
       case Artifact.isolateSnapshotData:
       case Artifact.vmSnapshotData:
-        return globals.fs.path.join(engineOutPath, 'gen', 'flutter', 'lib', 'snapshot', artifactFileName);
+        return _fileSystem.path.join(engineOutPath, 'gen', 'flutter', 'lib', 'snapshot', artifactFileName);
       case Artifact.platformKernelDill:
         if (platform == TargetPlatform.fuchsia_x64 || platform == TargetPlatform.fuchsia_arm64) {
-          return globals.fs.path.join(engineOutPath, 'flutter_runner_patched_sdk', artifactFileName);
+          return _fileSystem.path.join(engineOutPath, 'flutter_runner_patched_sdk', artifactFileName);
         }
-        return globals.fs.path.join(_getFlutterPatchedSdkPath(mode), artifactFileName);
+        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), artifactFileName);
       case Artifact.platformLibrariesJson:
-        return globals.fs.path.join(_getFlutterPatchedSdkPath(mode), 'lib', artifactFileName);
+        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), 'lib', artifactFileName);
       case Artifact.flutterFramework:
-        return globals.fs.path.join(engineOutPath, artifactFileName);
+        return _fileSystem.path.join(engineOutPath, artifactFileName);
       case Artifact.flutterMacOSFramework:
-        return globals.fs.path.join(engineOutPath, artifactFileName);
+        return _fileSystem.path.join(engineOutPath, artifactFileName);
       case Artifact.flutterPatchedSdkPath:
         // When using local engine always use [BuildMode.debug] regardless of
         // what was specified in [mode] argument because local engine will
         // have only one flutter_patched_sdk in standard location, that
         // is happen to be what debug(non-release) mode is using.
         if (platform == TargetPlatform.fuchsia_x64 || platform == TargetPlatform.fuchsia_arm64) {
-          return globals.fs.path.join(engineOutPath, 'flutter_runner_patched_sdk');
+          return _fileSystem.path.join(engineOutPath, 'flutter_runner_patched_sdk');
         }
         return _getFlutterPatchedSdkPath(BuildMode.debug);
       case Artifact.flutterWebSdk:
         return _getFlutterWebSdkPath();
       case Artifact.frontendServerSnapshotForEngineDartSdk:
-        return globals.fs.path.join(_hostEngineOutPath, 'gen', artifactFileName);
+        return _fileSystem.path.join(_hostEngineOutPath, 'gen', artifactFileName);
       case Artifact.engineDartSdkPath:
-        return globals.fs.path.join(_hostEngineOutPath, 'dart-sdk');
+        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk');
       case Artifact.engineDartBinary:
-        return globals.fs.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', artifactFileName);
+        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', artifactFileName);
       case Artifact.dart2jsSnapshot:
-        return globals.fs.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName);
+        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName);
       case Artifact.dartdevcSnapshot:
-        return globals.fs.path.join(dartSdkPath, 'bin', 'snapshots', artifactFileName);
+        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', artifactFileName);
       case Artifact.kernelWorkerSnapshot:
-        return globals.fs.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName);
+        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName);
       case Artifact.ideviceId:
       case Artifact.ideviceinfo:
       case Artifact.idevicename:
       case Artifact.idevicescreenshot:
       case Artifact.idevicesyslog:
-        return globals.cache.getArtifactDirectory('libimobiledevice').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('libimobiledevice').childFile(artifactFileName).path;
       case Artifact.ideviceinstaller:
-        return globals.cache.getArtifactDirectory('ideviceinstaller').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('ideviceinstaller').childFile(artifactFileName).path;
       case Artifact.iosDeploy:
-        return globals.cache.getArtifactDirectory('ios-deploy').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('ios-deploy').childFile(artifactFileName).path;
       case Artifact.iproxy:
-        return globals.cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
+        return _cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
       case Artifact.linuxDesktopPath:
-        return globals.fs.path.join(_hostEngineOutPath, artifactFileName);
+        return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
       case Artifact.windowsDesktopPath:
-        return globals.fs.path.join(_hostEngineOutPath, artifactFileName);
+        return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
       case Artifact.skyEnginePath:
-        return globals.fs.path.join(_hostEngineOutPath, 'gen', 'dart-pkg', artifactFileName);
+        return _fileSystem.path.join(_hostEngineOutPath, 'gen', 'dart-pkg', artifactFileName);
       case Artifact.flutterMacOSPodspec:
-        return globals.fs.path.join(_hostEngineOutPath, _artifactToFileName(artifact));
+        return _fileSystem.path.join(_hostEngineOutPath, _artifactToFileName(artifact));
       case Artifact.webPlatformKernelDill:
-        return globals.fs.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
+        return _fileSystem.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
       case Artifact.fuchsiaKernelCompiler:
         final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
         final String modeName = mode.isRelease ? 'release' : mode.toString();
         final String dartBinaries = 'dart_binaries-$modeName-$hostPlatform';
-        return globals.fs.path.join(engineOutPath, 'host_bundle', dartBinaries, 'kernel_compiler.dart.snapshot');
+        return _fileSystem.path.join(engineOutPath, 'host_bundle', dartBinaries, 'kernel_compiler.dart.snapshot');
       case Artifact.fuchsiaFlutterRunner:
         final String jitOrAot = mode.isJit ? '_jit' : '_aot';
         final String productOrNo = mode.isRelease ? '_product' : '';
-        return globals.fs.path.join(engineOutPath, 'flutter$jitOrAot${productOrNo}_runner-0.far');
+        return _fileSystem.path.join(engineOutPath, 'flutter$jitOrAot${productOrNo}_runner-0.far');
     }
     assert(false, 'Invalid artifact $artifact.');
     return null;
@@ -494,24 +545,24 @@
 
   @override
   String getEngineType(TargetPlatform platform, [ BuildMode mode ]) {
-    return globals.fs.path.basename(engineOutPath);
+    return _fileSystem.path.basename(engineOutPath);
   }
 
   String _getFlutterPatchedSdkPath(BuildMode buildMode) {
-    return globals.fs.path.join(engineOutPath,
+    return _fileSystem.path.join(engineOutPath,
         buildMode == BuildMode.release ? 'flutter_patched_sdk_product' : 'flutter_patched_sdk');
   }
 
   String _getFlutterWebSdkPath() {
-    return globals.fs.path.join(engineOutPath, 'flutter_web_sdk');
+    return _fileSystem.path.join(engineOutPath, 'flutter_web_sdk');
   }
 
   String _genSnapshotPath() {
     const List<String> clangDirs = <String>['.', 'clang_x64', 'clang_x86', 'clang_i386'];
     final String genSnapshotName = _artifactToFileName(Artifact.genSnapshot);
     for (final String clangDir in clangDirs) {
-      final String genSnapshotPath = globals.fs.path.join(engineOutPath, clangDir, genSnapshotName);
-      if (globals.processManager.canRun(genSnapshotPath)) {
+      final String genSnapshotPath = _fileSystem.path.join(engineOutPath, clangDir, genSnapshotName);
+      if (_processManager.canRun(genSnapshotPath)) {
         return genSnapshotPath;
       }
     }
@@ -519,12 +570,13 @@
   }
 
   String _flutterTesterPath(TargetPlatform platform) {
-    if (getCurrentHostPlatform() == HostPlatform.linux_x64) {
-      return globals.fs.path.join(engineOutPath, _artifactToFileName(Artifact.flutterTester));
-    } else if (getCurrentHostPlatform() == HostPlatform.darwin_x64) {
-      return globals.fs.path.join(engineOutPath, 'flutter_tester');
-    } else if (getCurrentHostPlatform() == HostPlatform.windows_x64) {
-      return globals.fs.path.join(engineOutPath, 'flutter_tester.exe');
+    final HostPlatform hostPlatform = _currentHostPlatformAsHost(_platform);
+    if (hostPlatform == HostPlatform.linux_x64) {
+      return _fileSystem.path.join(engineOutPath, _artifactToFileName(Artifact.flutterTester));
+    } else if (hostPlatform == HostPlatform.darwin_x64) {
+      return _fileSystem.path.join(engineOutPath, 'flutter_tester');
+    } else if (hostPlatform == HostPlatform.windows_x64) {
+      return _fileSystem.path.join(engineOutPath, 'flutter_tester.exe');
     }
     throw Exception('Unsupported platform $platform.');
   }
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index d7bf786..ac5e45d6 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 
 import 'package:meta/meta.dart';
+import 'package:platform/platform.dart';
 
 import 'android/gradle_utils.dart';
 import 'base/common.dart';
@@ -89,7 +90,19 @@
 class Cache {
   /// [rootOverride] is configurable for testing.
   /// [artifacts] is configurable for testing.
-  Cache({ Directory rootOverride, List<ArtifactSet> artifacts }) : _rootOverride = rootOverride {
+  Cache({
+    Directory rootOverride,
+    List<ArtifactSet> artifacts,
+    // TODO(jonahwilliams): make required once migrated to context-free.
+    Logger logger,
+    FileSystem fileSystem,
+    Platform platform,
+    OperatingSystemUtils osUtils,
+  }) : _rootOverride = rootOverride,
+       _logger = logger ?? globals.logger,
+       _fileSystem = fileSystem ?? globals.fs,
+       _platform = platform ?? globals.platform ,
+       _osUtils = osUtils ?? os {
     if (artifacts == null) {
       _artifacts.add(MaterialFonts(this));
 
@@ -116,6 +129,11 @@
     }
   }
 
+  final Logger _logger;
+  final Platform _platform;
+  final FileSystem _fileSystem;
+  final OperatingSystemUtils _osUtils;
+
   static const List<String> _hostsBlockedInChina = <String> [
     'storage.googleapis.com',
   ];
@@ -217,7 +235,7 @@
     if (_dartSdkVersion == null) {
       // Make the version string more customer-friendly.
       // Changes '2.1.0-dev.8.0.flutter-4312ae32' to '2.1.0 (build 2.1.0-dev.8.0 4312ae32)'
-      final String justVersion = globals.platform.version.split(' ')[0];
+      final String justVersion = _platform.version.split(' ')[0];
       _dartSdkVersion = justVersion.replaceFirstMapped(RegExp(r'(\d+\.\d+\.\d+)(.+)'), (Match match) {
         final String noFlutter = match[2].replaceAll('.flutter-', ' ');
         return '${match[1]} (build ${match[1]}$noFlutter)';
@@ -234,7 +252,7 @@
   String _engineRevision;
 
   String get storageBaseUrl {
-    final String overrideUrl = globals.platform.environment['FLUTTER_STORAGE_BASE_URL'];
+    final String overrideUrl = _platform.environment['FLUTTER_STORAGE_BASE_URL'];
     if (overrideUrl == null) {
       return 'https://storage.googleapis.com';
     }
@@ -254,7 +272,7 @@
     if (_hasWarnedAboutStorageOverride) {
       return;
     }
-    globals.logger.printStatus(
+    _logger.printStatus(
       'Flutter assets will be downloaded from $overrideUrl. Make sure you trust this source!',
       emphasis: true,
     );
@@ -264,18 +282,18 @@
   /// Return the top-level directory in the cache; this is `bin/cache`.
   Directory getRoot() {
     if (_rootOverride != null) {
-      return globals.fs.directory(globals.fs.path.join(_rootOverride.path, 'bin', 'cache'));
+      return _fileSystem.directory(_fileSystem.path.join(_rootOverride.path, 'bin', 'cache'));
     } else {
-      return globals.fs.directory(globals.fs.path.join(flutterRoot, 'bin', 'cache'));
+      return _fileSystem.directory(_fileSystem.path.join(flutterRoot, 'bin', 'cache'));
     }
   }
 
   /// Return a directory in the cache dir. For `pkg`, this will return `bin/cache/pkg`.
   Directory getCacheDir(String name) {
-    final Directory dir = globals.fs.directory(globals.fs.path.join(getRoot().path, name));
+    final Directory dir = _fileSystem.directory(_fileSystem.path.join(getRoot().path, name));
     if (!dir.existsSync()) {
       dir.createSync(recursive: true);
-      os.chmod(dir, '755');
+      _osUtils.chmod(dir, '755');
     }
     return dir;
   }
@@ -287,7 +305,7 @@
   Directory getCacheArtifacts() => getCacheDir('artifacts');
 
   /// Location of LICENSE file.
-  File getLicenseFile() => globals.fs.file(globals.fs.path.join(flutterRoot, 'LICENSE'));
+  File getLicenseFile() => _fileSystem.file(_fileSystem.path.join(flutterRoot, 'LICENSE'));
 
   /// Get a named directory from with the cache's artifact directory; for example,
   /// `material_fonts` would return `bin/cache/artifacts/material_fonts`.
@@ -323,7 +341,7 @@
   }
 
   String getVersionFor(String artifactName) {
-    final File versionFile = globals.fs.file(globals.fs.path.join(
+    final File versionFile = _fileSystem.file(globals.fs.path.join(
         _rootOverride?.path ?? flutterRoot, 'bin', 'internal',
         '$artifactName.version'));
     return versionFile.existsSync() ? versionFile.readAsStringSync().trim() : null;
@@ -339,7 +357,7 @@
   }
 
   File getStampFileFor(String artifactName) {
-    return globals.fs.file(globals.fs.path.join(getRoot().path, '$artifactName.stamp'));
+    return _fileSystem.file(_fileSystem.path.join(getRoot().path, '$artifactName.stamp'));
   }
 
   /// Returns `true` if either [entity] is older than the tools stamp or if
@@ -358,13 +376,13 @@
     final Uri url = Uri.parse(urlStr);
     final Directory thirdPartyDir = getArtifactDirectory('third_party');
 
-    final Directory serviceDir = globals.fs.directory(globals.fs.path.join(thirdPartyDir.path, serviceName));
+    final Directory serviceDir = _fileSystem.directory(_fileSystem.path.join(thirdPartyDir.path, serviceName));
     if (!serviceDir.existsSync()) {
       serviceDir.createSync(recursive: true);
-      os.chmod(serviceDir, '755');
+      _osUtils.chmod(serviceDir, '755');
     }
 
-    final File cachedFile = globals.fs.file(globals.fs.path.join(serviceDir.path, url.pathSegments.last));
+    final File cachedFile = _fileSystem.file(_fileSystem.path.join(serviceDir.path, url.pathSegments.last));
     if (!cachedFile.existsSync()) {
       try {
         await _downloadFile(url, cachedFile);
@@ -383,7 +401,7 @@
     }
     for (final ArtifactSet artifact in _artifacts) {
       if (!requiredArtifacts.contains(artifact.developmentArtifact)) {
-        globals.printTrace('Artifact $artifact is not required, skipping update.');
+        _logger.printTrace('Artifact $artifact is not required, skipping update.');
         continue;
       }
       if (artifact.isUpToDate()) {
@@ -393,7 +411,7 @@
         await artifact.update();
       } on SocketException catch (e) {
         if (_hostsBlockedInChina.contains(e.address?.host)) {
-          globals.printError(
+          _logger.printError(
             'Failed to retrieve Flutter tool dependencies: ${e.message}.\n'
             'If you\'re in China, please see this page: '
             'https://flutter.dev/community/china',
@@ -409,15 +427,15 @@
     String engineVersion,
     bool includeAllPlatforms = true,
   }) async {
-    final bool includeAllPlatformsState = globals.cache.includeAllPlatforms;
+    final bool includeAllPlatformsState = this.includeAllPlatforms;
     bool allAvailible = true;
-    globals.cache.includeAllPlatforms = includeAllPlatforms;
+    this.includeAllPlatforms = includeAllPlatforms;
     for (final ArtifactSet cachedArtifact in _artifacts) {
       if (cachedArtifact is EngineCachedArtifact) {
         allAvailible &= await cachedArtifact.checkForArtifacts(engineVersion);
       }
     }
-    globals.cache.includeAllPlatforms = includeAllPlatformsState;
+    this.includeAllPlatforms = includeAllPlatformsState;
     return allAvailible;
   }
 }
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index d6e7c6d..4135286 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -72,10 +72,18 @@
       AndroidValidator: () => AndroidValidator(),
       AndroidWorkflow: () => AndroidWorkflow(),
       ApplicationPackageFactory: () => ApplicationPackageFactory(),
-      Artifacts: () => CachedArtifacts(),
+      Artifacts: () => CachedArtifacts(
+        fileSystem: globals.fs,
+        cache: globals.cache,
+        platform: globals.platform,
+      ),
       AssetBundleFactory: () => AssetBundleFactory.defaultInstance,
       BuildSystem: () => const BuildSystem(),
-      Cache: () => Cache(),
+      Cache: () => Cache(
+        fileSystem: globals.fs,
+        logger: globals.logger,
+        platform: globals.platform,
+      ),
       ChromeLauncher: () => const ChromeLauncher(),
       CocoaPods: () => CocoaPods(),
       CocoaPodsValidator: () => const CocoaPodsValidator(),