blob: a2979670fd939e5d349771f307885eb248c2be86 [file] [log] [blame]
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:io'
show
Process,
ProcessResult,
ProcessSignal,
ProcessStartMode,
systemEncoding;
import 'common.dart';
import 'process_manager.dart';
/// Local implementation of the `ProcessManager` interface.
///
/// This implementation delegates directly to the corresponding static methods
/// in `dart:io`.
///
/// All methods that take a `command` will run `toString()` on the command
/// elements to derive the executable and arguments that should be passed to
/// the underlying `dart:io` methods. Thus, the degenerate case of
/// `List<String>` will trivially work as expected.
class LocalProcessManager implements ProcessManager {
/// Creates a new `LocalProcessManager`.
const LocalProcessManager();
@override
Future<Process> start(
covariant List<Object> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment: true,
bool runInShell: false,
ProcessStartMode mode: ProcessStartMode.normal,
}) {
return Process.start(
_getExecutable(command, workingDirectory, runInShell),
_getArguments(command),
workingDirectory: workingDirectory,
environment: environment,
includeParentEnvironment: includeParentEnvironment,
runInShell: runInShell,
mode: mode,
);
}
@override
Future<ProcessResult> run(
covariant List<Object> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment: true,
bool runInShell: false,
Encoding stdoutEncoding: systemEncoding,
Encoding stderrEncoding: systemEncoding,
}) {
return Process.run(
_getExecutable(command, workingDirectory, runInShell),
_getArguments(command),
workingDirectory: workingDirectory,
environment: environment,
includeParentEnvironment: includeParentEnvironment,
runInShell: runInShell,
stdoutEncoding: stdoutEncoding,
stderrEncoding: stderrEncoding,
);
}
@override
ProcessResult runSync(
covariant List<Object> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment: true,
bool runInShell: false,
Encoding stdoutEncoding: systemEncoding,
Encoding stderrEncoding: systemEncoding,
}) {
return Process.runSync(
_getExecutable(command, workingDirectory, runInShell),
_getArguments(command),
workingDirectory: workingDirectory,
environment: environment,
includeParentEnvironment: includeParentEnvironment,
runInShell: runInShell,
stdoutEncoding: stdoutEncoding,
stderrEncoding: stderrEncoding,
);
}
@override
bool canRun(covariant Object executable, {String workingDirectory}) =>
getExecutablePath(executable, workingDirectory) != null;
@override
bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) {
return Process.killPid(pid, signal);
}
}
String _getExecutable(
List<dynamic> command, String workingDirectory, bool runInShell) {
String commandName = command.first.toString();
if (runInShell) {
return commandName;
}
String exe = getExecutablePath(commandName, workingDirectory);
if (exe == null) {
throw new ArgumentError('Cannot find executable for $commandName.');
}
return exe;
}
List<String> _getArguments(List<dynamic> command) =>
// Adding a specific type to map in order to workaround dart issue
// https://github.com/dart-lang/sdk/issues/32414
command
.skip(1)
.map<String>((dynamic element) => element.toString())
.toList();