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.
Files changed (37) hide show
  1. package/builtins/platforms/node/services/ci.service.d.ts +1 -1
  2. package/builtins/platforms/node/services/ci.service.js +1 -1
  3. package/builtins/platforms/node/services/clean.service.d.ts +1 -1
  4. package/builtins/platforms/node/services/clean.service.js +1 -1
  5. package/builtins/platforms/node/services/publish.service.d.ts +10 -5
  6. package/builtins/platforms/node/services/publish.service.js +46 -11
  7. package/builtins/publish-targets/npm/npm-publish-target.js +3 -1
  8. package/cli.js +81 -23
  9. package/commands/changelog.command.js +1 -1
  10. package/commands/version.command.js +42 -29
  11. package/constants.js +1 -1
  12. package/core/application.d.ts +8 -1
  13. package/core/application.js +7 -1
  14. package/core/classes/log-sink.d.ts +99 -0
  15. package/core/classes/log-sink.js +101 -0
  16. package/{utils → core/classes}/logger.d.ts +1 -1
  17. package/core/classes/run-reporters.d.ts +64 -0
  18. package/core/classes/run-reporters.js +135 -0
  19. package/core/classes/service.d.ts +1 -1
  20. package/core/command-builder.js +3 -0
  21. package/core/interfaces/custom-command.d.ts +5 -1
  22. package/core/interfaces/run-step.d.ts +5 -5
  23. package/index.d.ts +2 -2
  24. package/index.js +1 -1
  25. package/package.json +1 -1
  26. package/services/exec.service.d.ts +1 -1
  27. package/services/exec.service.js +1 -1
  28. package/services/run.service.d.ts +22 -3
  29. package/services/run.service.js +190 -125
  30. package/services/version-plan.service.js +3 -3
  31. package/utils/progress-panel.d.ts +6 -0
  32. package/utils/progress-panel.js +22 -7
  33. package/utils/run-bin.d.ts +10 -2
  34. package/utils/run-bin.js +57 -11
  35. package/utils/version-group.d.ts +9 -0
  36. package/utils/version-group.js +11 -0
  37. /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
+ }
@@ -1,4 +1,4 @@
1
- import type { Repository } from '../core/classes/repository.js';
1
+ import type { Repository } from './repository.js';
2
2
  export type LogLevel = 'silent' | 'error' | 'info' | 'verbose';
3
3
  export declare const LOG_LEVELS: LogLevel[];
4
4
  /**
@@ -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,
@@ -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
- * **A script whose steps mention `topo` at all is taken as the whole statement**: the first
101
- * `true` is the barrier, and if no step says `true` there is no wait. A script where no step
102
- * mentions it falls back to `run.<script>.topo` - on by default - waiting before its first step,
103
- * which is where the wait has always been. `run.<script>.topo: false` and `--no-topo` still turn
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,7 +1,7 @@
1
1
  {
2
2
  "name": "rman",
3
3
  "description": "Repository manager",
4
- "version": "2.10.1",
4
+ "version": "2.11.1",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
7
7
  "dependencies": {
@@ -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
@@ -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) -