reslop 0.2.5 → 0.2.7
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/CHANGELOG.md +22 -1
- package/LICENSE +1 -1
- package/README.md +11 -11
- package/bin/reslop.js +3 -8
- package/lib/ansi.js +72 -19
- package/lib/api.js +1 -1
- package/lib/capabilities.js +8 -8
- package/lib/cli.js +61 -75
- package/lib/clipboard.js +39 -47
- package/lib/dashboard/git.js +128 -0
- package/lib/dashboard/model.js +357 -0
- package/lib/dashboard/npm.js +290 -0
- package/lib/dashboard/tree.js +278 -0
- package/lib/deps-diff.js +197 -402
- package/lib/deps.js +113 -240
- package/lib/detect.js +8 -18
- package/lib/diff/align.js +41 -113
- package/lib/diff/diff.js +12 -43
- package/lib/diff/display.js +25 -36
- package/lib/diff/edit.js +6 -20
- package/lib/diff/inline.js +76 -144
- package/lib/diff/items.js +33 -47
- package/lib/diff/parse.js +28 -56
- package/lib/diff/patch.js +12 -33
- package/lib/diff/unit.js +79 -178
- package/lib/editor.js +52 -69
- package/lib/files.js +79 -91
- package/lib/find.js +61 -0
- package/lib/git-branches.js +254 -416
- package/lib/git-deps.js +148 -272
- package/lib/git-reword-todo.js +5 -13
- package/lib/git-worktree.js +161 -214
- package/lib/git.js +21 -49
- package/lib/github.js +67 -181
- package/lib/gitlab.js +40 -90
- package/lib/highlight/bash.js +55 -177
- package/lib/highlight/core.js +155 -141
- package/lib/highlight/css.js +25 -58
- package/lib/highlight/csv.js +19 -37
- package/lib/highlight/dart.js +72 -213
- package/lib/highlight/dot.js +14 -14
- package/lib/highlight/html.js +42 -63
- package/lib/highlight/js.js +177 -506
- package/lib/highlight/json.js +17 -37
- package/lib/highlight/log.js +19 -25
- package/lib/highlight/txt.js +7 -10
- package/lib/highlight.js +17 -46
- package/lib/keys.js +75 -83
- package/lib/manifest.js +67 -126
- package/lib/npm-commands.js +120 -169
- package/lib/remote.js +140 -190
- package/lib/render/branches.js +63 -61
- package/lib/render/chrome.js +412 -347
- package/lib/render/commits.js +160 -361
- package/lib/render/dash-activity.js +212 -0
- package/lib/render/dash-blocks.js +496 -0
- package/lib/render/dash-table.js +295 -0
- package/lib/render/dashboard.js +62 -0
- package/lib/render/diff.js +123 -258
- package/lib/render/files.js +60 -86
- package/lib/render/frame.js +82 -117
- package/lib/render/notes.js +150 -210
- package/lib/render/npm.js +213 -177
- package/lib/render/packages.js +93 -0
- package/lib/render/present.js +4 -11
- package/lib/render/primitives.js +77 -172
- package/lib/render/render.js +5 -14
- package/lib/render/report.js +43 -0
- package/lib/render/repos.js +226 -0
- package/lib/render/search.js +25 -0
- package/lib/render/tiles.js +355 -0
- package/lib/render/unit.js +15 -31
- package/lib/report-model.js +110 -33
- package/lib/report-parse.js +56 -37
- package/lib/report-render.js +102 -59
- package/lib/report-run.js +87 -77
- package/lib/report-test.js +221 -99
- package/lib/report-tools.js +96 -154
- package/lib/review-merge.js +33 -41
- package/lib/review.js +69 -129
- package/lib/runs.js +225 -0
- package/lib/select.js +53 -91
- package/lib/session/accessors.js +14 -21
- package/lib/session/actions.js +189 -65
- package/lib/session/branches.js +164 -222
- package/lib/session/change-actions.js +49 -119
- package/lib/session/commit.js +298 -352
- package/lib/session/compose.js +572 -715
- package/lib/session/dashboard.js +530 -0
- package/lib/session/dispatch.js +197 -171
- package/lib/session/files-pane.js +92 -45
- package/lib/session/find.js +94 -0
- package/lib/session/items.js +6 -17
- package/lib/session/lifecycle.js +420 -466
- package/lib/session/load.js +1 -14
- package/lib/session/navigation.js +4 -2
- package/lib/session/npm.js +403 -420
- package/lib/session/ops.js +5 -13
- package/lib/session/packages.js +143 -0
- package/lib/session/pointer.js +30 -14
- package/lib/session/progress.js +39 -30
- package/lib/session/review.js +1 -3
- package/lib/session/tasks.js +277 -236
- package/lib/session/templates.js +51 -59
- package/lib/session/terminal.js +85 -132
- package/lib/session/view.js +59 -80
- package/lib/session/watch.js +201 -212
- package/lib/session/workspace.js +455 -0
- package/lib/session.js +95 -161
- package/lib/update.js +44 -111
- package/lib/utilities.js +46 -88
- package/lib/workspace.js +166 -0
- package/lib/wrap.js +29 -55
- package/package.json +1 -1
package/lib/npm-commands.js
CHANGED
|
@@ -36,7 +36,7 @@ const writeManifest = (root, pkg) => {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
const scriptEntries = (pkg) => {
|
|
39
|
-
const scripts = pkg
|
|
39
|
+
const scripts = pkg.scripts;
|
|
40
40
|
if (!scripts || typeof scripts !== 'object') return [];
|
|
41
41
|
const entries = [];
|
|
42
42
|
for (const name of Object.keys(scripts)) {
|
|
@@ -56,11 +56,8 @@ const binNames = (pkg) => {
|
|
|
56
56
|
return base ? [base] : [];
|
|
57
57
|
}
|
|
58
58
|
if (!bin || typeof bin !== 'object' || Array.isArray(bin)) return [];
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
if (typeof bin[name] === 'string' && bin[name]) names.push(name);
|
|
62
|
-
}
|
|
63
|
-
return names;
|
|
59
|
+
const isPath = (name) => typeof bin[name] === 'string' && bin[name] !== '';
|
|
60
|
+
return Object.keys(bin).filter(isPath);
|
|
64
61
|
};
|
|
65
62
|
|
|
66
63
|
const declaredNames = (pkg) => {
|
|
@@ -68,7 +65,7 @@ const declaredNames = (pkg) => {
|
|
|
68
65
|
for (const section of SECTIONS) {
|
|
69
66
|
const map = pkg[section];
|
|
70
67
|
if (!map || typeof map !== 'object') continue;
|
|
71
|
-
|
|
68
|
+
names.push(...Object.keys(map));
|
|
72
69
|
}
|
|
73
70
|
return names;
|
|
74
71
|
};
|
|
@@ -107,25 +104,50 @@ const isPassingTest = (line) => {
|
|
|
107
104
|
if (!text) return false;
|
|
108
105
|
if (/^\s*[✔✓√] /.test(plain)) return true;
|
|
109
106
|
if (/^ok \d+ /.test(text)) return true;
|
|
110
|
-
|
|
111
|
-
return false;
|
|
107
|
+
return /^\s*PASS\b/.test(plain);
|
|
112
108
|
};
|
|
113
109
|
|
|
114
|
-
const isNodeFrame = (line) => stripAnsi(line).includes('(node:');
|
|
115
|
-
|
|
116
110
|
const indentStack = (line) => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const lead = line.match(/^\s*/)?.[0] ?? '';
|
|
120
|
-
const body = lead ? line.slice(lead.length) : line;
|
|
121
|
-
return ` ${body}`;
|
|
111
|
+
if (!/^\s*at\s/.test(stripAnsi(line))) return line;
|
|
112
|
+
return ` ${line.trimStart()}`;
|
|
122
113
|
};
|
|
123
114
|
|
|
124
115
|
const withoutNodeFrame = (line) => {
|
|
125
|
-
if (!isNodeFrame(line)) return line;
|
|
126
116
|
const plain = stripAnsi(line);
|
|
127
|
-
if (
|
|
128
|
-
return null;
|
|
117
|
+
if (!plain.includes('(node:')) return line;
|
|
118
|
+
return /\{\s*$/.test(plain) ? '{' : null;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const withSep = (dir) => {
|
|
122
|
+
const sep = dir.includes('\\') ? '\\' : '/';
|
|
123
|
+
if (dir.endsWith(sep)) return dir;
|
|
124
|
+
return `${dir}${sep}`;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const stripOne = (text, dir) => {
|
|
128
|
+
if (!dir) return text;
|
|
129
|
+
let next = text.split(withSep(dir)).join('');
|
|
130
|
+
if (next.includes(dir)) next = next.split(dir).join('.');
|
|
131
|
+
return next;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const relativize = (text, root) => {
|
|
135
|
+
if (!root) return text;
|
|
136
|
+
const slash = root.replaceAll('\\', '/');
|
|
137
|
+
const back = slash.replaceAll('/', '\\');
|
|
138
|
+
const resolved = path.resolve(root).replaceAll('\\', '/');
|
|
139
|
+
const resolvedBack = resolved.replaceAll('/', '\\');
|
|
140
|
+
let next = text;
|
|
141
|
+
for (const dir of [slash, back, resolved, resolvedBack]) {
|
|
142
|
+
next = stripOne(next, dir);
|
|
143
|
+
}
|
|
144
|
+
return next;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const traceLine = (line, root) => {
|
|
148
|
+
const next = withoutNodeFrame(line);
|
|
149
|
+
if (next === null) return null;
|
|
150
|
+
return relativize(indentStack(next), root);
|
|
129
151
|
};
|
|
130
152
|
|
|
131
153
|
const objectEnd = (lines, start) => {
|
|
@@ -162,19 +184,18 @@ const showValue = (value) => {
|
|
|
162
184
|
};
|
|
163
185
|
|
|
164
186
|
const parseObject = (lines) => {
|
|
165
|
-
const body = lines.slice(1, -1);
|
|
166
187
|
try {
|
|
167
188
|
const value = JSON.parse(lines.join('\n'));
|
|
168
189
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
169
190
|
return null;
|
|
170
191
|
}
|
|
171
|
-
const entries = [
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
192
|
+
const entries = Object.keys(value).map((key) => [
|
|
193
|
+
key,
|
|
194
|
+
showValue(value[key]),
|
|
195
|
+
]);
|
|
175
196
|
return entries.length ? entries : null;
|
|
176
197
|
} catch {
|
|
177
|
-
return parseInspect(
|
|
198
|
+
return parseInspect(lines.slice(1, -1));
|
|
178
199
|
}
|
|
179
200
|
};
|
|
180
201
|
|
|
@@ -182,18 +203,22 @@ const TABLE_KEY = '\x1b[900m';
|
|
|
182
203
|
const TABLE_VAL = '\x1b[901m';
|
|
183
204
|
|
|
184
205
|
const formatTable = (entries) => {
|
|
185
|
-
|
|
206
|
+
const prepared = [];
|
|
207
|
+
let keyWidth = 0;
|
|
186
208
|
for (const entry of entries) {
|
|
187
|
-
|
|
209
|
+
const lines = `${entry[1]}`.split('\n').filter((line) => line.trim());
|
|
210
|
+
if (!lines.length) continue;
|
|
211
|
+
prepared.push([entry[0], lines]);
|
|
212
|
+
keyWidth = Math.max(keyWidth, visibleWidth(entry[0]));
|
|
188
213
|
}
|
|
189
214
|
const rows = [];
|
|
190
|
-
for (const entry of
|
|
191
|
-
const
|
|
192
|
-
for (let i = 0; i <
|
|
215
|
+
for (const entry of prepared) {
|
|
216
|
+
const lines = entry[1];
|
|
217
|
+
for (let i = 0; i < lines.length; i++) {
|
|
193
218
|
const name = i === 0 ? entry[0] : '';
|
|
194
|
-
const pad = ' '.repeat(Math.max(0,
|
|
219
|
+
const pad = ' '.repeat(Math.max(0, keyWidth - visibleWidth(name)));
|
|
195
220
|
const key = ` ${pad}${name} `;
|
|
196
|
-
const value = ` ${
|
|
221
|
+
const value = ` ${lines[i]} `;
|
|
197
222
|
rows.push(`${TABLE_KEY}${key}${TABLE_VAL} ${value}`);
|
|
198
223
|
}
|
|
199
224
|
}
|
|
@@ -204,67 +229,30 @@ const foldObjects = (lines) => {
|
|
|
204
229
|
const out = [];
|
|
205
230
|
for (let i = 0; i < lines.length; i++) {
|
|
206
231
|
const end = objectEnd(lines, i);
|
|
207
|
-
|
|
208
|
-
out.push(lines[i]);
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
const entries = parseObject(lines.slice(i, end + 1));
|
|
232
|
+
const entries = end < 0 ? null : parseObject(lines.slice(i, end + 1));
|
|
212
233
|
if (!entries) {
|
|
213
234
|
out.push(lines[i]);
|
|
214
235
|
continue;
|
|
215
236
|
}
|
|
216
237
|
if (out.length && out[out.length - 1] !== '') out.push('');
|
|
217
|
-
|
|
238
|
+
out.push(...formatTable(entries));
|
|
218
239
|
i = end;
|
|
219
240
|
}
|
|
220
241
|
return out;
|
|
221
242
|
};
|
|
222
243
|
|
|
223
|
-
const withSep = (dir) => {
|
|
224
|
-
const sep = dir.includes('\\') ? '\\' : '/';
|
|
225
|
-
if (dir.endsWith(sep)) return dir;
|
|
226
|
-
return `${dir}${sep}`;
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
const stripOne = (text, dir) => {
|
|
230
|
-
if (!dir) return text;
|
|
231
|
-
let next = text.split(withSep(dir)).join('');
|
|
232
|
-
if (next.includes(dir)) next = next.split(dir).join('.');
|
|
233
|
-
return next;
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
const relativize = (text, root) => {
|
|
237
|
-
if (!root) return text;
|
|
238
|
-
const slash = root.replaceAll('\\', '/');
|
|
239
|
-
const back = slash.replaceAll('/', '\\');
|
|
240
|
-
const resolved = path.resolve(root).replaceAll('\\', '/');
|
|
241
|
-
const resolvedBack = resolved.replaceAll('/', '\\');
|
|
242
|
-
let next = text;
|
|
243
|
-
for (const dir of [slash, back, resolved, resolvedBack]) {
|
|
244
|
-
next = stripOne(next, dir);
|
|
245
|
-
}
|
|
246
|
-
return next;
|
|
247
|
-
};
|
|
248
|
-
|
|
249
244
|
const reduceOutput = (text, root, status) => {
|
|
250
|
-
const lines = `${text ?? ''}`.split(/\r?\n/);
|
|
251
245
|
const kept = [];
|
|
252
|
-
for (const line of
|
|
246
|
+
for (const line of `${text ?? ''}`.split(/\r?\n/)) {
|
|
253
247
|
if (isPassingTest(line)) continue;
|
|
254
|
-
const next =
|
|
255
|
-
if (next
|
|
256
|
-
kept.push(relativize(indentStack(next), root));
|
|
248
|
+
const next = traceLine(line, root);
|
|
249
|
+
if (next !== null) kept.push(next);
|
|
257
250
|
}
|
|
258
251
|
const folded = foldObjects(kept);
|
|
259
252
|
while (folded.length && folded[folded.length - 1] === '') folded.pop();
|
|
260
|
-
if (status
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
const code = status === undefined || status === null ? 'null' : status;
|
|
265
|
-
const exit = `exit ${code}`;
|
|
266
|
-
if (!folded.length) return `${exit}\n`;
|
|
267
|
-
return `${folded.join('\n')}\n${exit}\n`;
|
|
253
|
+
if (status !== '') folded.push(`exit ${status ?? 'null'}`);
|
|
254
|
+
if (!folded.length) return '';
|
|
255
|
+
return `${folded.join('\n')}\n`;
|
|
268
256
|
};
|
|
269
257
|
|
|
270
258
|
const logFileName = (command, date, index) => {
|
|
@@ -308,10 +296,9 @@ const readLogNames = (dir) => {
|
|
|
308
296
|
|
|
309
297
|
const staleLogFiles = (root, now = new Date()) => {
|
|
310
298
|
const dir = path.join(root, LOG_DIR);
|
|
311
|
-
const names = readLogNames(dir);
|
|
312
299
|
const files = [];
|
|
313
300
|
let bytes = 0;
|
|
314
|
-
for (const name of
|
|
301
|
+
for (const name of readLogNames(dir)) {
|
|
315
302
|
if (!name.endsWith('.log') || !isStaleLog(name, now)) continue;
|
|
316
303
|
const full = path.join(dir, name);
|
|
317
304
|
let stat;
|
|
@@ -334,31 +321,22 @@ const removeStaleLogs = (root, now = new Date()) => {
|
|
|
334
321
|
return found.bytes;
|
|
335
322
|
};
|
|
336
323
|
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const formatSize = (bytes) => {
|
|
343
|
-
const size = bytes > 0 ? bytes : 0;
|
|
344
|
-
if (size < 1024) return `${size}b`;
|
|
345
|
-
const kb = size / 1024;
|
|
346
|
-
if (kb < 1024) return `${scaled(kb)}k`;
|
|
347
|
-
return `${scaled(kb / 1024)}m`;
|
|
324
|
+
const logSlot = (dir, name) => {
|
|
325
|
+
const rawName = name.replace(/\.log$/, '.raw.log');
|
|
326
|
+
const full = path.join(dir, name);
|
|
327
|
+
const rawFull = path.join(dir, rawName);
|
|
328
|
+
return { name, full, dir, rawName, rawFull };
|
|
348
329
|
};
|
|
349
330
|
|
|
350
331
|
const nextLogFile = (root, command, now = new Date()) => {
|
|
351
332
|
const date = dateStamp(now);
|
|
352
333
|
const dir = path.join(root, LOG_DIR);
|
|
353
|
-
let
|
|
354
|
-
let
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
index += 1;
|
|
358
|
-
name = logFileName(command, date, index);
|
|
359
|
-
full = path.join(dir, name);
|
|
334
|
+
let slot = null;
|
|
335
|
+
for (let index = 1; index <= 100; index++) {
|
|
336
|
+
slot = logSlot(dir, logFileName(command, date, index));
|
|
337
|
+
if (!fs.existsSync(slot.full) && !fs.existsSync(slot.rawFull)) break;
|
|
360
338
|
}
|
|
361
|
-
return
|
|
339
|
+
return slot;
|
|
362
340
|
};
|
|
363
341
|
|
|
364
342
|
const logText = (text) =>
|
|
@@ -367,22 +345,12 @@ const logText = (text) =>
|
|
|
367
345
|
.map((line) => line.trimEnd())
|
|
368
346
|
.join('\n');
|
|
369
347
|
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const parseScriptLine = (text) => {
|
|
378
|
-
const raw = `${text ?? ''}`.trim();
|
|
379
|
-
const at = raw.indexOf(': ');
|
|
380
|
-
if (at <= 0) return null;
|
|
381
|
-
const name = raw.slice(0, at).trim();
|
|
382
|
-
const command = raw.slice(at + 2).trim();
|
|
383
|
-
if (!name || !command) return null;
|
|
384
|
-
if (!/^[\w:.-]+$/.test(name)) return null;
|
|
385
|
-
return { name, command };
|
|
348
|
+
const saveLogs = async (slot, reduced, raw) => {
|
|
349
|
+
await fs.promises.mkdir(slot.dir, { recursive: true });
|
|
350
|
+
await Promise.all([
|
|
351
|
+
fs.promises.writeFile(slot.full, logText(reduced)),
|
|
352
|
+
fs.promises.writeFile(slot.rawFull, logText(raw)),
|
|
353
|
+
]);
|
|
386
354
|
};
|
|
387
355
|
|
|
388
356
|
const orderedScripts = (pkg) => {
|
|
@@ -393,47 +361,25 @@ const orderedScripts = (pkg) => {
|
|
|
393
361
|
return scripts;
|
|
394
362
|
};
|
|
395
363
|
|
|
396
|
-
const
|
|
397
|
-
const scripts = orderedScripts(pkg);
|
|
398
|
-
const names = Object.keys(scripts);
|
|
399
|
-
const ordered = {};
|
|
400
|
-
if (prev && names.includes(prev)) {
|
|
401
|
-
for (const key of names) {
|
|
402
|
-
if (key === prev) ordered[next.name] = next.command;
|
|
403
|
-
else if (key !== next.name) ordered[key] = scripts[key];
|
|
404
|
-
}
|
|
405
|
-
} else {
|
|
406
|
-
for (const key of names) ordered[key] = scripts[key];
|
|
407
|
-
ordered[next.name] = next.command;
|
|
408
|
-
}
|
|
409
|
-
pkg.scripts = ordered;
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
const dropScript = (pkg, name) => {
|
|
413
|
-
const scripts = orderedScripts(pkg);
|
|
414
|
-
if (!Object.hasOwn(scripts, name)) return false;
|
|
364
|
+
const pickScripts = (scripts, names) => {
|
|
415
365
|
const ordered = {};
|
|
416
|
-
for (const key of
|
|
417
|
-
|
|
418
|
-
}
|
|
419
|
-
pkg.scripts = ordered;
|
|
420
|
-
return true;
|
|
366
|
+
for (const key of names) ordered[key] = scripts[key];
|
|
367
|
+
return ordered;
|
|
421
368
|
};
|
|
422
369
|
|
|
423
|
-
const
|
|
370
|
+
const upsertScript = (pkg, prev, next) => {
|
|
424
371
|
const scripts = orderedScripts(pkg);
|
|
425
372
|
const names = Object.keys(scripts);
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const swap = names[at];
|
|
431
|
-
names[at] = names[next];
|
|
432
|
-
names[next] = swap;
|
|
373
|
+
if (!prev || !names.includes(prev)) {
|
|
374
|
+
pkg.scripts = { ...scripts, [next.name]: next.command };
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
433
377
|
const ordered = {};
|
|
434
|
-
for (const key of names)
|
|
378
|
+
for (const key of names) {
|
|
379
|
+
if (key === prev) ordered[next.name] = next.command;
|
|
380
|
+
else if (key !== next.name) ordered[key] = scripts[key];
|
|
381
|
+
}
|
|
435
382
|
pkg.scripts = ordered;
|
|
436
|
-
return true;
|
|
437
383
|
};
|
|
438
384
|
|
|
439
385
|
const saveScript = (root, prev, next) => {
|
|
@@ -444,23 +390,30 @@ const saveScript = (root, prev, next) => {
|
|
|
444
390
|
|
|
445
391
|
const removeScript = (root, name) => {
|
|
446
392
|
const pkg = readManifest(root);
|
|
447
|
-
if (!pkg
|
|
393
|
+
if (!pkg) return false;
|
|
394
|
+
const scripts = orderedScripts(pkg);
|
|
395
|
+
if (!Object.hasOwn(scripts, name)) return false;
|
|
396
|
+
const names = Object.keys(scripts).filter((key) => key !== name);
|
|
397
|
+
pkg.scripts = pickScripts(scripts, names);
|
|
448
398
|
writeManifest(root, pkg);
|
|
449
399
|
return true;
|
|
450
400
|
};
|
|
451
401
|
|
|
452
402
|
const reorderScript = (root, name, delta) => {
|
|
453
403
|
const pkg = readManifest(root);
|
|
454
|
-
if (!pkg
|
|
404
|
+
if (!pkg) return false;
|
|
405
|
+
const scripts = orderedScripts(pkg);
|
|
406
|
+
const names = Object.keys(scripts);
|
|
407
|
+
const at = names.indexOf(name);
|
|
408
|
+
const next = at + delta;
|
|
409
|
+
if (at < 0 || next < 0 || next >= names.length) return false;
|
|
410
|
+
names[at] = names[next];
|
|
411
|
+
names[next] = name;
|
|
412
|
+
pkg.scripts = pickScripts(scripts, names);
|
|
455
413
|
writeManifest(root, pkg);
|
|
456
414
|
return true;
|
|
457
415
|
};
|
|
458
416
|
|
|
459
|
-
const npmArgs = (entry) => {
|
|
460
|
-
if (entry.kind === 'bin') return ['exec', '--', entry.name];
|
|
461
|
-
return ['run', entry.name];
|
|
462
|
-
};
|
|
463
|
-
|
|
464
417
|
const signalPid = (pid, signal) => {
|
|
465
418
|
try {
|
|
466
419
|
process.kill(pid, signal);
|
|
@@ -471,7 +424,7 @@ const signalPid = (pid, signal) => {
|
|
|
471
424
|
};
|
|
472
425
|
|
|
473
426
|
const killTree = (proc) => {
|
|
474
|
-
const pid = proc
|
|
427
|
+
const pid = proc.pid;
|
|
475
428
|
if (!pid) return;
|
|
476
429
|
if (process.platform === 'win32') {
|
|
477
430
|
const killer = spawn(
|
|
@@ -508,6 +461,8 @@ const startNpm = (cwd, entry, onData, onClose) => {
|
|
|
508
461
|
settled = true;
|
|
509
462
|
onClose({ status, text: raw });
|
|
510
463
|
};
|
|
464
|
+
const isBin = entry.kind === 'bin';
|
|
465
|
+
const args = isBin ? ['exec', '--', entry.name] : ['run', entry.name];
|
|
511
466
|
let child;
|
|
512
467
|
try {
|
|
513
468
|
const opts = npmOpts({
|
|
@@ -515,7 +470,7 @@ const startNpm = (cwd, entry, onData, onClose) => {
|
|
|
515
470
|
env: commandEnv(),
|
|
516
471
|
detached: process.platform !== 'win32',
|
|
517
472
|
});
|
|
518
|
-
child = spawn(npmBin(),
|
|
473
|
+
child = spawn(npmBin(), args, opts);
|
|
519
474
|
} catch (error) {
|
|
520
475
|
raw = `${error.message}\n`;
|
|
521
476
|
finish(1);
|
|
@@ -526,13 +481,10 @@ const startNpm = (cwd, entry, onData, onClose) => {
|
|
|
526
481
|
raw += chunk;
|
|
527
482
|
onData(raw);
|
|
528
483
|
};
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
if (child.stderr) {
|
|
534
|
-
child.stderr.setEncoding('utf8');
|
|
535
|
-
child.stderr.on('data', push);
|
|
484
|
+
for (const stream of [child.stdout, child.stderr]) {
|
|
485
|
+
if (!stream) continue;
|
|
486
|
+
stream.setEncoding('utf8');
|
|
487
|
+
stream.on('data', push);
|
|
536
488
|
}
|
|
537
489
|
child.on('error', (error) => {
|
|
538
490
|
if (!stopped) raw += `${error.message}\n`;
|
|
@@ -552,20 +504,19 @@ module.exports = {
|
|
|
552
504
|
listCommands,
|
|
553
505
|
reduceOutput,
|
|
554
506
|
logFileName,
|
|
555
|
-
|
|
507
|
+
nextLogFile,
|
|
508
|
+
saveLogs,
|
|
556
509
|
staleLogFiles,
|
|
557
510
|
removeStaleLogs,
|
|
558
|
-
formatSize,
|
|
559
|
-
parseScriptLine,
|
|
560
511
|
saveScript,
|
|
561
512
|
removeScript,
|
|
562
513
|
reorderScript,
|
|
563
514
|
startNpm,
|
|
564
515
|
commandEnv,
|
|
565
516
|
isPassingTest,
|
|
566
|
-
|
|
567
|
-
indentStack,
|
|
517
|
+
traceLine,
|
|
568
518
|
relativize,
|
|
569
519
|
TABLE_KEY,
|
|
570
520
|
TABLE_VAL,
|
|
521
|
+
formatTable,
|
|
571
522
|
};
|