rman 2.10.1 → 2.11.1
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/builtins/platforms/node/services/publish.service.d.ts +10 -5
- package/builtins/platforms/node/services/publish.service.js +46 -11
- package/builtins/publish-targets/npm/npm-publish-target.js +3 -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
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Where a run's log goes besides the screen - the global `--json` and `--log-file`.
|
|
5
|
+
*
|
|
6
|
+
* - **`--json`**: the log is written to stdout as JSON Lines, one event per line, and nothing else
|
|
7
|
+
* is - no panel, no spinner, no prose.
|
|
8
|
+
* - **`--log-file <path>`**: the log is written to that file, in the same format the console uses -
|
|
9
|
+
* JSON Lines under `--json`, plain text lines otherwise.
|
|
10
|
+
*
|
|
11
|
+
* One per invocation, on `RmanApplication.logSink`, beside `statusRegion` and for the same reason:
|
|
12
|
+
* what writes to it is handed the application already, so nothing reaches for ambient state.
|
|
13
|
+
*/
|
|
14
|
+
/* **A log, not an answer.** `list`, `version`, `publish`, `config`, `info` and `github-release`
|
|
15
|
+
* declare their own `--json`, and what it prints is the command's *result* - a contract the shared
|
|
16
|
+
* release workflow reads with `jq` (`rman publish --dry-run --json`, `rman list --json`). This never
|
|
17
|
+
* writes to stdout for one of those: the result stays where it was, in the shape it had.
|
|
18
|
+
*
|
|
19
|
+
* **Every line is stripped of escape sequences** before it is written anywhere. A child piped with
|
|
20
|
+
* `FORCE_COLOR` carries colour, and a JSON string or a log file holding `\u001b[32m` is noise to every
|
|
21
|
+
* reader that is not a terminal - which is every reader of either.
|
|
22
|
+
*
|
|
23
|
+
* **The file is opened on the first event, not up front**, so a command that writes no log leaves
|
|
24
|
+
* no empty file behind - and `used` stays false, which is how the CLI can say so. Written
|
|
25
|
+
* synchronously, line by line: an interrupted run keeps every line written before the interrupt,
|
|
26
|
+
* and lines from concurrent packages stay whole and in order. */
|
|
27
|
+
export class LogSink {
|
|
28
|
+
/** The console format is JSON Lines - so nothing but events may reach stdout. */
|
|
29
|
+
json;
|
|
30
|
+
/** Whether anything was written - read by the CLI to warn about a flag nothing honoured. */
|
|
31
|
+
used = false;
|
|
32
|
+
fd;
|
|
33
|
+
file;
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.json = !!options.json;
|
|
36
|
+
this.file = options.file ? path.resolve(options.cwd ?? process.cwd(), options.file) : undefined;
|
|
37
|
+
}
|
|
38
|
+
/** Whether an event would go anywhere. A caller can skip building one when it would not. */
|
|
39
|
+
get active() {
|
|
40
|
+
return this.json || !!this.file;
|
|
41
|
+
}
|
|
42
|
+
/** The resolved file, for the message that reports it. */
|
|
43
|
+
get filePath() {
|
|
44
|
+
return this.file;
|
|
45
|
+
}
|
|
46
|
+
report(event) {
|
|
47
|
+
if (!this.active)
|
|
48
|
+
return;
|
|
49
|
+
this.used = true;
|
|
50
|
+
const time = new Date().toISOString();
|
|
51
|
+
const clean = stripEvent(event);
|
|
52
|
+
const json = JSON.stringify({ time, ...clean });
|
|
53
|
+
if (this.json)
|
|
54
|
+
process.stdout.write(json + '\n');
|
|
55
|
+
if (this.file)
|
|
56
|
+
this.append((this.json ? json : textLine(time, clean)) + '\n');
|
|
57
|
+
}
|
|
58
|
+
/** Closes the file, if one was opened. Safe to call twice. */
|
|
59
|
+
close() {
|
|
60
|
+
if (this.fd === undefined)
|
|
61
|
+
return;
|
|
62
|
+
fs.closeSync(this.fd);
|
|
63
|
+
this.fd = undefined;
|
|
64
|
+
}
|
|
65
|
+
append(text) {
|
|
66
|
+
if (this.fd === undefined) {
|
|
67
|
+
fs.mkdirSync(path.dirname(this.file), { recursive: true });
|
|
68
|
+
this.fd = fs.openSync(this.file, 'w');
|
|
69
|
+
}
|
|
70
|
+
fs.writeSync(this.fd, text);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** One event as a line of the text log: the time, the package in brackets, and what happened. */
|
|
74
|
+
function textLine(time, e) {
|
|
75
|
+
switch (e.event) {
|
|
76
|
+
case 'start':
|
|
77
|
+
return `${time} [${e.package}] ▶ ${e.step}${e.command ? ` | ${e.command}` : ''}`;
|
|
78
|
+
case 'output':
|
|
79
|
+
return `${time} [${e.package}] ${e.line}`;
|
|
80
|
+
case 'end':
|
|
81
|
+
return (`${time} [${e.package}] ${e.status === 'success' ? '✔' : '✖'} ${e.step} ${e.status} (${e.ms} ms)` +
|
|
82
|
+
(e.error ? `\n${time} [${e.package}] ${e.error.split('\n').join(`\n${time} [${e.package}] `)}` : ''));
|
|
83
|
+
case 'summary':
|
|
84
|
+
return (`${time} ${e.succeeded} succeeded, ${e.failed} failed` +
|
|
85
|
+
(e.skipped ? `, ${e.skipped} skipped` : '') +
|
|
86
|
+
` (${e.ms} ms)`);
|
|
87
|
+
case 'message':
|
|
88
|
+
return `${time} ${e.message}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Every string field of an event, with escape sequences removed. */
|
|
92
|
+
function stripEvent(e) {
|
|
93
|
+
const out = {};
|
|
94
|
+
for (const [k, v] of Object.entries(e))
|
|
95
|
+
out[k] = typeof v === 'string' ? stripAnsi(v) : v;
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
function stripAnsi(s) {
|
|
99
|
+
// eslint-disable-next-line no-control-regex
|
|
100
|
+
return s.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, '');
|
|
101
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ProgressPanel } from '../../utils/progress-panel.js';
|
|
2
|
+
import type { LogEvent, Reporter, ReportOrigin } from './log-sink.js';
|
|
3
|
+
import { type LogLevel } from './logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* The screen with no live panel: each line a step prints, led by its package, and one line per step
|
|
6
|
+
* when it ends - the output `--no-progress`, a pipe or CI gets.
|
|
7
|
+
*/
|
|
8
|
+
export declare class PlainReporter implements Reporter {
|
|
9
|
+
/** What the per-step lines call the run - `run`, `build`, `check`. */
|
|
10
|
+
protected readonly commandName: string;
|
|
11
|
+
/** Whose tally the recap prints; absent for a reporter that only says rman's own messages. */
|
|
12
|
+
protected readonly panel?: ProgressPanel | undefined;
|
|
13
|
+
readonly childEnv: Record<string, string> | undefined;
|
|
14
|
+
/** Four letters per level, as winston and log4j-style formats shorten them - `ERROR` keeps its five. */
|
|
15
|
+
protected readonly levelTags: Readonly<Record<Exclude<LogLevel, 'silent'>, string>>;
|
|
16
|
+
constructor(
|
|
17
|
+
/** What the per-step lines call the run - `run`, `build`, `check`. */
|
|
18
|
+
commandName: string,
|
|
19
|
+
/** Whose tally the recap prints; absent for a reporter that only says rman's own messages. */
|
|
20
|
+
panel?: ProgressPanel | undefined);
|
|
21
|
+
report(event: LogEvent, origin?: ReportOrigin): void;
|
|
22
|
+
/** The `executing` line, at `verbose` only - rman's old behaviour, hidden by default. */
|
|
23
|
+
protected started(event: Extract<LogEvent, {
|
|
24
|
+
event: 'start';
|
|
25
|
+
}>, origin: ReportOrigin): void;
|
|
26
|
+
/** One line of a step's output, to the stream it came from, led by its package - in red when rman
|
|
27
|
+
* itself wrote the line to say why the step failed (`level: 'error'`). */
|
|
28
|
+
protected output(event: Extract<LogEvent, {
|
|
29
|
+
event: 'output';
|
|
30
|
+
}>, origin: ReportOrigin): void;
|
|
31
|
+
/** `[INFO] build pkg ┆ exec success ┆ tsc -b (123 ms)` - suppressed below `info` unless it failed,
|
|
32
|
+
* and under `silent` even then. */
|
|
33
|
+
protected ended(event: Extract<LogEvent, {
|
|
34
|
+
event: 'end';
|
|
35
|
+
}>, origin: ReportOrigin): void;
|
|
36
|
+
/**
|
|
37
|
+
* A line's own level as `[INFO]`, `[VERB]`, `[ERROR]` - upper case, four letters but for `ERROR`, in
|
|
38
|
+
* the level's colour.
|
|
39
|
+
*/
|
|
40
|
+
protected levelTag(level: Exclude<LogLevel, 'silent'>): string;
|
|
41
|
+
/** Whether `level` prints what `wanted` does. */
|
|
42
|
+
protected atLeast(level: LogLevel, wanted: LogLevel): boolean;
|
|
43
|
+
/** The `┆ <what it runs>` tail of a step line, **or nothing at all** when the step has no label of
|
|
44
|
+
* its own - an anonymous function handed to `forEachPackage`, where the slot name already said
|
|
45
|
+
* everything and a separator with nothing after it is noise. */
|
|
46
|
+
protected describing(origin: ReportOrigin): string[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The screen while the live panel draws: a step's lines go to its package's row - the last one
|
|
50
|
+
* shown under it, all of them replayed if the package fails - and the recap lists every package.
|
|
51
|
+
*/
|
|
52
|
+
export declare class PanelReporter extends PlainReporter {
|
|
53
|
+
/** A child's lines are only stored, and replayed into a row whose width is measured - colour
|
|
54
|
+
* would only be escape codes counted as text there. */
|
|
55
|
+
readonly childEnv: undefined;
|
|
56
|
+
constructor(commandName: string, panel: ProgressPanel);
|
|
57
|
+
/** The row names the step itself; there is no separate line to print. */
|
|
58
|
+
protected started(): void;
|
|
59
|
+
protected output(event: Extract<LogEvent, {
|
|
60
|
+
event: 'output';
|
|
61
|
+
}>, origin: ReportOrigin): void;
|
|
62
|
+
/** The row shows the step's outcome; the recap prints the package's. */
|
|
63
|
+
protected ended(): void;
|
|
64
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import colors from 'ansi-colors';
|
|
2
|
+
import { colorsPrintedOutput } from '../../utils/run-bin.js';
|
|
3
|
+
import { LOG_LEVELS } from './logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* The screen with no live panel: each line a step prints, led by its package, and one line per step
|
|
6
|
+
* when it ends - the output `--no-progress`, a pipe or CI gets.
|
|
7
|
+
*/
|
|
8
|
+
/* **Every line names its package.** Packages run concurrently, so one package's lines land between
|
|
9
|
+
* another's, and a step's own status line comes only once the step has ended - *below* its output.
|
|
10
|
+
* Unlabelled, a compiler error read as the package whose line happened to sit above it: reported on
|
|
11
|
+
* opra, where `@opra/api-ui`'s TS2307 printed under `@opra/openapi ┆ after success` and the
|
|
12
|
+
* `api-ui ┆ exec failed` it belonged to came three lines later.
|
|
13
|
+
*
|
|
14
|
+
* **A step's lines are written to the stream, never through `console`.** A function step's own
|
|
15
|
+
* `console` is captured and arrives here as `output` events, synchronously and still inside that
|
|
16
|
+
* step's async context - so a `console.log` from here would be captured again and come straight
|
|
17
|
+
* back. The step lines and the recap are written outside any step and use `console` as they always
|
|
18
|
+
* did. */
|
|
19
|
+
export class PlainReporter {
|
|
20
|
+
commandName;
|
|
21
|
+
panel;
|
|
22
|
+
childEnv;
|
|
23
|
+
/** Four letters per level, as winston and log4j-style formats shorten them - `ERROR` keeps its five. */
|
|
24
|
+
levelTags = {
|
|
25
|
+
error: 'ERROR',
|
|
26
|
+
info: 'INFO',
|
|
27
|
+
verbose: 'VERB',
|
|
28
|
+
};
|
|
29
|
+
constructor(
|
|
30
|
+
/** What the per-step lines call the run - `run`, `build`, `check`. */
|
|
31
|
+
commandName,
|
|
32
|
+
/** Whose tally the recap prints; absent for a reporter that only says rman's own messages. */
|
|
33
|
+
panel) {
|
|
34
|
+
this.commandName = commandName;
|
|
35
|
+
this.panel = panel;
|
|
36
|
+
/** A child is run without a terminal and its lines are printed by rman, so it would drop its
|
|
37
|
+
* colour; this brings it back where our own stdout is a terminal - and only the colour, since
|
|
38
|
+
* tools gate their live output on `isTTY`, which stays false. */
|
|
39
|
+
this.childEnv = colorsPrintedOutput() ? { FORCE_COLOR: '1' } : undefined;
|
|
40
|
+
}
|
|
41
|
+
report(event, origin) {
|
|
42
|
+
switch (event.event) {
|
|
43
|
+
case 'start':
|
|
44
|
+
if (origin)
|
|
45
|
+
this.started(event, origin);
|
|
46
|
+
return;
|
|
47
|
+
case 'output':
|
|
48
|
+
if (origin)
|
|
49
|
+
this.output(event, origin);
|
|
50
|
+
return;
|
|
51
|
+
case 'end':
|
|
52
|
+
if (origin)
|
|
53
|
+
this.ended(event, origin);
|
|
54
|
+
return;
|
|
55
|
+
case 'summary':
|
|
56
|
+
this.panel?.printSummary();
|
|
57
|
+
return;
|
|
58
|
+
case 'message':
|
|
59
|
+
console.log(event.level === 'error' ? colors.red(event.message) : colors.gray(event.message));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** The `executing` line, at `verbose` only - rman's old behaviour, hidden by default. */
|
|
63
|
+
started(event, origin) {
|
|
64
|
+
if (!this.atLeast(origin.logLevel, 'verbose'))
|
|
65
|
+
return;
|
|
66
|
+
console.log(this.levelTag('verbose'), this.commandName, colors.cyan(event.package), colors.gray('┆'), colors.cyanBright.bold(event.step), colors.cyanBright.bold('executing'), ...this.describing(origin));
|
|
67
|
+
}
|
|
68
|
+
/** One line of a step's output, to the stream it came from, led by its package - in red when rman
|
|
69
|
+
* itself wrote the line to say why the step failed (`level: 'error'`). */
|
|
70
|
+
/* **Red only where rman knows, and the stream is not knowing.** It was "red on stderr" for one
|
|
71
|
+
* build, and every progress line went red with it: dpdm prints `Start analyzing dependencies...`
|
|
72
|
+
* and `Analyze done!` to stderr, as spinner libraries do. In the other direction tsc writes its
|
|
73
|
+
* diagnostics to **stdout** (measured: a type error, exit 2, one line on stdout, none on stderr).
|
|
74
|
+
* Neither direction holds. A line is printed as it arrives, before anything knows whether its
|
|
75
|
+
* step will fail, so what is left is the message rman writes itself - a function step's throw,
|
|
76
|
+
* `runBin`'s `exited with code`. Reading the text for `error` is a guess: a test runner prints
|
|
77
|
+
* "0 errors" on success. */
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- the panel's override needs the row
|
|
79
|
+
output(event, origin) {
|
|
80
|
+
const name = event.level === 'error' ? colors.red(event.package) : colors.cyan(event.package);
|
|
81
|
+
const prefix = name + ' ' + colors.gray('┆') + ' ';
|
|
82
|
+
(event.stream === 'stderr' ? process.stderr : process.stdout).write(prefix + event.line + '\n');
|
|
83
|
+
}
|
|
84
|
+
/** `[INFO] build pkg ┆ exec success ┆ tsc -b (123 ms)` - suppressed below `info` unless it failed,
|
|
85
|
+
* and under `silent` even then. */
|
|
86
|
+
ended(event, origin) {
|
|
87
|
+
const failed = event.status === 'failed';
|
|
88
|
+
if (!failed && !this.atLeast(origin.logLevel, 'info'))
|
|
89
|
+
return;
|
|
90
|
+
if (failed && origin.logLevel === 'silent')
|
|
91
|
+
return;
|
|
92
|
+
console.log(this.levelTag(failed ? 'error' : 'info'), this.commandName, failed ? colors.red(event.package) : colors.cyan(event.package), colors.gray('┆'), colors.cyanBright.bold(event.step), failed ? colors.red.bold('failed') : colors.green.bold('success'), ...this.describing(origin), colors.yellow(` (${event.ms} ms)`));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* A line's own level as `[INFO]`, `[VERB]`, `[ERROR]` - upper case, four letters but for `ERROR`, in
|
|
96
|
+
* the level's colour.
|
|
97
|
+
*/
|
|
98
|
+
/* **The line's level, not the package's threshold.** `origin.logLevel` decides which lines are
|
|
99
|
+
* printed; the tag says what this line is. Printing the threshold would tag a success line `[VERB]`
|
|
100
|
+
* in a package set to `verbose` - winston and the rest tag the message, not the logger. */
|
|
101
|
+
levelTag(level) {
|
|
102
|
+
const tag = `[${this.levelTags[level]}]`;
|
|
103
|
+
return level === 'error' ? colors.red(tag) : level === 'info' ? colors.green(tag) : colors.magenta(tag);
|
|
104
|
+
}
|
|
105
|
+
/** Whether `level` prints what `wanted` does. */
|
|
106
|
+
atLeast(level, wanted) {
|
|
107
|
+
return LOG_LEVELS.indexOf(level) >= LOG_LEVELS.indexOf(wanted);
|
|
108
|
+
}
|
|
109
|
+
/** The `┆ <what it runs>` tail of a step line, **or nothing at all** when the step has no label of
|
|
110
|
+
* its own - an anonymous function handed to `forEachPackage`, where the slot name already said
|
|
111
|
+
* everything and a separator with nothing after it is noise. */
|
|
112
|
+
describing(origin) {
|
|
113
|
+
return origin.label ? [colors.gray('┆'), origin.label] : [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The screen while the live panel draws: a step's lines go to its package's row - the last one
|
|
118
|
+
* shown under it, all of them replayed if the package fails - and the recap lists every package.
|
|
119
|
+
*/
|
|
120
|
+
export class PanelReporter extends PlainReporter {
|
|
121
|
+
/** A child's lines are only stored, and replayed into a row whose width is measured - colour
|
|
122
|
+
* would only be escape codes counted as text there. */
|
|
123
|
+
childEnv = undefined;
|
|
124
|
+
constructor(commandName, panel) {
|
|
125
|
+
super(commandName, panel);
|
|
126
|
+
}
|
|
127
|
+
/** The row names the step itself; there is no separate line to print. */
|
|
128
|
+
started() { }
|
|
129
|
+
output(event, origin) {
|
|
130
|
+
origin.item.log.push(event.line);
|
|
131
|
+
origin.item.lastLine = event.line;
|
|
132
|
+
}
|
|
133
|
+
/** The row shows the step's outcome; the recap prints the package's. */
|
|
134
|
+
ended() { }
|
|
135
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Logger } from '../../utils/logger.js';
|
|
2
1
|
import type { RmanApplication } from '../application.js';
|
|
2
|
+
import type { Logger } from './logger.js';
|
|
3
3
|
import type { Repository } from './repository.js';
|
|
4
4
|
/**
|
|
5
5
|
* **The one service shape.** Everything that does work on a repository is a class extending this,
|
package/core/command-builder.js
CHANGED
|
@@ -25,6 +25,9 @@ contextFor) {
|
|
|
25
25
|
* a field nothing ever sees - measured, `rman config` printed a status line above its own YAML
|
|
26
26
|
* document while declaring `printsDocument: true`. */
|
|
27
27
|
printsDocument: meta.printsDocument,
|
|
28
|
+
/** A command declaring `--json` itself prints its result that way, and owns the flag: under the
|
|
29
|
+
* global `--json` its stdout is that result, never a stream of log events. */
|
|
30
|
+
ownsJson: !!meta.config && 'json' in meta.config,
|
|
28
31
|
builder: (cmd) => {
|
|
29
32
|
if (meta.parserConfiguration)
|
|
30
33
|
cmd.parserConfiguration(meta.parserConfiguration);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ArgumentsCamelCase, Argv } from 'yargs';
|
|
2
2
|
import type { RmanConfig as CommandDeclaration } from '../../interfaces/rman-config.interface.js';
|
|
3
3
|
import type { RunService } from '../../services/run.service.js';
|
|
4
|
-
import type { Logger } from '../../utils/logger.js';
|
|
5
4
|
import type { RunBinOptions, RunBinResult } from '../../utils/run-bin.js';
|
|
5
|
+
import type { Logger } from '../classes/logger.js';
|
|
6
6
|
import type { Package } from '../classes/package.js';
|
|
7
7
|
import type { Repository } from '../classes/repository.js';
|
|
8
8
|
import type { RunStepFn } from './run-step.js';
|
|
@@ -111,6 +111,10 @@ declare module 'yargs' {
|
|
|
111
111
|
* `CommandMetadata.printsDocument`. Here as well as there because `cli.ts` reads it off the
|
|
112
112
|
* *registration*, which is the only shape that reaches `program.command`. */
|
|
113
113
|
printsDocument?: boolean;
|
|
114
|
+
/** Whether the command declares its own `--json`, printing its *result* as JSON - in which case
|
|
115
|
+
* the global `--json` is that, and its log is not written to stdout. Carried from the
|
|
116
|
+
* declaration by `toYargsCommand`, for the reason `printsDocument` is. */
|
|
117
|
+
ownsJson?: boolean;
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
120
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Logger } from '../../utils/logger.js';
|
|
2
1
|
import type { RunBinOptions, RunBinResult } from '../../utils/run-bin.js';
|
|
2
|
+
import type { Logger } from '../classes/logger.js';
|
|
3
3
|
import type { Package } from '../classes/package.js';
|
|
4
4
|
import type { Repository } from '../classes/repository.js';
|
|
5
5
|
/**
|
|
@@ -97,10 +97,10 @@ export interface RunStepObject {
|
|
|
97
97
|
* later `topo: false` a true statement about the step that changes nothing about when it runs -
|
|
98
98
|
* worth writing as intent, not a lever.
|
|
99
99
|
*
|
|
100
|
-
* **
|
|
101
|
-
* `
|
|
102
|
-
*
|
|
103
|
-
*
|
|
100
|
+
* **The barrier is the first step marked `true`; with none, the first unmarked step**, which
|
|
101
|
+
* takes `run.<script>.topo` - on by default. A `false` frees its own step only, so a script waits
|
|
102
|
+
* nowhere only when every step says `false`. A package's own script replacing a marked `exec`
|
|
103
|
+
* (an npm `build`) keeps that mark. `run.<script>.topo: false` and `--no-topo` still turn
|
|
104
104
|
* ordering off outright.
|
|
105
105
|
*
|
|
106
106
|
* Only in `run.<script>`: a `version` hook runs for one package around its own version write,
|
package/index.d.ts
CHANGED
|
@@ -135,11 +135,11 @@ export { parallelOptions, readParallelOptions, readRunOptions, runOptions } from
|
|
|
135
135
|
export { BinPath } from './utils/bin-path.js';
|
|
136
136
|
/** A shell command, with the repository's local binaries on PATH - for a command string an author
|
|
137
137
|
* wrote. `runBin` is the one to reach for when the arguments are assembled in code. */
|
|
138
|
+
export type { LogLevel } from './core/classes/logger.js';
|
|
139
|
+
export { LOG_LEVELS, Logger, resolveRootLogLevel } from './core/classes/logger.js';
|
|
138
140
|
export type { ExecOptions, ExecResult } from './utils/exec.js';
|
|
139
141
|
export { exec } from './utils/exec.js';
|
|
140
142
|
export { GitHelper } from './utils/git.js';
|
|
141
|
-
export type { LogLevel } from './utils/logger.js';
|
|
142
|
-
export { LOG_LEVELS, Logger, resolveRootLogLevel } from './utils/logger.js';
|
|
143
143
|
/** `--scope`/`--deps`/`--dependents`/`--private`, so a plugin's command filters packages the same
|
|
144
144
|
* way every built-in does rather than inventing its own flags. */
|
|
145
145
|
export { applyFromRootOption, applyPackageFilterOptions, filterPackages, fromRootOption, type PackageFilterOptions, packageFilterOptions, readFromRootOption, readPackageFilterOptions, ROOT_SELECTOR, } from './utils/package-filter.js';
|
package/index.js
CHANGED
|
@@ -120,9 +120,9 @@ export { parallelOptions, readParallelOptions, readRunOptions, runOptions } from
|
|
|
120
120
|
/** Where a repository's locally installed binaries live - the core spells the PATH variable, a
|
|
121
121
|
* plugin says which directories go on it (see `Plugin.binPaths`). */
|
|
122
122
|
export { BinPath } from './utils/bin-path.js';
|
|
123
|
+
export { LOG_LEVELS, Logger, resolveRootLogLevel } from './core/classes/logger.js';
|
|
123
124
|
export { exec } from './utils/exec.js';
|
|
124
125
|
export { GitHelper } from './utils/git.js';
|
|
125
|
-
export { LOG_LEVELS, Logger, resolveRootLogLevel } from './utils/logger.js';
|
|
126
126
|
/** `--scope`/`--deps`/`--dependents`/`--private`, so a plugin's command filters packages the same
|
|
127
127
|
* way every built-in does rather than inventing its own flags. */
|
|
128
128
|
export { applyFromRootOption, applyPackageFilterOptions, filterPackages, fromRootOption, packageFilterOptions, readFromRootOption, readPackageFilterOptions, ROOT_SELECTOR, } from './utils/package-filter.js';
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { type LogLevel } from '../core/classes/logger.js';
|
|
1
2
|
import { Service } from '../core/classes/service.js';
|
|
2
|
-
import { type LogLevel } from '../utils/logger.js';
|
|
3
3
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
4
4
|
/**
|
|
5
5
|
* A service class - see `ListService` for the shape and `Service` for the three measured
|
package/services/exec.service.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import colors from 'ansi-colors';
|
|
3
3
|
import { Task } from 'power-tasks';
|
|
4
|
+
import { Logger, resolveRootLogLevel } from '../core/classes/logger.js';
|
|
4
5
|
import { Service } from '../core/classes/service.js';
|
|
5
6
|
import { exec as execCommand } from '../utils/exec.js';
|
|
6
|
-
import { Logger, resolveRootLogLevel } from '../utils/logger.js';
|
|
7
7
|
import { filterPackages } from '../utils/package-filter.js';
|
|
8
8
|
import { ProgressPanel } from '../utils/progress-panel.js';
|
|
9
9
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { Reporter } from '../core/classes/log-sink.js';
|
|
2
|
+
import { type LogLevel } from '../core/classes/logger.js';
|
|
1
3
|
import type { Package } from '../core/classes/package.js';
|
|
2
4
|
import type { Repository } from '../core/classes/repository.js';
|
|
3
5
|
import { Service } from '../core/classes/service.js';
|
|
4
6
|
import type { RunStepContext, RunStepFn, RunStepValue } from '../core/interfaces/run-step.js';
|
|
5
|
-
import { type LogLevel } from '../utils/logger.js';
|
|
6
7
|
import { type PackageFilterOptions } from '../utils/package-filter.js';
|
|
7
8
|
import { ProgressPanel } from '../utils/progress-panel.js';
|
|
8
9
|
/**
|
|
@@ -78,6 +79,24 @@ export declare class RunService extends Service {
|
|
|
78
79
|
parallel<T>(tasks: readonly (() => Promise<T>)[], options?: {
|
|
79
80
|
parallel?: boolean | number;
|
|
80
81
|
}): Promise<T[]>;
|
|
82
|
+
/**
|
|
83
|
+
* The index of the step a package waits for its dependencies before, or `-1` when every step is
|
|
84
|
+
* marked `topo: false`: the first step marked `true`, else the first unmarked one.
|
|
85
|
+
*/
|
|
86
|
+
protected barrierOf(steps: readonly {
|
|
87
|
+
topo?: boolean;
|
|
88
|
+
}[]): number;
|
|
89
|
+
/**
|
|
90
|
+
* A line of rman's own about the run - "nothing to run", "no package defines it" - on the console
|
|
91
|
+
* as prose, or as a `message` event under `--json`, where stdout belongs to the events. Also in the
|
|
92
|
+
* log file when there is one.
|
|
93
|
+
*/
|
|
94
|
+
protected say(level: 'info' | 'error', message: string): void;
|
|
95
|
+
/**
|
|
96
|
+
* Who renders a run: the panel when it draws, plain lines when it does not, neither under `--json`
|
|
97
|
+
* (stdout belongs to the events) - plus the run's log, when the CLI asked for one.
|
|
98
|
+
*/
|
|
99
|
+
protected reportersFor(commandName: string, panel?: ProgressPanel): Reporter[];
|
|
81
100
|
}
|
|
82
101
|
export declare namespace RunService {
|
|
83
102
|
export interface Options extends PackageFilterOptions {
|
|
@@ -282,12 +301,12 @@ export declare namespace RunService {
|
|
|
282
301
|
* Runs `fn` with `console` captured into `onLine`, and leaves the real `console` behind when the
|
|
283
302
|
* last concurrent step is done.
|
|
284
303
|
*/
|
|
285
|
-
export function withCapturedConsole<T>(onLine: (line: string) => void, fn: () => T | Promise<T>): Promise<T>;
|
|
304
|
+
export function withCapturedConsole<T>(onLine: (line: string, stream?: 'stdout' | 'stderr') => void, fn: () => T | Promise<T>): Promise<T>;
|
|
286
305
|
/**
|
|
287
306
|
* `onCommand` is told what the step is spawning, for as long as it runs - the argv while a child
|
|
288
307
|
* is up, `undefined` when it returns.
|
|
289
308
|
*/
|
|
290
|
-
export function createStepContext(pkg: Package, cwd: string, onCommand?: (command: string | undefined) => void, onLine?: (line: string) => void): RunStepContext;
|
|
309
|
+
export function createStepContext(pkg: Package, cwd: string, onCommand?: (command: string | undefined) => void, onLine?: (line: string, stream?: 'stdout' | 'stderr') => void): RunStepContext;
|
|
291
310
|
/**
|
|
292
311
|
* `.rmanrc` conditional execution, GitHub Actions-`if`-flavored but a small closed grammar
|
|
293
312
|
* instead of a full expression language (less to get wrong, still covers what's asked for) -
|