depflow 3.0.0-dev.10 → 3.0.0-dev.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +513 -117
- package/dist/builder/Builder.d.ts +279 -0
- package/dist/builder/Builder.js +391 -0
- package/dist/builder/Builder.js.map +1 -0
- package/dist/cli/Actions.d.ts +187 -0
- package/dist/cli/Actions.js +793 -0
- package/dist/cli/Actions.js.map +1 -0
- package/dist/cli/CLI.d.ts +170 -0
- package/dist/cli/CLI.js +231 -0
- package/dist/cli/CLI.js.map +1 -0
- package/dist/cli/DepflowCLI.d.ts +62 -0
- package/dist/cli/DepflowCLI.js +229 -0
- package/dist/cli/DepflowCLI.js.map +1 -0
- package/dist/cli/Flags.d.ts +106 -0
- package/dist/cli/Flags.js +125 -0
- package/dist/cli/Flags.js.map +1 -0
- package/dist/cli/bin.js +63 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/config/Config.d.ts +690 -0
- package/dist/config/Config.js +45 -0
- package/dist/config/Config.js.map +1 -0
- package/dist/config/ImportMap.d.ts +60 -0
- package/dist/config/ImportMap.js +66 -0
- package/dist/config/ImportMap.js.map +1 -0
- package/dist/config/JsonSchema.d.ts +12 -0
- package/dist/config/JsonSchema.js +26 -0
- package/dist/config/JsonSchema.js.map +1 -0
- package/dist/config/Settings.d.ts +201 -0
- package/dist/config/Settings.js +191 -0
- package/dist/config/Settings.js.map +1 -0
- package/dist/config/TSConfig.d.ts +73 -0
- package/dist/config/TSConfig.js +73 -0
- package/dist/config/TSConfig.js.map +1 -0
- package/dist/config/codecs/JsonCodec.d.ts +30 -0
- package/dist/config/codecs/JsonCodec.js +31 -0
- package/dist/config/codecs/JsonCodec.js.map +1 -0
- package/dist/config/codecs/YamlCodec.d.ts +62 -0
- package/dist/config/codecs/YamlCodec.js +89 -0
- package/dist/config/codecs/YamlCodec.js.map +1 -0
- package/dist/dependency/DepUtils.d.ts +78 -0
- package/dist/dependency/DepUtils.js +122 -0
- package/dist/dependency/DepUtils.js.map +1 -0
- package/dist/dependency/Dependency.d.ts +81 -0
- package/dist/dependency/Dependency.js +71 -0
- package/dist/dependency/Dependency.js.map +1 -0
- package/dist/dependency/Git.d.ts +75 -0
- package/dist/dependency/Git.js +97 -0
- package/dist/dependency/Git.js.map +1 -0
- package/dist/dependency/GitDependency.d.ts +30 -0
- package/dist/dependency/GitDependency.js +79 -0
- package/dist/dependency/GitDependency.js.map +1 -0
- package/dist/dependency/NpmDependency.d.ts +27 -0
- package/dist/dependency/NpmDependency.js +91 -0
- package/dist/dependency/NpmDependency.js.map +1 -0
- package/{build/support/PathResolver → dist/resolve}/AliasCompiler.d.ts +18 -5
- package/{build/support/PathResolver → dist/resolve}/AliasCompiler.js +31 -9
- package/dist/resolve/AliasCompiler.js.map +1 -0
- package/{build/support/PathResolver → dist/resolve}/PathResolver.d.ts +25 -8
- package/dist/resolve/PathResolver.js +133 -0
- package/dist/resolve/PathResolver.js.map +1 -0
- package/dist/resolve/PathRewriter.d.ts +24 -0
- package/{build/support/PathResolver → dist/resolve}/PathRewriter.js +21 -11
- package/dist/resolve/PathRewriter.js.map +1 -0
- package/{build → dist}/schema/Config/Builder.d.ts +114 -49
- package/dist/schema/Config/Builder.js +78 -0
- package/dist/schema/Config/Builder.js.map +1 -0
- package/{build → dist}/schema/Config/Config.d.ts +169 -78
- package/dist/schema/Config/Config.js +62 -0
- package/dist/schema/Config/Config.js.map +1 -0
- package/{build → dist}/schema/Config/Dependency.d.ts +219 -89
- package/dist/schema/Config/Dependency.js +80 -0
- package/dist/schema/Config/Dependency.js.map +1 -0
- package/{build → dist}/schema/Config/Extractor.d.ts +41 -17
- package/dist/schema/Config/Extractor.js +43 -0
- package/dist/schema/Config/Extractor.js.map +1 -0
- package/{build → dist}/schema/Config/Resolver.d.ts +25 -8
- package/dist/schema/Config/Resolver.js +43 -0
- package/dist/schema/Config/Resolver.js.map +1 -0
- package/{build → dist}/schema/Config/Transform.d.ts +22 -5
- package/dist/schema/Config/Transform.js +51 -0
- package/dist/schema/Config/Transform.js.map +1 -0
- package/dist/schema/Defaults.d.ts +20 -0
- package/dist/schema/Defaults.js +24 -0
- package/dist/schema/Defaults.js.map +1 -0
- package/dist/schema/ImportMap.d.ts +30 -0
- package/dist/schema/ImportMap.js +28 -0
- package/dist/schema/ImportMap.js.map +1 -0
- package/{build → dist}/schema/TSConfig.d.ts +23 -9
- package/dist/schema/TSConfig.js +39 -0
- package/dist/schema/TSConfig.js.map +1 -0
- package/{build → dist}/schema/schema.d.ts +11 -2
- package/{build → dist}/schema/schema.js +11 -2
- package/dist/schema/schema.js.map +1 -0
- package/dist/task/Command.d.ts +287 -0
- package/dist/task/Command.js +404 -0
- package/dist/task/Command.js.map +1 -0
- package/dist/task/Group.d.ts +15 -0
- package/dist/task/Group.js +29 -0
- package/dist/task/Group.js.map +1 -0
- package/dist/task/OutputPolicy.d.ts +262 -0
- package/dist/task/OutputPolicy.js +364 -0
- package/dist/task/OutputPolicy.js.map +1 -0
- package/dist/task/Task.d.ts +210 -0
- package/dist/task/Task.js +312 -0
- package/dist/task/Task.js.map +1 -0
- package/package.json +14 -10
- package/.gitignore +0 -7
- package/build/cli/DepFLowCLI.d.ts +0 -16
- package/build/cli/DepFLowCLI.js +0 -254
- package/build/cli/DepFLowCLI.js.map +0 -1
- package/build/cli/bin.js +0 -38
- package/build/cli/bin.js.map +0 -1
- package/build/config/Config.d.ts +0 -28
- package/build/config/Config.js +0 -46
- package/build/config/Config.js.map +0 -1
- package/build/config/ImportMap.d.ts +0 -51
- package/build/config/ImportMap.js +0 -97
- package/build/config/ImportMap.js.map +0 -1
- package/build/config/TSConfig.d.ts +0 -54
- package/build/config/TSConfig.js +0 -104
- package/build/config/TSConfig.js.map +0 -1
- package/build/schema/Config/Builder.js +0 -48
- package/build/schema/Config/Builder.js.map +0 -1
- package/build/schema/Config/Config.js +0 -20
- package/build/schema/Config/Config.js.map +0 -1
- package/build/schema/Config/Dependency.js +0 -25
- package/build/schema/Config/Dependency.js.map +0 -1
- package/build/schema/Config/Extractor.js +0 -25
- package/build/schema/Config/Extractor.js.map +0 -1
- package/build/schema/Config/Resolver.js +0 -25
- package/build/schema/Config/Resolver.js.map +0 -1
- package/build/schema/Config/Transform.js +0 -27
- package/build/schema/Config/Transform.js.map +0 -1
- package/build/schema/ImportMap.d.ts +0 -22
- package/build/schema/ImportMap.js +0 -12
- package/build/schema/ImportMap.js.map +0 -1
- package/build/schema/TSConfig.js +0 -19
- package/build/schema/TSConfig.js.map +0 -1
- package/build/schema/schema.js.map +0 -1
- package/build/support/Builder/Builder.d.ts +0 -46
- package/build/support/Builder/Builder.js +0 -116
- package/build/support/Builder/Builder.js.map +0 -1
- package/build/support/Dependency/Dependency.d.ts +0 -38
- package/build/support/Dependency/Dependency.js +0 -14
- package/build/support/Dependency/Dependency.js.map +0 -1
- package/build/support/Dependency/GitDependency.d.ts +0 -20
- package/build/support/Dependency/GitDependency.js +0 -67
- package/build/support/Dependency/GitDependency.js.map +0 -1
- package/build/support/Dependency/NpmDependency.d.ts +0 -18
- package/build/support/Dependency/NpmDependency.js +0 -65
- package/build/support/Dependency/NpmDependency.js.map +0 -1
- package/build/support/Git.d.ts +0 -53
- package/build/support/Git.js +0 -86
- package/build/support/Git.js.map +0 -1
- package/build/support/PathResolver/AliasCompiler.js.map +0 -1
- package/build/support/PathResolver/PathResolver.js +0 -105
- package/build/support/PathResolver/PathResolver.js.map +0 -1
- package/build/support/PathResolver/PathRewriter.d.ts +0 -18
- package/build/support/PathResolver/PathRewriter.js.map +0 -1
- package/build/support/PathResolver/Utils.d.ts +0 -36
- package/build/support/PathResolver/Utils.js +0 -45
- package/build/support/PathResolver/Utils.js.map +0 -1
- package/build/support/Task/Command.d.ts +0 -49
- package/build/support/Task/Command.js +0 -100
- package/build/support/Task/Command.js.map +0 -1
- package/build/support/Task/Task.d.ts +0 -84
- package/build/support/Task/Task.js +0 -145
- package/build/support/Task/Task.js.map +0 -1
- package/build/support/Utils.d.ts +0 -40
- package/build/support/Utils.js +0 -138
- package/build/support/Utils.js.map +0 -1
- package/build/support/Validator.d.ts +0 -22
- package/build/support/Validator.js +0 -28
- package/build/support/Validator.js.map +0 -1
- /package/{build → dist}/cli/bin.d.ts +0 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Runs one instruction, as a script in a shared shell or as its own process, streaming its
|
|
4
|
+
* output and settling exactly one verdict for it.
|
|
5
|
+
* @license Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { Events } from "@netfeez/common";
|
|
9
|
+
export class Command extends Events {
|
|
10
|
+
/**
|
|
11
|
+
* Monotonic source of the markers written into the shell, so two commands executed in the same
|
|
12
|
+
* millisecond can never share one, and a marker can never be replayed by a later command.
|
|
13
|
+
*/
|
|
14
|
+
static vToken = 0;
|
|
15
|
+
/**
|
|
16
|
+
* The shells already read by a command, so the reader of a shell shared by the instructions of a
|
|
17
|
+
* task is attached once instead of once per instruction.
|
|
18
|
+
*/
|
|
19
|
+
static vShells = new WeakMap();
|
|
20
|
+
mode;
|
|
21
|
+
shell;
|
|
22
|
+
script;
|
|
23
|
+
program;
|
|
24
|
+
/** The sentinel the shell writes once the instruction finished, carrying its exit status. */
|
|
25
|
+
marker;
|
|
26
|
+
child = null;
|
|
27
|
+
settled = false;
|
|
28
|
+
startedAt = 0;
|
|
29
|
+
output = '';
|
|
30
|
+
errors = '';
|
|
31
|
+
outputCursor = 0;
|
|
32
|
+
errorsCursor = 0;
|
|
33
|
+
vOrdinal;
|
|
34
|
+
constructor(mode, options) {
|
|
35
|
+
super();
|
|
36
|
+
this.mode = mode;
|
|
37
|
+
this.shell = options.shell ?? null;
|
|
38
|
+
this.script = options.script ?? '';
|
|
39
|
+
this.program = options.program ?? { executable: '', args: [] };
|
|
40
|
+
this.marker = Command.token();
|
|
41
|
+
this.vOrdinal = options.ordinal ?? 1;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Creates a command that runs a script in an already running shell.
|
|
45
|
+
* @param shell - The shell the script is written to, or `null` when the shell of the task is gone.
|
|
46
|
+
* @param script - The shell script to run.
|
|
47
|
+
* @returns The command, not yet started.
|
|
48
|
+
*
|
|
49
|
+
* @remarks The shell is not owned by the command: it outlives it, so the death of a command is
|
|
50
|
+
* never the death of the shell, and a shell that dies is reported by the task that owns it. A
|
|
51
|
+
* command with no shell fails as soon as it runs, instead of waiting for output that can never
|
|
52
|
+
* come.
|
|
53
|
+
*
|
|
54
|
+
* @remarks The ordinal travels with every line the command emits, so the task never has to invent
|
|
55
|
+
* which of its instructions a line belongs to.
|
|
56
|
+
*
|
|
57
|
+
* @param ordinal - The position of the instruction inside its task, starting at 1.
|
|
58
|
+
*/
|
|
59
|
+
static inShell(shell, script, ordinal = 1) {
|
|
60
|
+
return new Command('shell', { shell: shell ?? undefined, script, ordinal });
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Creates a command that runs a program in a process of its own, where nothing in the arguments
|
|
64
|
+
* nor in the working directory can be reinterpreted by a shell.
|
|
65
|
+
* @param program - The program to run.
|
|
66
|
+
* @param ordinal - The position of the instruction inside its task, starting at 1.
|
|
67
|
+
* @returns The command, not yet started.
|
|
68
|
+
*/
|
|
69
|
+
static asProgram(program, ordinal = 1) {
|
|
70
|
+
return new Command('program', { program, ordinal });
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Creates a shell for running scripts, started in the given working directory.
|
|
74
|
+
* @param cwd - The working directory the shell is started in, so a script never needs to `cd` into
|
|
75
|
+
* the folder the task belongs to reach it.
|
|
76
|
+
* @returns The shell process.
|
|
77
|
+
*
|
|
78
|
+
* @remarks The shell leads its own process group where the platform allows it, so the task owning
|
|
79
|
+
* it can take down the whole tree of processes a script left behind. It holds the event loop while
|
|
80
|
+
* the task runs, and the task releases it when it is done, so a task in flight is never cut short.
|
|
81
|
+
*
|
|
82
|
+
* @remarks The arguments of the shell are its own, never a string to be interpreted: `cmd.exe` is
|
|
83
|
+
* started quiet (`/Q`) and without the autorun registry entries (`/D`), so it neither greets itself
|
|
84
|
+
* nor echoes the orders it is given. The greeting a shell still writes is dropped by
|
|
85
|
+
* {@link Command.prepare}.
|
|
86
|
+
*/
|
|
87
|
+
static createShell(cwd) {
|
|
88
|
+
const isWin = process.platform === 'win32';
|
|
89
|
+
return spawn(isWin ? 'cmd.exe' : 'bash', isWin ? ['/Q', '/D'] : [], {
|
|
90
|
+
shell: false,
|
|
91
|
+
cwd,
|
|
92
|
+
detached: !isWin,
|
|
93
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Silences a shell and waits until it answers, so nothing the shell says about itself is ever read as
|
|
98
|
+
* the output of an instruction.
|
|
99
|
+
* @param shell - The shell to prepare, the one {@link Command.createShell} started.
|
|
100
|
+
* @returns A promise resolving once the shell reported itself ready, or once it is gone.
|
|
101
|
+
*
|
|
102
|
+
* @remarks A shell reading its orders from a pipe narrates them: `cmd.exe` writes its banner and its
|
|
103
|
+
* prompt to stdout before and after every order, and both belong to the shell, not to the
|
|
104
|
+
* instruction that follows. The prompt is reduced to a blank line, and everything the shell wrote
|
|
105
|
+
* before the first instruction took it over is dropped by {@link Command.reader}, so the first
|
|
106
|
+
* instruction starts from a shell that only speaks when spoken to. A shell that is already gone
|
|
107
|
+
* resolves too: the instruction is the one that reports it, not this handshake.
|
|
108
|
+
*
|
|
109
|
+
* The handshake ends on the readiness marker or on the death of the shell, never on the orders
|
|
110
|
+
* having been written: a write that succeeded says nothing about what the shell already said.
|
|
111
|
+
*/
|
|
112
|
+
static prepare(shell) {
|
|
113
|
+
const state = Command.reader(shell);
|
|
114
|
+
if (state.ready)
|
|
115
|
+
return Promise.resolve();
|
|
116
|
+
const marker = Command.token();
|
|
117
|
+
return new Promise((resolve) => {
|
|
118
|
+
const onGone = () => {
|
|
119
|
+
if (state.ready)
|
|
120
|
+
return;
|
|
121
|
+
shell.off('exit', onGone);
|
|
122
|
+
shell.off('error', onGone);
|
|
123
|
+
shell.stdin.off('error', onGone);
|
|
124
|
+
state.probe = null;
|
|
125
|
+
state.ready = true;
|
|
126
|
+
resolve();
|
|
127
|
+
};
|
|
128
|
+
const onWritten = (error) => { if (error)
|
|
129
|
+
onGone(); };
|
|
130
|
+
state.probe = (text) => { if (text.includes(`${marker}=1`))
|
|
131
|
+
onGone(); };
|
|
132
|
+
shell.once('exit', onGone);
|
|
133
|
+
shell.once('error', onGone);
|
|
134
|
+
shell.stdin.on('error', onGone);
|
|
135
|
+
shell.stdin.write(`${Command.warmup(marker)}\n`, onWritten);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The single reader of a shell, attached the first time anything reads it and kept for its whole life.
|
|
140
|
+
* @param shell - The shell to read.
|
|
141
|
+
* @returns The state of the reader, holding whoever is reading the shell right now.
|
|
142
|
+
*
|
|
143
|
+
* @remarks A shell is read through one pair of listeners for its whole life, and what it produced goes
|
|
144
|
+
* to the command reading it, or to nobody while the shell is only talking to itself. The handover is
|
|
145
|
+
* therefore a single assignment, which nothing can slip into: a reader attached to the shell by one
|
|
146
|
+
* instruction and detached by the next leaves a window in which the trailing prompt of the shell is
|
|
147
|
+
* read as the output of the instruction that follows it.
|
|
148
|
+
**/
|
|
149
|
+
static reader(shell) {
|
|
150
|
+
const existing = Command.vShells.get(shell);
|
|
151
|
+
if (existing)
|
|
152
|
+
return existing;
|
|
153
|
+
const state = { reader: null, probe: null, ready: false };
|
|
154
|
+
shell.stdout.on('data', (data) => {
|
|
155
|
+
if (state.reader)
|
|
156
|
+
state.reader.onStdout(data);
|
|
157
|
+
else
|
|
158
|
+
state.probe?.(data.toString());
|
|
159
|
+
});
|
|
160
|
+
shell.stderr.on('data', (data) => { state.reader?.onStderr(data); });
|
|
161
|
+
Command.vShells.set(shell, state);
|
|
162
|
+
return state;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Takes down a process and every process it started.
|
|
166
|
+
* @param child - The process to take down.
|
|
167
|
+
* @returns void
|
|
168
|
+
**/
|
|
169
|
+
static terminate(child) {
|
|
170
|
+
try {
|
|
171
|
+
if (process.platform === 'win32' || !child.pid)
|
|
172
|
+
child.kill('SIGKILL');
|
|
173
|
+
else
|
|
174
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
175
|
+
}
|
|
176
|
+
catch { }
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The human readable form of a program, used to describe it when it fails.
|
|
180
|
+
* @param program - The program to format.
|
|
181
|
+
* @returns The program followed by its arguments.
|
|
182
|
+
**/
|
|
183
|
+
static format(program) {
|
|
184
|
+
return [program.executable, ...(program.args ?? [])].join(' ');
|
|
185
|
+
}
|
|
186
|
+
/** The human readable form of this instruction, used to describe it when it fails. **/
|
|
187
|
+
get label() {
|
|
188
|
+
return this.mode === 'shell' ? this.script : Command.format(this.program);
|
|
189
|
+
}
|
|
190
|
+
/** The position of this instruction inside its task, starting at 1, carried by every line it emits. **/
|
|
191
|
+
get ordinal() {
|
|
192
|
+
return this.vOrdinal;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Starts the command, emitting a `log` event per stdout line, an `err` event per stderr line and
|
|
196
|
+
* a single `end` event carrying the verdict.
|
|
197
|
+
* @returns void
|
|
198
|
+
*
|
|
199
|
+
* @remarks The verdict is settled exactly once: on the status line the shell writes, on the exit
|
|
200
|
+
* of the process, on a spawn failure, or when the command is killed.
|
|
201
|
+
*/
|
|
202
|
+
exec() {
|
|
203
|
+
if (this.settled)
|
|
204
|
+
return;
|
|
205
|
+
this.startedAt = Date.now();
|
|
206
|
+
if (this.mode === 'shell')
|
|
207
|
+
this.execInShell();
|
|
208
|
+
else
|
|
209
|
+
this.execAsProgram();
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Takes the command down, carrying why into its verdict.
|
|
213
|
+
* @param reason - Why the command is being killed, carried into its verdict.
|
|
214
|
+
* @returns void
|
|
215
|
+
*
|
|
216
|
+
* @remarks A program is taken down along with every process it started. A script cannot be: it
|
|
217
|
+
* shares the shell with the rest of the task, so the task that owns the shell is the one that takes
|
|
218
|
+
* the shell down when the run ends.
|
|
219
|
+
*/
|
|
220
|
+
kill(reason = 'stopped') {
|
|
221
|
+
if (this.child)
|
|
222
|
+
Command.terminate(this.child);
|
|
223
|
+
this.settle({ code: null, signal: null, reason });
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Runs the script in the shell, followed by the sentinel that carries its exit status.
|
|
227
|
+
* @returns void
|
|
228
|
+
**/
|
|
229
|
+
execInShell() {
|
|
230
|
+
if (!this.shell)
|
|
231
|
+
return void this.settle({ code: null, signal: null, reason: 'shell' });
|
|
232
|
+
if (this.shell.exitCode !== null || this.shell.signalCode !== null)
|
|
233
|
+
return void this.settle({ code: null, signal: null, reason: 'shell' });
|
|
234
|
+
Command.reader(this.shell).reader = this;
|
|
235
|
+
this.shell.stdin.on('error', this.onStdinError);
|
|
236
|
+
try {
|
|
237
|
+
this.shell.stdin.write(`${this.script}\n${Command.sentinel(this.marker)}\n`);
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
this.settle({ code: null, signal: null, reason: 'shell' });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Runs the program in a process of its own, started in its own working directory.
|
|
245
|
+
* @returns void
|
|
246
|
+
**/
|
|
247
|
+
execAsProgram() {
|
|
248
|
+
this.child = spawn(this.program.executable, this.program.args ?? [], {
|
|
249
|
+
shell: false,
|
|
250
|
+
cwd: this.program.cwd,
|
|
251
|
+
detached: process.platform !== 'win32',
|
|
252
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
253
|
+
});
|
|
254
|
+
this.child.stdout.on('data', this.onStdout);
|
|
255
|
+
this.child.stderr.on('data', this.onStderr);
|
|
256
|
+
this.child.once('error', () => this.settle({ code: null, signal: null, reason: 'spawn' }));
|
|
257
|
+
this.child.once('close', (code, signal) => this.settle({ code, signal, reason: null }));
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Consumes a stdout chunk, emitting the lines it closes, and stops at the sentinel when the
|
|
261
|
+
* command is a script.
|
|
262
|
+
* @param data - The raw chunk written to stdout.
|
|
263
|
+
* @returns void
|
|
264
|
+
**/
|
|
265
|
+
onStdout = (data) => {
|
|
266
|
+
const chunk = data.toString();
|
|
267
|
+
this.output += chunk;
|
|
268
|
+
if (this.mode === 'shell' && !this.settled) {
|
|
269
|
+
const status = this.sentinel(this.output);
|
|
270
|
+
if (status !== null) {
|
|
271
|
+
this.output = this.output.slice(0, status.index);
|
|
272
|
+
this.stream(true);
|
|
273
|
+
this.settle(status.code === null ? { code: null, signal: null, reason: 'protocol' } : { code: status.code, signal: null, reason: null });
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
this.stream();
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* The status line the shell wrote, as the index it starts at and the exit status it carries.
|
|
281
|
+
* @param output - The output collected so far.
|
|
282
|
+
* @returns The status, `null` when the line is not there yet, or a null code when it carries none.
|
|
283
|
+
*
|
|
284
|
+
* @remarks Only a whole line that is the sentinel counts, and the sentinel carries a random
|
|
285
|
+
* suffix, so nothing an instruction prints can stand for the shell reporting its status.
|
|
286
|
+
**/
|
|
287
|
+
sentinel(output) {
|
|
288
|
+
const match = output.match(new RegExp(`(?:^|\n)(${this.marker})=([^\\n]*)\\n`));
|
|
289
|
+
if (!match || match.index === undefined)
|
|
290
|
+
return null;
|
|
291
|
+
const code = Number(match[2]);
|
|
292
|
+
return {
|
|
293
|
+
index: match.index + (match[0].startsWith('\n') ? 1 : 0),
|
|
294
|
+
code: Number.isInteger(code) ? code : null
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Consumes a stderr chunk, emitting the lines it closes.
|
|
299
|
+
* @param data - The raw chunk written to stderr.
|
|
300
|
+
* @returns void
|
|
301
|
+
**/
|
|
302
|
+
onStderr = (data) => {
|
|
303
|
+
this.errors += data.toString();
|
|
304
|
+
this.stream();
|
|
305
|
+
};
|
|
306
|
+
/**
|
|
307
|
+
* Absorbs the failure of writing into a shell that is already gone, which is how a sentinel that
|
|
308
|
+
* will never arrive announces itself.
|
|
309
|
+
* @returns void
|
|
310
|
+
**/
|
|
311
|
+
onStdinError = () => {
|
|
312
|
+
this.settle({ code: null, signal: null, reason: 'shell' });
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* Emits the lines both streams have closed since the last call.
|
|
316
|
+
* @param final - Whether the remaining partial line is emitted too, as nothing else will come.
|
|
317
|
+
* @returns void
|
|
318
|
+
**/
|
|
319
|
+
stream(final = false) {
|
|
320
|
+
this.outputCursor = this.emitLines(this.output, this.outputCursor, 'log', final);
|
|
321
|
+
this.errorsCursor = this.emitLines(this.errors, this.errorsCursor, 'err', final);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Emits the complete lines a buffer holds from a given cursor, each carrying the ordinal of the
|
|
325
|
+
* instruction it belongs to.
|
|
326
|
+
* @param buffer - The accumulated output of the stream.
|
|
327
|
+
* @param cursor - Where the previous call stopped.
|
|
328
|
+
* @param event - The event each line is emitted with.
|
|
329
|
+
* @param final - Whether the trailing partial line is emitted as well.
|
|
330
|
+
* @returns The position the cursor reached.
|
|
331
|
+
**/
|
|
332
|
+
emitLines(buffer, cursor, event, final) {
|
|
333
|
+
const end = final ? buffer.length : buffer.lastIndexOf('\n') + 1;
|
|
334
|
+
if (end <= cursor)
|
|
335
|
+
return cursor;
|
|
336
|
+
for (const line of buffer.slice(cursor, end).split('\n')) {
|
|
337
|
+
const text = line.trim();
|
|
338
|
+
if (text)
|
|
339
|
+
this.emit(event, text, this.vOrdinal);
|
|
340
|
+
}
|
|
341
|
+
return end;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Settles the verdict of the command, exactly once, detaching every listener it attached.
|
|
345
|
+
* @param outcome - The status, signal and reason the command ended with.
|
|
346
|
+
* @returns void
|
|
347
|
+
**/
|
|
348
|
+
settle(outcome) {
|
|
349
|
+
if (this.settled)
|
|
350
|
+
return;
|
|
351
|
+
this.settled = true;
|
|
352
|
+
if (this.shell) {
|
|
353
|
+
if (Command.reader(this.shell).reader === this)
|
|
354
|
+
Command.reader(this.shell).reader = null;
|
|
355
|
+
this.shell.stdin.off('error', this.onStdinError);
|
|
356
|
+
}
|
|
357
|
+
this.child?.stdout?.off('data', this.onStdout);
|
|
358
|
+
this.child?.stderr?.off('data', this.onStderr);
|
|
359
|
+
this.stream(true);
|
|
360
|
+
this.emit('end', {
|
|
361
|
+
code: outcome.code,
|
|
362
|
+
signal: outcome.signal,
|
|
363
|
+
reason: outcome.reason,
|
|
364
|
+
output: this.output.trim(),
|
|
365
|
+
error: this.errors.trim(),
|
|
366
|
+
time: Date.now() - this.startedAt
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* The line the shell writes once the previous instruction finished, in its own dialect.
|
|
371
|
+
* @param marker - The sentinel of the command.
|
|
372
|
+
* @returns The line carrying the exit status of the instruction.
|
|
373
|
+
**/
|
|
374
|
+
static sentinel(marker) {
|
|
375
|
+
return process.platform === 'win32'
|
|
376
|
+
? `echo ${marker}=%errorlevel%`
|
|
377
|
+
: `printf '${marker}=%d\\n' "$?"`;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* The orders that turn a fresh shell into one that only reports what an instruction produced.
|
|
381
|
+
* @param marker - The readiness marker of this shell.
|
|
382
|
+
* @returns The lines, in the dialect of the shell.
|
|
383
|
+
*
|
|
384
|
+
* @remarks `cmd.exe` greets itself with a banner and a prompt, and echoes every order it is given;
|
|
385
|
+
* `/Q` already silences the echo, and reducing the prompt to a newline leaves nothing else the
|
|
386
|
+
* reader of an instruction has to tell apart from its output. `bash` reading from a pipe is quiet on
|
|
387
|
+
* its own, so it only has to say it is ready.
|
|
388
|
+
**/
|
|
389
|
+
static warmup(marker) {
|
|
390
|
+
return process.platform === 'win32' ? `prompt $_\necho ${marker}=1` : `echo ${marker}=1`;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* A marker no other order of this process can carry, taken from a monotonic counter.
|
|
394
|
+
* @returns The marker of the next order written into a shell.
|
|
395
|
+
*
|
|
396
|
+
* @remarks The random suffix keeps a marker from being replayed by an instruction that happens to
|
|
397
|
+
* print it, and the counter keeps two orders written in the same millisecond from sharing one.
|
|
398
|
+
**/
|
|
399
|
+
static token() {
|
|
400
|
+
return `DEP_FLOW_${++Command.vToken}_${Math.random().toString(36).slice(2, 10)}`;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
export default Command;
|
|
404
|
+
//# sourceMappingURL=Command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Command.js","sourceRoot":"","sources":["../../src/task/Command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Colored group template factory for the grouper of @netfeez/vterm.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Grouper } from '@netfeez/vterm';
|
|
7
|
+
export declare namespace Group {
|
|
8
|
+
/**
|
|
9
|
+
* Builds a colored group template for the grouper of @netfeez/vterm.
|
|
10
|
+
* @param color - A hex color (`#RRGGBB`) or a vterm color index (1-7).
|
|
11
|
+
* @returns The group template with open, item, line and stop symbols.
|
|
12
|
+
*/
|
|
13
|
+
function create(color: `#${string}` | number): Grouper.GroupTemplate;
|
|
14
|
+
}
|
|
15
|
+
export default Group;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>.
|
|
3
|
+
* @description Colored group template factory for the grouper of @netfeez/vterm.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export var Group;
|
|
7
|
+
(function (Group) {
|
|
8
|
+
/**
|
|
9
|
+
* Builds a colored group template for the grouper of @netfeez/vterm.
|
|
10
|
+
* @param color - A hex color (`#RRGGBB`) or a vterm color index (1-7).
|
|
11
|
+
* @returns The group template with open, item, line and stop symbols.
|
|
12
|
+
*/
|
|
13
|
+
function create(color) {
|
|
14
|
+
let code = '';
|
|
15
|
+
if (typeof color === 'number') {
|
|
16
|
+
code = color >= 1 && color <= 7 ? `C${color}` : 'R';
|
|
17
|
+
}
|
|
18
|
+
else if (typeof color === 'string' && /^#([0-9A-Fa-f]{6})$/.test(color)) {
|
|
19
|
+
code = `C(${color})`;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
code = 'R';
|
|
23
|
+
}
|
|
24
|
+
return { open: `&N&${code}╭─`, item: `&N&${code}│ `, line: `&N&${code}├─`, stop: `&N&${code}╰─` };
|
|
25
|
+
}
|
|
26
|
+
Group.create = create;
|
|
27
|
+
})(Group || (Group = {}));
|
|
28
|
+
export default Group;
|
|
29
|
+
//# sourceMappingURL=Group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Group.js","sourceRoot":"","sources":["../../src/task/Group.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,KAAW,KAAK,CAerB;AAfD,WAAiB,KAAK;IAClB;;;;OAIG;IACH,SAAgB,MAAM,CAAC,KAA4B;QAC/C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACxD,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACxE,IAAI,GAAG,KAAK,KAAK,GAAG,CAAC;QACzB,CAAC;aAAM,CAAC;YAAC,IAAI,GAAG,GAAG,CAAC;QAAC,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC;IACtG,CAAC;IARe,MAAA,MAAM,SAQrB,CAAA;AACL,CAAC,EAfgB,KAAK,KAAL,KAAK,QAerB;AAED,eAAe,KAAK,CAAC"}
|