Revert "[flutter_tools] move process manager into tool (#75350)" (#75639)
This reverts commit 8b6baae44c8661d548643ced73493e6a66862622.
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index e7260c7..e5af683 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../android/android_builder.dart';
import '../android/android_sdk.dart';
diff --git a/packages/flutter_tools/lib/src/android/android_device_discovery.dart b/packages/flutter_tools/lib/src/android/android_device_discovery.dart
index d7f0125..b712fbd 100644
--- a/packages/flutter_tools/lib/src/android/android_device_discovery.dart
+++ b/packages/flutter_tools/lib/src/android/android_device_discovery.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/common.dart';
import '../base/file_system.dart';
diff --git a/packages/flutter_tools/lib/src/android/android_emulator.dart b/packages/flutter_tools/lib/src/android/android_emulator.dart
index b5932c3..4378d26 100644
--- a/packages/flutter_tools/lib/src/android/android_emulator.dart
+++ b/packages/flutter_tools/lib/src/android/android_emulator.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../android/android_sdk.dart';
import '../android/android_workflow.dart';
diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart
index 2665cd1..cc3a556 100644
--- a/packages/flutter_tools/lib/src/android/android_workflow.dart
+++ b/packages/flutter_tools/lib/src/android/android_workflow.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/common.dart';
import '../base/context.dart';
@@ -13,7 +14,6 @@
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/user_messages.dart' hide userMessages;
import '../base/version.dart';
import '../convert.dart';
diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart
index 78fb7f1..740674a 100644
--- a/packages/flutter_tools/lib/src/application_package.dart
+++ b/packages/flutter_tools/lib/src/application_package.dart
@@ -7,6 +7,7 @@
import 'dart:collection';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'package:xml/xml.dart';
import 'android/android_sdk.dart';
diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index aef8921..fc2e180 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -5,11 +5,11 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'base/common.dart';
import 'base/file_system.dart';
import 'base/platform.dart';
-import 'base/process.dart';
import 'base/utils.dart';
import 'build_info.dart';
import 'cache.dart';
diff --git a/packages/flutter_tools/lib/src/base/build.dart b/packages/flutter_tools/lib/src/base/build.dart
index 1d7a740..a1fe82f 100644
--- a/packages/flutter_tools/lib/src/base/build.dart
+++ b/packages/flutter_tools/lib/src/base/build.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../build_info.dart';
diff --git a/packages/flutter_tools/lib/src/base/error_handling_io.dart b/packages/flutter_tools/lib/src/base/error_handling_io.dart
index 383bdad..2298cf6 100644
--- a/packages/flutter_tools/lib/src/base/error_handling_io.dart
+++ b/packages/flutter_tools/lib/src/base/error_handling_io.dart
@@ -5,18 +5,17 @@
// @dart = 2.8
import 'dart:convert';
-import 'dart:io' as io show Directory, File, Link, ProcessException, ProcessResult, systemEncoding, Process, ProcessStartMode;
+import 'dart:io' as io show Directory, File, Link, ProcessException, ProcessResult, ProcessSignal, systemEncoding, Process, ProcessStartMode;
import 'dart:typed_data';
import 'package:file/file.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p; // ignore: package_path_import
+import 'package:process/process.dart';
import '../reporting/reporting.dart';
import 'common.dart' show throwToolExit;
-import 'io.dart';
import 'platform.dart';
-import 'process.dart';
// The Flutter tool hits file system and process errors that only the end-user can address.
// We would like these errors to not hit crash logging. In these cases, we
@@ -674,7 +673,7 @@
}
@override
- bool canRun(String executable, {String workingDirectory}) {
+ bool canRun(dynamic executable, {String workingDirectory}) {
return _runSync(
() => _delegate.canRun(executable, workingDirectory: workingDirectory),
platform: _platform,
@@ -682,7 +681,7 @@
}
@override
- bool killPid(int pid, [ProcessSignal signal = ProcessSignal.SIGTERM]) {
+ bool killPid(int pid, [io.ProcessSignal signal = io.ProcessSignal.sigterm]) {
return _runSync(
() => _delegate.killPid(pid, signal),
platform: _platform,
@@ -691,7 +690,7 @@
@override
Future<io.ProcessResult> run(
- List<String> command, {
+ List<dynamic> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment = true,
@@ -725,7 +724,7 @@
@override
Future<io.Process> start(
- List<String> command, {
+ List<dynamic> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment = true,
@@ -754,7 +753,7 @@
@override
io.ProcessResult runSync(
- List<String> command, {
+ List<dynamic> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment = true,
diff --git a/packages/flutter_tools/lib/src/base/os.dart b/packages/flutter_tools/lib/src/base/os.dart
index 87eef85..6dd4729 100644
--- a/packages/flutter_tools/lib/src/base/os.dart
+++ b/packages/flutter_tools/lib/src/base/os.dart
@@ -7,6 +7,7 @@
import 'package:archive/archive.dart';
import 'package:file/file.dart';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../build_info.dart';
import '../globals.dart' as globals;
diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart
index ace02bc..e4b8e05 100644
--- a/packages/flutter_tools/lib/src/base/process.dart
+++ b/packages/flutter_tools/lib/src/base/process.dart
@@ -7,15 +7,13 @@
import 'dart:async';
import 'package:meta/meta.dart';
-import 'package:file/local.dart' as local_fs;
+import 'package:process/process.dart';
import '../convert.dart';
import 'common.dart';
import 'context.dart';
-import 'file_system.dart';
import 'io.dart';
import 'logger.dart';
-import 'platform.dart';
typedef StringConverter = String Function(String string);
@@ -609,386 +607,3 @@
}
}
}
-
-/// Manages the creation of abstract processes.
-///
-/// Using instances of this class provides level of indirection from the static
-/// methods in the [Process] class, which in turn allows the underlying
-/// implementation to be mocked out or decorated for testing and debugging
-/// purposes.
-abstract class ProcessManager {
- /// Starts a process by running the specified [command].
- ///
- /// The first element in [command] will be treated as the executable to run,
- /// with subsequent elements being passed as arguments to the executable. It
- /// is left to implementations to decide what element types they support in
- /// the [command] list.
- ///
- /// Returns a `Future<Process>` that completes with a Process instance when
- /// the process has been successfully started. That [Process] object can be
- /// used to interact with the process. If the process cannot be started, the
- /// returned [Future] completes with an exception.
- ///
- /// Use [workingDirectory] to set the working directory for the process. Note
- /// that the change of directory occurs before executing the process on some
- /// platforms, which may have impact when using relative paths for the
- /// executable and the arguments.
- ///
- /// Use [environment] to set the environment variables for the process. If not
- /// set, the environment of the parent process is inherited. Currently, only
- /// US-ASCII environment variables are supported and errors are likely to occur
- /// if an environment variable with code-points outside the US-ASCII range is
- /// passed in.
- ///
- /// If [includeParentEnvironment] is `true`, the process's environment will
- /// include the parent process's environment, with [environment] taking
- /// precedence. Default is `true`.
- ///
- /// If [runInShell] is `true`, the process will be spawned through a system
- /// shell. On Linux and OS X, `/bin/sh` is used, while
- /// `%WINDIR%\system32\cmd.exe` is used on Windows.
- ///
- /// Users must read all data coming on the `stdout` and `stderr`
- /// streams of processes started with [start]. If the user
- /// does not read all data on the streams the underlying system
- /// resources will not be released since there is still pending data.
- ///
- /// The following code uses `start` to grep for `main` in the
- /// file `test.dart` on Linux.
- ///
- /// ProcessManager mgr = new LocalProcessManager();
- /// mgr.start('grep', ['-i', 'main', 'test.dart']).then((process) {
- /// stdout.addStream(process.stdout);
- /// stderr.addStream(process.stderr);
- /// });
- ///
- /// If [mode] is [ProcessStartMode.normal] (the default) a child
- /// process will be started with `stdin`, `stdout` and `stderr`
- /// connected.
- ///
- /// If `mode` is [ProcessStartMode.detached] a detached process will
- /// be created. A detached process has no connection to its parent,
- /// and can keep running on its own when the parent dies. The only
- /// information available from a detached process is its `pid`. There
- /// is no connection to its `stdin`, `stdout` or `stderr`, nor will
- /// the process' exit code become available when it terminates.
- ///
- /// If `mode` is [ProcessStartMode.detachedWithStdio] a detached
- /// process will be created where the `stdin`, `stdout` and `stderr`
- /// are connected. The creator can communicate with the child through
- /// these. The detached process will keep running even if these
- /// communication channels are closed. The process' exit code will
- /// not become available when it terminated.
- ///
- /// The default value for `mode` is `ProcessStartMode.NORMAL`.
- Future<Process> start(
- List<String> command, {
- String workingDirectory,
- Map<String, String> environment,
- bool includeParentEnvironment = true,
- bool runInShell = false,
- ProcessStartMode mode = ProcessStartMode.normal,
- });
-
- /// Starts a process and runs it non-interactively to completion.
- ///
- /// The first element in [command] will be treated as the executable to run,
- /// with subsequent elements being passed as arguments to the executable.
- ///
- /// Use [workingDirectory] to set the working directory for the process. Note
- /// that the change of directory occurs before executing the process on some
- /// platforms, which may have impact when using relative paths for the
- /// executable and the arguments.
- ///
- /// Use [environment] to set the environment variables for the process. If not
- /// set the environment of the parent process is inherited. Currently, only
- /// US-ASCII environment variables are supported and errors are likely to occur
- /// if an environment variable with code-points outside the US-ASCII range is
- /// passed in.
- ///
- /// If [includeParentEnvironment] is `true`, the process's environment will
- /// include the parent process's environment, with [environment] taking
- /// precedence. Default is `true`.
- ///
- /// If [runInShell] is true, the process will be spawned through a system
- /// shell. On Linux and OS X, `/bin/sh` is used, while
- /// `%WINDIR%\system32\cmd.exe` is used on Windows.
- ///
- /// The encoding used for decoding `stdout` and `stderr` into text is
- /// controlled through [stdoutEncoding] and [stderrEncoding]. The
- /// default encoding is [systemEncoding]. If `null` is used no
- /// decoding will happen and the [ProcessResult] will hold binary
- /// data.
- ///
- /// Returns a `Future<ProcessResult>` that completes with the
- /// result of running the process, i.e., exit code, standard out and
- /// standard in.
- ///
- /// The following code uses `run` to grep for `main` in the
- /// file `test.dart` on Linux.
- ///
- /// ProcessManager mgr = new LocalProcessManager();
- /// mgr.run('grep', ['-i', 'main', 'test.dart']).then((result) {
- /// stdout.write(result.stdout);
- /// stderr.write(result.stderr);
- /// });
- Future<ProcessResult> run(
- List<String> command, {
- String workingDirectory,
- Map<String, String> environment,
- bool includeParentEnvironment = true,
- bool runInShell = false,
- Encoding stdoutEncoding = systemEncoding,
- Encoding stderrEncoding = systemEncoding,
- });
-
- /// Starts a process and runs it to completion. This is a synchronous
- /// call and will block until the child process terminates.
- ///
- /// The arguments are the same as for [run]`.
- ///
- /// Returns a `ProcessResult` with the result of running the process,
- /// i.e., exit code, standard out and standard in.
- ProcessResult runSync(
- List<String> command, {
- String workingDirectory,
- Map<String, String> environment,
- bool includeParentEnvironment = true,
- bool runInShell = false,
- Encoding stdoutEncoding = systemEncoding,
- Encoding stderrEncoding = systemEncoding,
- });
-
- /// Returns `true` if the [executable] exists and if it can be executed.
- bool canRun(String executable, {String workingDirectory});
-
- /// Kills the process with id [pid].
- ///
- /// Where possible, sends the [signal] to the process with id
- /// `pid`. This includes Linux and OS X. The default signal is
- /// [ProcessSignal.sigterm] which will normally terminate the
- /// process.
- ///
- /// On platforms without signal support, including Windows, the call
- /// just terminates the process with id `pid` in a platform specific
- /// way, and the `signal` parameter is ignored.
- ///
- /// Returns `true` if the signal is successfully delivered to the
- /// process. Otherwise the signal could not be sent, usually meaning
- /// that the process is already dead.
- bool killPid(int pid, [ProcessSignal signal = ProcessSignal.SIGTERM]);
-}
-
-/// A process manager that delegates directly to the dart:io Process class.
-class LocalProcessManager implements ProcessManager {
- const LocalProcessManager({
- @visibleForTesting FileSystem fileSystem = const local_fs.LocalFileSystem(),
- @visibleForTesting Platform platform = const LocalPlatform(),
- }) : _platform = platform,
- _fileSystem = fileSystem;
-
- final Platform _platform;
- final FileSystem _fileSystem;
-
- @override
- bool canRun(String executable, {String workingDirectory}) {
- return getExecutablePath(executable, workingDirectory, platform: _platform, fileSystem: _fileSystem) != null;
- }
-
- @override
- bool killPid(int pid, [ProcessSignal signal = ProcessSignal.SIGTERM]) {
- return signal.send(pid);
- }
-
- @override
- Future<ProcessResult> run(List<String> command, {
- String workingDirectory,
- Map<String, String> environment,
- bool includeParentEnvironment = true,
- bool runInShell = false,
- Encoding stdoutEncoding = systemEncoding,
- Encoding stderrEncoding = systemEncoding,
- }) {
- return Process.run(
- sanitizeExecutablePath(_getExecutable(
- command,
- workingDirectory,
- runInShell,
- ), platform: _platform),
- _getArguments(command),
- environment: environment,
- includeParentEnvironment: includeParentEnvironment,
- stdoutEncoding: systemEncoding,
- stderrEncoding: systemEncoding,
- workingDirectory: workingDirectory,
- runInShell: runInShell,
- );
- }
-
- @override
- ProcessResult runSync(List<String> command, {
- String workingDirectory,
- Map<String, String> environment,
- bool includeParentEnvironment = true,
- bool runInShell = false,
- Encoding stdoutEncoding = systemEncoding,
- Encoding stderrEncoding = systemEncoding,
- }) {
- return Process.runSync(
- sanitizeExecutablePath(_getExecutable(
- command,
- workingDirectory,
- runInShell,
- ), platform: _platform),
- _getArguments(command),
- environment: environment,
- includeParentEnvironment: includeParentEnvironment,
- stdoutEncoding: systemEncoding,
- stderrEncoding: systemEncoding,
- workingDirectory: workingDirectory,
- runInShell: runInShell,
- );
- }
-
- @override
- Future<Process> start(
- List<String> command, {
- String workingDirectory,
- Map<String, String> environment,
- bool includeParentEnvironment = true,
- bool runInShell = false,
- ProcessStartMode mode = ProcessStartMode.normal,
- }) {
- return Process.start(
- sanitizeExecutablePath(_getExecutable(
- command,
- workingDirectory,
- runInShell,
- ), platform: _platform),
- _getArguments(command),
- workingDirectory: workingDirectory,
- environment: environment,
- includeParentEnvironment: includeParentEnvironment,
- runInShell: runInShell,
- mode: mode,
- );
- }
-
- String _getExecutable(
- List<String> command,
- String workingDirectory,
- bool runInShell,
- ) {
- final String commandName = command.first.toString();
- if (runInShell) {
- return commandName;
- }
- final String executable = getExecutablePath(commandName, workingDirectory, platform: _platform, fileSystem: _fileSystem);
- if (executable == null) {
- throw ArgumentError('Could not resolve $commandName to executablePath in $workingDirectory');
- }
- return executable;
- }
-
- List<String> _getArguments(
- List<String> command,
- ) {
- return command.skip(1).toList();
- }
-}
-
-/// Sanatizes the executable path on Windows.
-/// https://github.com/dart-lang/sdk/issues/37751
-String sanitizeExecutablePath(String executable, {@required Platform platform }) {
- if (executable.isEmpty) {
- return executable;
- }
- if (!platform.isWindows) {
- return executable;
- }
- if (executable.contains(' ') && !executable.contains('"')) {
- // Use quoted strings to indicate where the file name ends and the arguments begin;
- // otherwise, the file name is ambiguous.
- return '"$executable"';
- }
- return executable;
-}
-
-/// Searches the `PATH` for the executable that [command] is supposed to launch.
-///
-/// This first builds a list of candidate paths where the executable may reside.
-/// If [command] is already an absolute path, then the `PATH` environment
-/// variable will not be consulted, and the specified absolute path will be the
-/// only candidate that is considered.
-///
-/// Once the list of candidate paths has been constructed, this will pick the
-/// first such path that represents an existent file.
-///
-/// Return `null` if there were no viable candidates, meaning the executable
-/// could not be found.
-///
-/// If [platform] is not specified, it will default to the current platform.
-@visibleForTesting
-String getExecutablePath(
- String command,
- String workingDirectory, {
- @required Platform platform,
- @required FileSystem fileSystem,
-}) {
- try {
- workingDirectory ??= fileSystem.currentDirectory.path;
- } on FileSystemException {
- // The `currentDirectory` getter can throw a FileSystemException for example
- // when the process doesn't have read/list permissions in each component of
- // the cwd path. In this case, fall back on '.'.
- workingDirectory ??= '.';
- }
- final String pathSeparator = platform.isWindows ? ';' : ':';
-
- List<String> extensions = <String>[];
- if (platform.isWindows && fileSystem.path.extension(command).isEmpty) {
- extensions = platform.environment['PATHEXT'].split(pathSeparator);
- }
-
- List<String> candidates = <String>[];
- if (command.contains(fileSystem.path.separator)) {
- candidates = _getCandidatePaths(
- command, <String>[workingDirectory], extensions, fileSystem);
- } else {
- final List<String> searchPath = platform.environment['PATH'].split(pathSeparator);
- candidates = _getCandidatePaths(command, searchPath, extensions, fileSystem);
- }
- for (final String path in candidates) {
- if (fileSystem.file(path).existsSync()) {
- return path;
- }
- }
- return null;
-}
-
-/// Returns all possible combinations of `$searchPath\$command.$ext` for
-/// `searchPath` in [searchPaths] and `ext` in [extensions].
-///
-/// If [extensions] is empty, it will just enumerate all
-/// `$searchPath\$command`.
-/// If [command] is an absolute path, it will just enumerate
-/// `$command.$ext`.
-List<String> _getCandidatePaths(
- String command,
- List<String> searchPaths,
- List<String> extensions,
- FileSystem fileSystem,
-) {
- final List<String> withExtensions = extensions.isNotEmpty
- ? extensions.map((String ext) => '$command$ext').toList()
- : <String>[command];
- if (fileSystem.path.isAbsolute(command)) {
- return withExtensions;
- }
- return searchPaths
- .map((String path) =>
- withExtensions.map((String command) => fileSystem.path.join(path, command)))
- .expand((Iterable<String> e) => e)
- .toList()
- .cast<String>();
-}
diff --git a/packages/flutter_tools/lib/src/build_system/build_system.dart b/packages/flutter_tools/lib/src/build_system/build_system.dart
index 1c9a61e..48013e8 100644
--- a/packages/flutter_tools/lib/src/build_system/build_system.dart
+++ b/packages/flutter_tools/lib/src/build_system/build_system.dart
@@ -9,13 +9,13 @@
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
import 'package:pool/pool.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/error_handling_io.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/utils.dart';
import '../cache.dart';
import '../convert.dart';
diff --git a/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart b/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart
index 1bbefca..4eb4dc5 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'package:mime/mime.dart' as mime;
import '../../artifacts.dart';
@@ -12,7 +13,6 @@
import '../../base/file_system.dart';
import '../../base/io.dart';
import '../../base/logger.dart';
-import '../../base/process.dart';
import '../../convert.dart';
import '../../devfs.dart';
import '../build_system.dart';
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index 09179f5..8cdd95d 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -10,6 +10,7 @@
import 'package:file/memory.dart';
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
+import 'package:process/process.dart';
import 'android/gradle_utils.dart';
import 'base/common.dart';
diff --git a/packages/flutter_tools/lib/src/commands/analyze.dart b/packages/flutter_tools/lib/src/commands/analyze.dart
index 1012bbb..8b014f5 100644
--- a/packages/flutter_tools/lib/src/commands/analyze.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze.dart
@@ -5,12 +5,12 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/terminal.dart';
import '../runner/flutter_command.dart';
import 'analyze_continuously.dart';
diff --git a/packages/flutter_tools/lib/src/commands/analyze_base.dart b/packages/flutter_tools/lib/src/commands/analyze_base.dart
index 3efc142..b9ee108 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_base.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_base.dart
@@ -6,6 +6,7 @@
import 'package:args/args.dart';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'package:yaml/yaml.dart' as yaml;
import '../artifacts.dart';
@@ -13,7 +14,6 @@
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../cache.dart';
diff --git a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
index 4ad30b0..84aa07e 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_continuously.dart
@@ -6,6 +6,7 @@
import 'package:args/args.dart';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/common.dart';
@@ -13,7 +14,6 @@
import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/terminal.dart';
import '../dart/analysis.dart';
import 'analyze_base.dart';
diff --git a/packages/flutter_tools/lib/src/commands/analyze_once.dart b/packages/flutter_tools/lib/src/commands/analyze_once.dart
index dbc80aa..6a55909 100644
--- a/packages/flutter_tools/lib/src/commands/analyze_once.dart
+++ b/packages/flutter_tools/lib/src/commands/analyze_once.dart
@@ -8,13 +8,13 @@
import 'package:args/args.dart';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/terminal.dart';
import '../dart/analysis.dart';
import 'analyze_base.dart';
diff --git a/packages/flutter_tools/lib/src/commands/downgrade.dart b/packages/flutter_tools/lib/src/commands/downgrade.dart
index 88bbf55..71dfec2 100644
--- a/packages/flutter_tools/lib/src/commands/downgrade.dart
+++ b/packages/flutter_tools/lib/src/commands/downgrade.dart
@@ -4,6 +4,8 @@
// @dart = 2.8
+import 'package:process/process.dart';
+
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart
index 0a5095a..76923c2 100644
--- a/packages/flutter_tools/lib/src/compile.dart
+++ b/packages/flutter_tools/lib/src/compile.dart
@@ -8,6 +8,7 @@
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
+import 'package:process/process.dart';
import 'package:usage/uuid/uuid.dart';
import 'artifacts.dart';
@@ -16,7 +17,6 @@
import 'base/io.dart';
import 'base/logger.dart';
import 'base/platform.dart';
-import 'base/process.dart';
import 'build_info.dart';
import 'convert.dart';
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index bb3139b..ae436f5 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -6,6 +6,8 @@
import 'dart:async';
+import 'package:process/process.dart';
+
import 'android/android_sdk.dart';
import 'android/android_studio.dart';
import 'android/android_workflow.dart';
diff --git a/packages/flutter_tools/lib/src/dart/analysis.dart b/packages/flutter_tools/lib/src/dart/analysis.dart
index cc05e91..ef873b2 100644
--- a/packages/flutter_tools/lib/src/dart/analysis.dart
+++ b/packages/flutter_tools/lib/src/dart/analysis.dart
@@ -8,13 +8,13 @@
import 'dart:math' as math;
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../convert.dart';
diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart
index 61c9c44..535a08b 100644
--- a/packages/flutter_tools/lib/src/dart/pub.dart
+++ b/packages/flutter_tools/lib/src/dart/pub.dart
@@ -6,6 +6,7 @@
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
+import 'package:process/process.dart';
import '../base/bot_detector.dart';
import '../base/common.dart';
diff --git a/packages/flutter_tools/lib/src/desktop_device.dart b/packages/flutter_tools/lib/src/desktop_device.dart
index 20f7fac..0a8d1b9 100644
--- a/packages/flutter_tools/lib/src/desktop_device.dart
+++ b/packages/flutter_tools/lib/src/desktop_device.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'application_package.dart';
import 'base/common.dart';
@@ -14,7 +15,6 @@
import 'base/io.dart';
import 'base/logger.dart';
import 'base/os.dart';
-import 'base/process.dart';
import 'build_info.dart';
import 'convert.dart';
import 'devfs.dart';
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart
index 1c6d661..d6bbc42 100644
--- a/packages/flutter_tools/lib/src/device.dart
+++ b/packages/flutter_tools/lib/src/device.dart
@@ -8,6 +8,7 @@
import 'dart:math' as math;
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import 'android/android_device_discovery.dart';
@@ -24,7 +25,6 @@
import 'base/logger.dart';
import 'base/os.dart';
import 'base/platform.dart';
-import 'base/process.dart';
import 'base/terminal.dart';
import 'base/user_messages.dart' hide userMessages;
import 'base/utils.dart';
diff --git a/packages/flutter_tools/lib/src/devtools_launcher.dart b/packages/flutter_tools/lib/src/devtools_launcher.dart
index 3562058..791f577 100644
--- a/packages/flutter_tools/lib/src/devtools_launcher.dart
+++ b/packages/flutter_tools/lib/src/devtools_launcher.dart
@@ -8,11 +8,11 @@
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'base/io.dart' as io;
import 'base/logger.dart';
import 'base/platform.dart';
-import 'base/process.dart';
import 'convert.dart';
import 'persistent_tool_state.dart';
import 'resident_runner.dart';
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index 44b8590..badb294 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'android/android_studio_validator.dart';
import 'android/android_workflow.dart';
@@ -15,7 +16,6 @@
import 'base/logger.dart';
import 'base/os.dart';
import 'base/platform.dart';
-import 'base/process.dart';
import 'base/terminal.dart';
import 'base/user_messages.dart';
import 'base/utils.dart';
diff --git a/packages/flutter_tools/lib/src/emulator.dart b/packages/flutter_tools/lib/src/emulator.dart
index de70d4a..e825ea2 100644
--- a/packages/flutter_tools/lib/src/emulator.dart
+++ b/packages/flutter_tools/lib/src/emulator.dart
@@ -7,6 +7,7 @@
import 'dart:math' as math;
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'android/android_emulator.dart';
import 'android/android_sdk.dart';
diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_dev_finder.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_dev_finder.dart
index 44b6b91..4086dfc 100644
--- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_dev_finder.dart
+++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_dev_finder.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/common.dart';
import '../base/logger.dart';
diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart
index 7a04cce..9288e75 100644
--- a/packages/flutter_tools/lib/src/globals.dart
+++ b/packages/flutter_tools/lib/src/globals.dart
@@ -4,6 +4,8 @@
// @dart = 2.8
+import 'package:process/process.dart';
+
import 'android/android_sdk.dart';
import 'android/android_studio.dart';
import 'artifacts.dart';
@@ -80,8 +82,10 @@
platform: platform,
);
+const ProcessManager _kLocalProcessManager = LocalProcessManager();
+
/// The active process manager.
-ProcessManager get processManager => context.get<ProcessManager>();
+ProcessManager get processManager => context.get<ProcessManager>() ?? _kLocalProcessManager;
ProcessUtils get processUtils => context.get<ProcessUtils>();
const Platform _kLocalPlatform = LocalPlatform();
diff --git a/packages/flutter_tools/lib/src/ios/code_signing.dart b/packages/flutter_tools/lib/src/ios/code_signing.dart
index 22e2fce..20708d1 100644
--- a/packages/flutter_tools/lib/src/ios/code_signing.dart
+++ b/packages/flutter_tools/lib/src/ios/code_signing.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../application_package.dart';
import '../base/common.dart';
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index e29d606..a66f947 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import '../application_package.dart';
@@ -16,7 +17,6 @@
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../convert.dart';
diff --git a/packages/flutter_tools/lib/src/ios/ios_deploy.dart b/packages/flutter_tools/lib/src/ios/ios_deploy.dart
index 55c8cec..9980d77 100644
--- a/packages/flutter_tools/lib/src/ios/ios_deploy.dart
+++ b/packages/flutter_tools/lib/src/ios/ios_deploy.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/common.dart';
diff --git a/packages/flutter_tools/lib/src/ios/iproxy.dart b/packages/flutter_tools/lib/src/ios/iproxy.dart
index e712b6f..6ce9455 100644
--- a/packages/flutter_tools/lib/src/ios/iproxy.dart
+++ b/packages/flutter_tools/lib/src/ios/iproxy.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/io.dart';
import '../base/logger.dart';
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index e4bca0f..9aeaf00 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../application_package.dart';
import '../artifacts.dart';
diff --git a/packages/flutter_tools/lib/src/ios/plist_parser.dart b/packages/flutter_tools/lib/src/ios/plist_parser.dart
index a3319a9..46efe26 100644
--- a/packages/flutter_tools/lib/src/ios/plist_parser.dart
+++ b/packages/flutter_tools/lib/src/ios/plist_parser.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/file_system.dart';
import '../base/io.dart';
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 800f4e8..05d4a1d 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -8,6 +8,7 @@
import 'dart:math' as math;
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../application_package.dart';
import '../base/common.dart';
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
index 56cb7d7..88d1280 100644
--- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart
+++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -6,6 +6,7 @@
import 'package:file/memory.dart';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/common.dart';
diff --git a/packages/flutter_tools/lib/src/linux/linux_device.dart b/packages/flutter_tools/lib/src/linux/linux_device.dart
index 07ccb7f..e122cea 100644
--- a/packages/flutter_tools/lib/src/linux/linux_device.dart
+++ b/packages/flutter_tools/lib/src/linux/linux_device.dart
@@ -5,12 +5,12 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../build_info.dart';
import '../desktop_device.dart';
import '../device.dart';
diff --git a/packages/flutter_tools/lib/src/linux/linux_doctor.dart b/packages/flutter_tools/lib/src/linux/linux_doctor.dart
index 6573e73..73fa32f 100644
--- a/packages/flutter_tools/lib/src/linux/linux_doctor.dart
+++ b/packages/flutter_tools/lib/src/linux/linux_doctor.dart
@@ -5,9 +5,9 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/io.dart';
-import '../base/process.dart';
import '../base/user_messages.dart';
import '../base/version.dart';
import '../doctor.dart';
diff --git a/packages/flutter_tools/lib/src/macos/cocoapods.dart b/packages/flutter_tools/lib/src/macos/cocoapods.dart
index 39aeb55..de01064 100644
--- a/packages/flutter_tools/lib/src/macos/cocoapods.dart
+++ b/packages/flutter_tools/lib/src/macos/cocoapods.dart
@@ -6,6 +6,7 @@
import 'package:file/file.dart';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/common.dart';
import '../base/error_handling_io.dart';
diff --git a/packages/flutter_tools/lib/src/macos/macos_device.dart b/packages/flutter_tools/lib/src/macos/macos_device.dart
index 07f0fcb..175255f 100644
--- a/packages/flutter_tools/lib/src/macos/macos_device.dart
+++ b/packages/flutter_tools/lib/src/macos/macos_device.dart
@@ -5,13 +5,13 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../build_info.dart';
import '../desktop_device.dart';
import '../device.dart';
diff --git a/packages/flutter_tools/lib/src/macos/xcode.dart b/packages/flutter_tools/lib/src/macos/xcode.dart
index 57ba8de..034b0d9 100644
--- a/packages/flutter_tools/lib/src/macos/xcode.dart
+++ b/packages/flutter_tools/lib/src/macos/xcode.dart
@@ -8,6 +8,7 @@
import 'package:file/memory.dart';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/common.dart';
diff --git a/packages/flutter_tools/lib/src/test/web_test_compiler.dart b/packages/flutter_tools/lib/src/test/web_test_compiler.dart
index 53dad37..5ee47bf 100644
--- a/packages/flutter_tools/lib/src/test/web_test_compiler.dart
+++ b/packages/flutter_tools/lib/src/test/web_test_compiler.dart
@@ -6,6 +6,7 @@
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
+import 'package:process/process.dart';
import '../artifacts.dart';
import '../base/common.dart';
@@ -13,7 +14,6 @@
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../build_info.dart';
import '../bundle.dart';
import '../compile.dart';
diff --git a/packages/flutter_tools/lib/src/tester/flutter_tester.dart b/packages/flutter_tools/lib/src/tester/flutter_tester.dart
index 8270922..d99e7ef 100644
--- a/packages/flutter_tools/lib/src/tester/flutter_tester.dart
+++ b/packages/flutter_tools/lib/src/tester/flutter_tester.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../application_package.dart';
import '../artifacts.dart';
@@ -14,7 +15,6 @@
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
-import '../base/process.dart';
import '../build_info.dart';
import '../bundle.dart';
import '../convert.dart';
diff --git a/packages/flutter_tools/lib/src/web/chrome.dart b/packages/flutter_tools/lib/src/web/chrome.dart
index 0e44884..427f1d8 100644
--- a/packages/flutter_tools/lib/src/web/chrome.dart
+++ b/packages/flutter_tools/lib/src/web/chrome.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
import '../base/common.dart';
@@ -15,7 +16,6 @@
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../convert.dart';
/// An environment variable used to override the location of Google Chrome.
diff --git a/packages/flutter_tools/lib/src/web/web_device.dart b/packages/flutter_tools/lib/src/web/web_device.dart
index 044a73b..df30ece 100644
--- a/packages/flutter_tools/lib/src/web/web_device.dart
+++ b/packages/flutter_tools/lib/src/web/web_device.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../application_package.dart';
import '../base/file_system.dart';
@@ -12,7 +13,6 @@
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
-import '../base/process.dart';
import '../base/version.dart';
import '../build_info.dart';
import '../device.dart';
diff --git a/packages/flutter_tools/lib/src/windows/visual_studio.dart b/packages/flutter_tools/lib/src/windows/visual_studio.dart
index cf2f9eb..0aedcbb 100644
--- a/packages/flutter_tools/lib/src/windows/visual_studio.dart
+++ b/packages/flutter_tools/lib/src/windows/visual_studio.dart
@@ -5,6 +5,7 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/file_system.dart';
import '../base/io.dart';
diff --git a/packages/flutter_tools/lib/src/windows/windows_device.dart b/packages/flutter_tools/lib/src/windows/windows_device.dart
index c67c8dd..4798029 100644
--- a/packages/flutter_tools/lib/src/windows/windows_device.dart
+++ b/packages/flutter_tools/lib/src/windows/windows_device.dart
@@ -5,11 +5,11 @@
// @dart = 2.8
import 'package:meta/meta.dart';
+import 'package:process/process.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/os.dart';
-import '../base/process.dart';
import '../build_info.dart';
import '../desktop_device.dart';
import '../device.dart';