rman 2.10.0 → 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 +53 -31
- 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 +19 -0
- package/utils/version-group.js +23 -0
- /package/{utils → core/classes}/logger.js +0 -0
|
@@ -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) -
|