-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathchild_process.dart
More file actions
84 lines (73 loc) · 2.29 KB
/
child_process.dart
File metadata and controls
84 lines (73 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import 'dart:io';
import 'package:celest_cli/src/context.dart';
import 'package:celest_cli/src/utils/cli.dart';
/// A process which is a child of a command like `celest start`.
///
/// The parent command is responsible for managing the lifecycle of the child
/// process via this class.
final class ChildProcess {
ChildProcess(this.command);
/// The command to run as a child process.
final List<String> command;
Process? _process;
/// Whether [start] has been called.
bool get isStarted => _process != null;
/// The process's exit code.
Future<int> get exitCode {
if (_process case final process?) {
return process.exitCode;
}
throw StateError('Must call start first');
}
/// Starts the process and streams stdout/stderr to the console.
///
/// If [environment] is not null, it is passed to [Process.start].
///
/// If [dartDefines] are specified and the [command] is a `dart` or `flutter`
/// command, then the given values are passed to the command via the respective
/// flag.
Future<void> start({
Map<String, String>? environment,
Map<String, String>? dartDefines,
}) async {
if (_process != null) {
return;
}
var command = this.command;
if (dartDefines != null) {
switch (command.first) {
case 'dart':
command = [
'dart',
for (final MapEntry(:key, :value) in dartDefines.entries)
'-D$key=$value',
...command.sublist(1),
];
case 'flutter':
command = [
...command,
for (final MapEntry(:key, :value) in dartDefines.entries)
'--dart-define=$key=$value'
];
}
}
final process = _process = await processManager.start(
command,
environment: environment,
);
// Capture stdout/stderr
final commandName = command.first;
process.captureStdout(prefix: '[$commandName] ');
process.captureStderr(prefix: '[$commandName] ');
// TODO(dnys1): Handle stdin?
}
/// Kills the process with the given [signal] and waits for the process to
/// exit.
Future<void> stop([ProcessSignal signal = ProcessSignal.sigterm]) async {
if (_process case final process?) {
process.kill(signal);
await process.exitCode;
}
_process = null;
}
}