rman 2.20.0 → 2.21.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/cli.js CHANGED
@@ -99,6 +99,12 @@ export async function runCli(options) {
99
99
  ? err.message
100
100
  : '';
101
101
  console.log('\n' + colors.red(text));
102
+ /** The handler's own error is marked too, because it is the one that comes back: yargs
103
+ * rejects `parseAsync` with what the handler threw, not with what this throws, so
104
+ * `runCli`'s catch saw it unmarked and printed the same line again on stderr - every
105
+ * failing command said its reason twice. */
106
+ if (err && typeof err === 'object')
107
+ err.logged = true;
102
108
  /** A real `Error`, marked `logged` since the text above just went out: yargs hands the
103
109
  * reason over as a bare string, and rethrowing that raw made bad argv indistinguishable
104
110
  * from success to anything holding the promise - or the shell. */
package/constants.js CHANGED
@@ -1 +1 @@
1
- export const version = '2.20.0';
1
+ export const version = '2.21.0';
@@ -24,6 +24,20 @@ export interface ProgressItem {
24
24
  finishedAt?: number;
25
25
  /** Captured output, printed back out if the item ends up failing. */
26
26
  log: string[];
27
+ /**
28
+ * The same output split by the step that printed it, when the driver reports steps (`run`'s
29
+ * scheduler does). A failed item's recap then names the steps that passed in a line each and
30
+ * prints the output of the one that failed; without it, `log` is printed whole.
31
+ */
32
+ steps?: StepLog[];
33
+ }
34
+ /** One step of an item, as the recap shows it - see `ProgressItem.steps`. */
35
+ export interface StepLog {
36
+ /** `before: rman check` - the slot and what ran in it. */
37
+ label: string;
38
+ /** Unset while it runs, and for a step that never got to end. */
39
+ status?: 'success' | 'failed';
40
+ lines: string[];
27
41
  }
28
42
  export interface ProgressSummary {
29
43
  successCount: number;
@@ -81,6 +95,11 @@ export declare class ProgressPanel implements TerminalRegion {
81
95
  * `TerminalRegion` half of the takeover, so a `runBin` child's output goes somewhere sane while
82
96
  * a panel is up. */
83
97
  passThrough(text: string): void;
98
+ /**
99
+ * A failed item's steps: one line for each that passed, and the one that failed - or never got to
100
+ * end - with its whole output under it.
101
+ */
102
+ protected stepRecap(steps: readonly StepLog[]): string;
84
103
  /** Every line of a replayed log moved two columns right - an empty line left empty. */
85
104
  protected indentLog(text: string): string;
86
105
  private render;
@@ -79,6 +79,28 @@ export class ProgressPanel {
79
79
  process.stdout.write(text);
80
80
  this.render();
81
81
  }
82
+ /**
83
+ * A failed item's steps: one line for each that passed, and the one that failed - or never got to
84
+ * end - with its whole output under it.
85
+ */
86
+ /* **Only the failing step's output, and the user's call.** The whole log used to be replayed, on
87
+ * the reasoning that an earlier step's output can explain a later failure. In a real build that
88
+ * put `rman check`'s file count and its own recap above every lint error, four lines of success
89
+ * the reader had to skip to reach the one that mattered. The passing steps keep a line each, so
90
+ * the order is still there; `--log-file` keeps every line. */
91
+ stepRecap(steps) {
92
+ const out = [];
93
+ for (const step of steps) {
94
+ if (step.status === 'success') {
95
+ out.push(`${colors.green('✔')} ${colors.gray(step.label)}`);
96
+ continue;
97
+ }
98
+ out.push(`${colors.red('✖')} ${step.label}`);
99
+ if (step.lines.length)
100
+ out.push(this.indentLog(step.lines.join('\n')));
101
+ }
102
+ return out.join('\n');
103
+ }
82
104
  /** Every line of a replayed log moved two columns right - an empty line left empty. */
83
105
  indentLog(text) {
84
106
  return text
@@ -284,7 +306,9 @@ export class ProgressPanel {
284
306
  *
285
307
  * **Indented two columns**, so the log reads as belonging to the `X` line above it - level
286
308
  * with the recap's own lines it ran together with them, a nested rman's recap most of all. */
287
- if (item.log.length)
309
+ if (item.steps?.length)
310
+ console.log(this.indentLog(this.stepRecap(item.steps)));
311
+ else if (item.log.length)
288
312
  console.log(this.indentLog(item.log.join('\n')));
289
313
  }
290
314
  }
@@ -349,6 +373,7 @@ class PanelItem {
349
373
  startedAt;
350
374
  finishedAt;
351
375
  log = [];
376
+ steps = [];
352
377
  _currentStep;
353
378
  _currentCommand;
354
379
  constructor(name, stepsTotal) {
@@ -54,11 +54,16 @@ export declare class PanelReporter extends PlainReporter {
54
54
  * would only be escape codes counted as text there. */
55
55
  readonly childEnv: undefined;
56
56
  constructor(commandName: string, panel: ProgressPanel);
57
- /** The row names the step itself; there is no separate line to print. */
58
- protected started(): void;
57
+ /** The row names the step itself; there is no separate line to print - but the recap needs to
58
+ * know which lines were whose, so a step is opened here. */
59
+ protected started(event: Extract<LogEvent, {
60
+ event: 'start';
61
+ }>, origin: ReportOrigin): void;
59
62
  protected output(event: Extract<LogEvent, {
60
63
  event: 'output';
61
64
  }>, origin: ReportOrigin): void;
62
- /** The row shows the step's outcome; the recap prints the package's. */
63
- protected ended(): void;
65
+ /** The row shows the step's outcome; the recap prints the package's - and reads it from here. */
66
+ protected ended(event: Extract<LogEvent, {
67
+ event: 'end';
68
+ }>, origin: ReportOrigin): void;
64
69
  }
@@ -124,12 +124,20 @@ export class PanelReporter extends PlainReporter {
124
124
  constructor(commandName, panel) {
125
125
  super(commandName, panel);
126
126
  }
127
- /** The row names the step itself; there is no separate line to print. */
128
- started() { }
127
+ /** The row names the step itself; there is no separate line to print - but the recap needs to
128
+ * know which lines were whose, so a step is opened here. */
129
+ started(event, origin) {
130
+ origin.item.steps?.push({ label: event.command ? `${event.step}: ${event.command}` : event.step, lines: [] });
131
+ }
129
132
  output(event, origin) {
130
133
  origin.item.log.push(event.line);
134
+ origin.item.steps?.at(-1)?.lines.push(event.line);
131
135
  origin.item.lastLine = event.line;
132
136
  }
133
- /** The row shows the step's outcome; the recap prints the package's. */
134
- ended() { }
137
+ /** The row shows the step's outcome; the recap prints the package's - and reads it from here. */
138
+ ended(event, origin) {
139
+ const step = origin.item.steps?.at(-1);
140
+ if (step)
141
+ step.status = event.status;
142
+ }
135
143
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rman",
3
3
  "description": "Repository manager",
4
- "version": "2.20.0",
4
+ "version": "2.21.0",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
7
7
  "dependencies": {