rman 2.10.1 → 2.11.0
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/builtins/platforms/node/services/ci.service.d.ts +1 -1
- package/builtins/platforms/node/services/ci.service.js +1 -1
- package/builtins/platforms/node/services/clean.service.d.ts +1 -1
- package/builtins/platforms/node/services/clean.service.js +1 -1
- package/cli.js +81 -23
- package/commands/changelog.command.js +1 -1
- package/commands/version.command.js +42 -29
- package/constants.js +1 -1
- package/core/application.d.ts +8 -1
- package/core/application.js +7 -1
- package/core/classes/log-sink.d.ts +99 -0
- package/core/classes/log-sink.js +101 -0
- package/{utils → core/classes}/logger.d.ts +1 -1
- package/core/classes/run-reporters.d.ts +64 -0
- package/core/classes/run-reporters.js +135 -0
- package/core/classes/service.d.ts +1 -1
- package/core/command-builder.js +3 -0
- package/core/interfaces/custom-command.d.ts +5 -1
- package/core/interfaces/run-step.d.ts +5 -5
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/package.json +1 -1
- package/services/exec.service.d.ts +1 -1
- package/services/exec.service.js +1 -1
- package/services/run.service.d.ts +22 -3
- package/services/run.service.js +190 -125
- package/services/version-plan.service.js +3 -3
- package/utils/progress-panel.d.ts +6 -0
- package/utils/progress-panel.js +22 -7
- package/utils/run-bin.d.ts +10 -2
- package/utils/run-bin.js +57 -11
- package/utils/version-group.d.ts +9 -0
- package/utils/version-group.js +11 -0
- /package/{utils → core/classes}/logger.js +0 -0
package/utils/run-bin.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import colors from 'ansi-colors';
|
|
3
|
+
import { LOG_LEVELS } from '../core/classes/logger.js';
|
|
3
4
|
import { BinPath } from './bin-path.js';
|
|
4
5
|
import { trackChild } from './child-tracker.js';
|
|
5
|
-
import { LOG_LEVELS } from './logger.js';
|
|
6
6
|
/**
|
|
7
7
|
* Runs one of the repository's locally installed binaries, passing **argv as an array** - no shell.
|
|
8
8
|
*
|
|
@@ -62,7 +62,9 @@ export async function runBin(bin, argv, options = {}) {
|
|
|
62
62
|
* while a status region is live had it, which since 2.3.0 is every one of them. */
|
|
63
63
|
env: BinPath.env({
|
|
64
64
|
cwd,
|
|
65
|
-
env: region
|
|
65
|
+
env: forceColor(region, options, atLeast('info'))
|
|
66
|
+
? { FORCE_COLOR: '1', ...(options.env ?? process.env) }
|
|
67
|
+
: options.env,
|
|
66
68
|
app: options.app,
|
|
67
69
|
}),
|
|
68
70
|
windowsHide: true,
|
|
@@ -71,31 +73,46 @@ export async function runBin(bin, argv, options = {}) {
|
|
|
71
73
|
* which meant a plugin command's child outlived a Ctrl-C. See `trackChild`. */
|
|
72
74
|
trackChild(child);
|
|
73
75
|
let output = '';
|
|
76
|
+
/**
|
|
77
|
+
* **Split into lines per stream, holding the unfinished tail until the rest arrives** - the way
|
|
78
|
+
* `exec` already does. A `data` event ends wherever the pipe's buffer did, not at a newline, so
|
|
79
|
+
* splitting each chunk on its own cut a line arriving in two pieces into two lines. Harmless while
|
|
80
|
+
* the only reader was a panel row showing the last line; wrong once a caller prints every line, as
|
|
81
|
+
* the panel-off `run` does, where it put a newline in the middle of whatever the child wrote.
|
|
82
|
+
*/
|
|
83
|
+
const pending = { stdout: '', stderr: '' };
|
|
84
|
+
const emit = (stream, text, flush) => {
|
|
85
|
+
const lines = (pending[stream] + text).split(/\r?\n/);
|
|
86
|
+
pending[stream] = flush ? '' : lines.pop();
|
|
87
|
+
for (const line of lines)
|
|
88
|
+
if (line)
|
|
89
|
+
options.onLine(line, stream);
|
|
90
|
+
};
|
|
74
91
|
/** **Streamed through the region as it arrives, not held to the end.** Piping is how the region
|
|
75
92
|
* stays intact; buffering would additionally make a long command look silent, which is the very
|
|
76
93
|
* thing the region exists to fix. Only when a region is live - otherwise `pipe` keeps meaning
|
|
77
94
|
* "capture, and surface it if this fails". */
|
|
78
|
-
const collect = (d) => {
|
|
95
|
+
const collect = (stream) => (d) => {
|
|
79
96
|
const text = d.toString();
|
|
80
97
|
output += text;
|
|
81
98
|
/** A caller taking the lines owns them - it is showing them somewhere of its own, and writing
|
|
82
99
|
* them here as well would both double them and scroll whatever it is drawing. */
|
|
83
|
-
if (options.onLine)
|
|
84
|
-
|
|
85
|
-
if (line)
|
|
86
|
-
options.onLine(line);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
100
|
+
if (options.onLine)
|
|
101
|
+
return emit(stream, text, false);
|
|
89
102
|
if (region && atLeast('info'))
|
|
90
103
|
region.passThrough(text);
|
|
91
104
|
};
|
|
92
|
-
child.stdout?.on('data', collect);
|
|
93
|
-
child.stderr?.on('data', collect);
|
|
105
|
+
child.stdout?.on('data', collect('stdout'));
|
|
106
|
+
child.stderr?.on('data', collect('stderr'));
|
|
94
107
|
return new Promise((resolve, reject) => {
|
|
95
108
|
child.on('error', (e) => {
|
|
96
109
|
reject(e?.code === 'ENOENT' ? new Error(`"${bin}" was not found - is it installed in this repository?`) : e);
|
|
97
110
|
});
|
|
98
111
|
child.on('close', code => {
|
|
112
|
+
/** A last line with no newline after it is still a line. */
|
|
113
|
+
if (options.onLine)
|
|
114
|
+
for (const stream of ['stdout', 'stderr'])
|
|
115
|
+
emit(stream, '', true);
|
|
99
116
|
if (code === 0)
|
|
100
117
|
return resolve({ code: 0, output });
|
|
101
118
|
/** Captured output has to be surfaced here or it is lost with the process - the one thing
|
|
@@ -111,3 +128,32 @@ export async function runBin(bin, argv, options = {}) {
|
|
|
111
128
|
});
|
|
112
129
|
});
|
|
113
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Whether a piped child is told it may colour anyway.
|
|
133
|
+
*
|
|
134
|
+
* A child checks `isTTY` to decide whether to colour, and a pipe is not one - so a child whose output
|
|
135
|
+
* is shown rather than read loses the colour it had with the terminal. Two cases show it: a live
|
|
136
|
+
* region routing it through `passThrough`, and a caller taking the lines to print (`onLine`) while
|
|
137
|
+
* our own output really is a terminal. Not when stdout is redirected, where escapes would land in a
|
|
138
|
+
* file, and not under `NO_COLOR`, which is the user saying no.
|
|
139
|
+
*
|
|
140
|
+
* **`FORCE_COLOR` turns on colour and nothing else.** A tool's live output - a spinner, a progress
|
|
141
|
+
* bar - is gated on `isTTY`, which stays false, so a child piped this way prints plain lines in
|
|
142
|
+
* colour: exactly what a run with no progress panel is after.
|
|
143
|
+
*/
|
|
144
|
+
function forceColor(region, options, info) {
|
|
145
|
+
if (!info)
|
|
146
|
+
return false;
|
|
147
|
+
if (region)
|
|
148
|
+
return true;
|
|
149
|
+
return !!options.onLine && colorsPrintedOutput();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Whether a child whose lines rman prints itself should be told to colour them: our own stdout is a
|
|
153
|
+
* terminal, and `NO_COLOR` is not set. The one rule for both kinds of step - `runBin`'s, above, and a
|
|
154
|
+
* shell step `exec` runs with its lines printed by `RunService` - so the two cannot disagree about
|
|
155
|
+
* when a piped child gets its colour back.
|
|
156
|
+
*/
|
|
157
|
+
export function colorsPrintedOutput() {
|
|
158
|
+
return !!process.stdout.isTTY && !process.env.NO_COLOR;
|
|
159
|
+
}
|
package/utils/version-group.d.ts
CHANGED
|
@@ -26,6 +26,15 @@ export declare function groupKeyOf(pkg: Package): string;
|
|
|
26
26
|
* opted out of grouping has no group to name.
|
|
27
27
|
*/
|
|
28
28
|
export declare function isSoloGroupKey(key: string): boolean;
|
|
29
|
+
/** Whether a group key is one the repository **named** (`group: "core"`) - a real value, as opposed
|
|
30
|
+
* to the implicit default group or the root's own entry, which have descriptions rather than names. */
|
|
31
|
+
export declare function isNamedGroupKey(key: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The group key of a monorepo root's own plan entry. Not something `groupKeyOf` ever returns: the
|
|
34
|
+
* root is never a member of a release group - its number is the repository's identity - so the
|
|
35
|
+
* planner gives it a key of its own, and this is that key's one spelling.
|
|
36
|
+
*/
|
|
37
|
+
export declare const ROOT_GROUP_KEY = "__root__";
|
|
29
38
|
/**
|
|
30
39
|
* How many distinct version lines this package's repository releases along - 1 when every package
|
|
31
40
|
* moves together, more once anything is grouped apart.
|
package/utils/version-group.js
CHANGED
|
@@ -34,6 +34,17 @@ export function groupKeyOf(pkg) {
|
|
|
34
34
|
export function isSoloGroupKey(key) {
|
|
35
35
|
return key.startsWith('solo:');
|
|
36
36
|
}
|
|
37
|
+
/** Whether a group key is one the repository **named** (`group: "core"`) - a real value, as opposed
|
|
38
|
+
* to the implicit default group or the root's own entry, which have descriptions rather than names. */
|
|
39
|
+
export function isNamedGroupKey(key) {
|
|
40
|
+
return key.startsWith('named:');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The group key of a monorepo root's own plan entry. Not something `groupKeyOf` ever returns: the
|
|
44
|
+
* root is never a member of a release group - its number is the repository's identity - so the
|
|
45
|
+
* planner gives it a key of its own, and this is that key's one spelling.
|
|
46
|
+
*/
|
|
47
|
+
export const ROOT_GROUP_KEY = '__root__';
|
|
37
48
|
/**
|
|
38
49
|
* How many distinct version lines this package's repository releases along - 1 when every package
|
|
39
50
|
* moves together, more once anything is grouped apart.
|
|
File without changes
|