@lage-run/reporters 1.5.1 → 1.7.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.
Files changed (49) hide show
  1. package/lib/AdoReporter.d.ts +3 -0
  2. package/lib/AdoReporter.js +2 -2
  3. package/lib/AdoReporter.js.map +1 -1
  4. package/lib/BasicReporter.d.ts +15 -1
  5. package/lib/BasicReporter.js +38 -29
  6. package/lib/BasicReporter.js.map +1 -1
  7. package/lib/ChromeTraceEventsReporter.d.ts +3 -0
  8. package/lib/ChromeTraceEventsReporter.js +4 -5
  9. package/lib/ChromeTraceEventsReporter.js.map +1 -1
  10. package/lib/GithubActionsReporter.d.ts +3 -0
  11. package/lib/GithubActionsReporter.js +2 -2
  12. package/lib/GithubActionsReporter.js.map +1 -1
  13. package/lib/GroupedReporter.d.ts +9 -9
  14. package/lib/GroupedReporter.js +42 -63
  15. package/lib/GroupedReporter.js.map +1 -1
  16. package/lib/JsonReporter.d.ts +5 -1
  17. package/lib/JsonReporter.js +3 -3
  18. package/lib/JsonReporter.js.map +1 -1
  19. package/lib/LogReporter.d.ts +24 -2
  20. package/lib/LogReporter.js +63 -79
  21. package/lib/LogReporter.js.map +1 -1
  22. package/lib/ProgressReporter.d.ts +24 -4
  23. package/lib/ProgressReporter.js +108 -119
  24. package/lib/ProgressReporter.js.map +1 -1
  25. package/lib/VerboseFileLogReporter.d.ts +6 -1
  26. package/lib/VerboseFileLogReporter.js +27 -21
  27. package/lib/VerboseFileLogReporter.js.map +1 -1
  28. package/lib/formatDuration.d.ts +10 -0
  29. package/lib/formatDuration.js +61 -0
  30. package/lib/formatDuration.js.map +1 -0
  31. package/lib/formatHelpers.d.ts +13 -0
  32. package/lib/formatHelpers.js +61 -0
  33. package/lib/formatHelpers.js.map +1 -0
  34. package/lib/index.d.ts +1 -0
  35. package/lib/index.js +13 -0
  36. package/lib/index.js.map +1 -1
  37. package/lib/slowestTargetRuns.js +2 -2
  38. package/lib/slowestTargetRuns.js.map +1 -1
  39. package/lib/types/TargetLogData.d.ts +5 -0
  40. package/package.json +8 -10
  41. package/lib/formatBytes.d.ts +0 -1
  42. package/lib/formatBytes.js +0 -13
  43. package/lib/formatBytes.js.map +0 -1
  44. package/lib/gradient.d.ts +0 -6
  45. package/lib/gradient.js +0 -18
  46. package/lib/gradient.js.map +0 -1
  47. package/lib/types/progressBarTypes.d.ts +0 -12
  48. package/lib/types/progressBarTypes.js +0 -4
  49. package/lib/types/progressBarTypes.js.map +0 -1
@@ -1,5 +1,8 @@
1
1
  import type { TargetRun } from "@lage-run/scheduler-types";
2
2
  import { GroupedReporter } from "./GroupedReporter.js";
3
+ /**
4
+ * Reporter that formats logs for Azure DevOps, optionally with grouping.
5
+ */
3
6
  export declare class AdoReporter extends GroupedReporter {
4
7
  protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string;
5
8
  protected formatGroupEnd(): string;
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "AdoReporter", {
8
8
  return AdoReporter;
9
9
  }
10
10
  });
11
- const _formathrtime = require("@lage-run/format-hrtime");
11
+ const _formatDuration = require("./formatDuration.js");
12
12
  const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
13
13
  const _GroupedReporter = require("./GroupedReporter.js");
14
14
  function _interop_require_default(obj) {
@@ -18,7 +18,7 @@ function _interop_require_default(obj) {
18
18
  }
19
19
  class AdoReporter extends _GroupedReporter.GroupedReporter {
20
20
  formatGroupStart(packageName, task, status, duration) {
21
- return `##[group] ${_GroupedReporter.colors.pkg(packageName)} ${_GroupedReporter.colors.task(task)} ${status}${duration ? `, took ${(0, _formathrtime.formatDuration)((0, _formathrtime.hrToSeconds)(duration))}` : ""}\n`;
21
+ return `##[group] ${_GroupedReporter.colors.pkg(packageName)} ${_GroupedReporter.colors.task(task)} ${status}${duration ? `, took ${(0, _formatDuration.formatHrtime)(duration)}` : ""}\n`;
22
22
  }
23
23
  formatGroupEnd() {
24
24
  return `##[endgroup]\n`;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/AdoReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"@lage-run/format-hrtime\";\nimport chalk from \"chalk\";\nimport type { TargetRun } from \"@lage-run/scheduler-types\";\nimport { colors, GroupedReporter } from \"./GroupedReporter.js\";\n\nexport class AdoReporter extends GroupedReporter {\n protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string {\n return `##[group] ${colors.pkg(packageName)} ${colors.task(task)} ${status}${\n duration ? `, took ${formatDuration(hrToSeconds(duration))}` : \"\"\n }\\n`;\n }\n\n protected formatGroupEnd(): string {\n return `##[endgroup]\\n`;\n }\n\n protected writeSummaryHeader(): void {\n this.logStream.write(chalk.cyanBright(`##[section]Summary\\n`));\n }\n\n protected writeSummaryFooter(): void {\n // ADO sections have no closing marker\n }\n\n protected writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void {\n let packagesMessage = `##vso[task.logissue type=error]Your build failed on the following packages => `;\n\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const taskLogs = this.logEntries.get(targetId);\n\n packagesMessage += `[${packageName} ${task}], `;\n\n this.logStream.write(`##[error] [${chalk.magenta(packageName)} ${chalk.cyan(task)}] ${chalk.redBright(\"ERROR DETECTED\")}\\n`);\n\n if (taskLogs) {\n for (const entry of taskLogs) {\n // Log each entry separately to prevent truncation\n this.logStream.write(`##[error] ${entry.msg}\\n`);\n }\n }\n }\n }\n\n packagesMessage += \"find the error logs above with the prefix '##[error]!'\\n\";\n this.logStream.write(packagesMessage);\n }\n}\n"],"names":["AdoReporter","GroupedReporter","formatGroupStart","packageName","task","status","duration","colors","pkg","formatDuration","hrToSeconds","formatGroupEnd","writeSummaryHeader","logStream","write","chalk","cyanBright","writeSummaryFooter","writeFailures","failed","targetRuns","packagesMessage","targetId","target","get","taskLogs","logEntries","magenta","cyan","redBright","entry","msg"],"mappings":";;;;+BAKaA;;;eAAAA;;;8BAL+B;8DAC1B;iCAEsB;;;;;;AAEjC,MAAMA,oBAAoBC,gCAAe;IACpCC,iBAAiBC,WAAmB,EAAEC,IAAY,EAAEC,MAAc,EAAEC,QAA2B,EAAU;QACjH,OAAO,CAAC,UAAU,EAAEC,uBAAM,CAACC,GAAG,CAACL,aAAa,CAAC,EAAEI,uBAAM,CAACH,IAAI,CAACA,MAAM,CAAC,EAAEC,SAClEC,WAAW,CAAC,OAAO,EAAEG,IAAAA,4BAAc,EAACC,IAAAA,yBAAW,EAACJ,YAAY,GAAG,GAChE,EAAE,CAAC;IACN;IAEUK,iBAAyB;QACjC,OAAO,CAAC,cAAc,CAAC;IACzB;IAEUC,qBAA2B;QACnC,IAAI,CAACC,SAAS,CAACC,KAAK,CAACC,cAAK,CAACC,UAAU,CAAC,CAAC,oBAAoB,CAAC;IAC9D;IAEUC,qBAA2B;IACnC,sCAAsC;IACxC;IAEUC,cAAcC,MAAgB,EAAEC,UAA2C,EAAQ;QAC3F,IAAIC,kBAAkB,CAAC,8EAA8E,CAAC;QAEtG,KAAK,MAAMC,YAAYH,OAAQ;YAC7B,MAAMI,SAASH,WAAWI,GAAG,CAACF,WAAWC;YAEzC,IAAIA,QAAQ;gBACV,MAAM,EAAEpB,WAAW,EAAEC,IAAI,EAAE,GAAGmB;gBAC9B,MAAME,WAAW,IAAI,CAACC,UAAU,CAACF,GAAG,CAACF;gBAErCD,mBAAmB,CAAC,CAAC,EAAElB,YAAY,CAAC,EAAEC,KAAK,GAAG,CAAC;gBAE/C,IAAI,CAACS,SAAS,CAACC,KAAK,CAAC,CAAC,WAAW,EAAEC,cAAK,CAACY,OAAO,CAACxB,aAAa,CAAC,EAAEY,cAAK,CAACa,IAAI,CAACxB,MAAM,EAAE,EAAEW,cAAK,CAACc,SAAS,CAAC,kBAAkB,EAAE,CAAC;gBAE3H,IAAIJ,UAAU;oBACZ,KAAK,MAAMK,SAASL,SAAU;wBAC5B,kDAAkD;wBAClD,IAAI,CAACZ,SAAS,CAACC,KAAK,CAAC,CAAC,UAAU,EAAEgB,MAAMC,GAAG,CAAC,EAAE,CAAC;oBACjD;gBACF;YACF;QACF;QAEAV,mBAAmB;QACnB,IAAI,CAACR,SAAS,CAACC,KAAK,CAACO;IACvB;AACF"}
1
+ {"version":3,"sources":["../src/AdoReporter.ts"],"sourcesContent":["import { formatHrtime } from \"./formatDuration.js\";\nimport chalk from \"chalk\";\nimport type { TargetRun } from \"@lage-run/scheduler-types\";\nimport { colors, GroupedReporter } from \"./GroupedReporter.js\";\n\n/**\n * Reporter that formats logs for Azure DevOps, optionally with grouping.\n */\nexport class AdoReporter extends GroupedReporter {\n protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string {\n return `##[group] ${colors.pkg(packageName)} ${colors.task(task)} ${status}${duration ? `, took ${formatHrtime(duration)}` : \"\"}\\n`;\n }\n\n protected formatGroupEnd(): string {\n return `##[endgroup]\\n`;\n }\n\n protected writeSummaryHeader(): void {\n this.logStream.write(chalk.cyanBright(`##[section]Summary\\n`));\n }\n\n protected writeSummaryFooter(): void {\n // ADO sections have no closing marker\n }\n\n protected writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void {\n let packagesMessage = `##vso[task.logissue type=error]Your build failed on the following packages => `;\n\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const taskLogs = this.logEntries.get(targetId);\n\n packagesMessage += `[${packageName} ${task}], `;\n\n this.logStream.write(`##[error] [${chalk.magenta(packageName)} ${chalk.cyan(task)}] ${chalk.redBright(\"ERROR DETECTED\")}\\n`);\n\n if (taskLogs) {\n for (const entry of taskLogs) {\n // Log each entry separately to prevent truncation\n this.logStream.write(`##[error] ${entry.msg}\\n`);\n }\n }\n }\n }\n\n packagesMessage += \"find the error logs above with the prefix '##[error]!'\\n\";\n this.logStream.write(packagesMessage);\n }\n}\n"],"names":["AdoReporter","GroupedReporter","formatGroupStart","packageName","task","status","duration","colors","pkg","formatHrtime","formatGroupEnd","writeSummaryHeader","logStream","write","chalk","cyanBright","writeSummaryFooter","writeFailures","failed","targetRuns","packagesMessage","targetId","target","get","taskLogs","logEntries","magenta","cyan","redBright","entry","msg"],"mappings":";;;;+BAQaA;;;eAAAA;;;gCARgB;8DACX;iCAEsB;;;;;;AAKjC,MAAMA,oBAAoBC,gCAAe;IACpCC,iBAAiBC,WAAmB,EAAEC,IAAY,EAAEC,MAAc,EAAEC,QAA2B,EAAU;QACjH,OAAO,CAAC,UAAU,EAAEC,uBAAM,CAACC,GAAG,CAACL,aAAa,CAAC,EAAEI,uBAAM,CAACH,IAAI,CAACA,MAAM,CAAC,EAAEC,SAASC,WAAW,CAAC,OAAO,EAAEG,IAAAA,4BAAY,EAACH,WAAW,GAAG,GAAG,EAAE,CAAC;IACrI;IAEUI,iBAAyB;QACjC,OAAO,CAAC,cAAc,CAAC;IACzB;IAEUC,qBAA2B;QACnC,IAAI,CAACC,SAAS,CAACC,KAAK,CAACC,cAAK,CAACC,UAAU,CAAC,CAAC,oBAAoB,CAAC;IAC9D;IAEUC,qBAA2B;IACnC,sCAAsC;IACxC;IAEUC,cAAcC,MAAgB,EAAEC,UAA2C,EAAQ;QAC3F,IAAIC,kBAAkB,CAAC,8EAA8E,CAAC;QAEtG,KAAK,MAAMC,YAAYH,OAAQ;YAC7B,MAAMI,SAASH,WAAWI,GAAG,CAACF,WAAWC;YAEzC,IAAIA,QAAQ;gBACV,MAAM,EAAEnB,WAAW,EAAEC,IAAI,EAAE,GAAGkB;gBAC9B,MAAME,WAAW,IAAI,CAACC,UAAU,CAACF,GAAG,CAACF;gBAErCD,mBAAmB,CAAC,CAAC,EAAEjB,YAAY,CAAC,EAAEC,KAAK,GAAG,CAAC;gBAE/C,IAAI,CAACQ,SAAS,CAACC,KAAK,CAAC,CAAC,WAAW,EAAEC,cAAK,CAACY,OAAO,CAACvB,aAAa,CAAC,EAAEW,cAAK,CAACa,IAAI,CAACvB,MAAM,EAAE,EAAEU,cAAK,CAACc,SAAS,CAAC,kBAAkB,EAAE,CAAC;gBAE3H,IAAIJ,UAAU;oBACZ,KAAK,MAAMK,SAASL,SAAU;wBAC5B,kDAAkD;wBAClD,IAAI,CAACZ,SAAS,CAACC,KAAK,CAAC,CAAC,UAAU,EAAEgB,MAAMC,GAAG,CAAC,EAAE,CAAC;oBACjD;gBACF;YACF;QACF;QAEAV,mBAAmB;QACnB,IAAI,CAACR,SAAS,CAACC,KAAK,CAACO;IACvB;AACF"}
@@ -1,16 +1,30 @@
1
- import { type LogEntry, type Reporter } from "@lage-run/logger";
1
+ import type { LogEntry, Reporter } from "@lage-run/logger";
2
2
  import type { SchedulerRunSummary } from "@lage-run/scheduler-types";
3
+ import type { Writable } from "stream";
4
+ /**
5
+ * Shows running/remaining target counts and completed targets, but does not display
6
+ * the names of running targets for efficiency.
7
+ */
3
8
  export declare class BasicReporter implements Reporter {
4
9
  private taskData;
5
10
  private updateTimer;
6
11
  private startTimer;
12
+ private logMemory;
13
+ private logStream;
7
14
  constructor(params?: {
8
15
  concurrency?: number;
9
16
  version?: string;
10
17
  frequency?: number;
18
+ /** Whether to capture and report main process memory usage on target completion */
19
+ logMemory?: boolean;
20
+ /** Stream for output (defaults to process.stdout) */
21
+ logStream?: Writable;
11
22
  });
12
23
  log(entry: LogEntry): void;
13
24
  summarize(schedulerRunSummary: SchedulerRunSummary): void;
25
+ /** Clear the update timer */
26
+ cleanup(): void;
14
27
  private reportCompletion;
15
28
  private renderStatus;
29
+ private print;
16
30
  }
@@ -9,9 +9,8 @@ Object.defineProperty(exports, "BasicReporter", {
9
9
  }
10
10
  });
11
11
  const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
12
- const _gradient = require("./gradient.js");
13
- const _formathrtime = require("@lage-run/format-hrtime");
14
- const _formatBytes = require("./formatBytes.js");
12
+ const _formatDuration = require("./formatDuration.js");
13
+ const _formatHelpers = require("./formatHelpers.js");
15
14
  function _define_property(obj, key, value) {
16
15
  if (key in obj) {
17
16
  Object.defineProperty(obj, key, {
@@ -52,7 +51,6 @@ const colors = {
52
51
  task: _chalk.default.hex("#00DDDD"),
53
52
  pkg: _chalk.default.hex("#FFD66B")
54
53
  };
55
- const hrLine = "┈".repeat(80);
56
54
  const icons = {
57
55
  success: "✓",
58
56
  failed: "✗",
@@ -64,12 +62,6 @@ const terminal = {
64
62
  showCursor: "\x1b[?25h",
65
63
  clearLine: "\x1b[2K\r"
66
64
  };
67
- const fancy = (str)=>(0, _gradient.gradient)({
68
- r: 237,
69
- g: 178,
70
- b: 77
71
- }, "cyan")(str);
72
- const print = (message)=>process.stdout.write(message + "\n");
73
65
  class BasicReporter {
74
66
  log(entry) {
75
67
  const data = entry.data;
@@ -91,49 +83,55 @@ class BasicReporter {
91
83
  this.reportCompletion({
92
84
  target: data.target,
93
85
  status: data.status,
94
- duration: data.duration
86
+ duration: data.duration,
87
+ memoryUsage: data.memoryUsage
95
88
  });
96
89
  }
97
90
  }
98
91
  }
99
92
  summarize(schedulerRunSummary) {
100
93
  clearInterval(this.updateTimer);
101
- process.stdout.write(terminal.clearLine);
94
+ this.logStream.write(terminal.clearLine);
102
95
  const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;
103
96
  const { failed, aborted, skipped, success, pending } = targetRunByStatus;
104
97
  if (targetRuns.size > 0) {
105
- print(colors.summary(`\nSummary`));
106
- print(hrLine);
107
- print(`success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`);
108
- print(`worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${(0, _formatBytes.formatBytes)(schedulerRunSummary.maxWorkerMemoryUsage)}`);
98
+ this.print(colors.summary(`\nSummary`));
99
+ this.print(_formatHelpers.hrLine);
100
+ this.print(`success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`);
101
+ this.print(`worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${(0, _formatHelpers.formatBytes)(schedulerRunSummary.maxWorkerMemoryUsage)}`);
109
102
  } else {
110
- print("Nothing has been run.");
103
+ this.print("Nothing has been run.");
111
104
  }
112
- print(hrLine);
105
+ this.print(_formatHelpers.hrLine);
113
106
  for (const targetId of failed){
114
107
  const target = targetRuns.get(targetId)?.target;
115
108
  if (target) {
116
109
  const failureLogs = this.taskData.get(targetId)?.logEntries;
117
- print(`[${colors.pkg(target.packageName ?? "<root>")} ${colors.task(target.task)}] ${colors.failed("ERROR DETECTED")}`);
110
+ this.print(`[${colors.pkg(target.packageName ?? "<root>")} ${colors.task(target.task)}] ${colors.failed("ERROR DETECTED")}`);
118
111
  if (failureLogs) {
119
112
  for (const entry of failureLogs){
120
- print(entry.msg);
113
+ this.print(entry.msg);
121
114
  }
122
115
  }
123
- print(hrLine);
116
+ this.print(_formatHelpers.hrLine);
124
117
  }
125
118
  }
126
119
  const allCacheHits = [
127
120
  ...targetRuns.values()
128
121
  ].filter((run)=>!run.target.hidden).length === skipped.length;
129
- const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : "";
130
- print(`Took a total of ${(0, _formathrtime.formatDuration)((0, _formathrtime.hrToSeconds)(duration))} to complete. ${allCacheHitText}`);
122
+ const allCacheHitText = allCacheHits ? (0, _formatHelpers.fancyGradient)(`All targets skipped!`) : "";
123
+ this.print(`Took a total of ${(0, _formatDuration.formatHrtime)(duration)} to complete. ${allCacheHitText}`);
124
+ }
125
+ /** Clear the update timer */ cleanup() {
126
+ clearInterval(this.updateTimer);
127
+ this.updateTimer = undefined;
131
128
  }
132
129
  reportCompletion(completion) {
133
130
  const icon = icons[completion.status];
134
131
  const statusColor = colors[completion.status];
135
- const durationText = completion.duration ? ` (${(0, _formathrtime.formatDuration)((0, _formathrtime.hrToSeconds)(completion.duration))})` : "";
136
- const message = `${statusColor(`${icon} ${completion.status.padEnd(8)}`)} ${colors.label(completion.target.label)}${colors.duration(durationText)}`;
132
+ const durationText = completion.duration ? ` (${(0, _formatDuration.formatHrtime)(completion.duration)})` : "";
133
+ const memText = (0, _formatHelpers.formatMemoryUsage)(completion.memoryUsage, this.logMemory);
134
+ const message = `${statusColor(`${icon} ${completion.status.padEnd(8)}`)} ${colors.label(completion.target.label)}${colors.duration(durationText + memText)}`;
137
135
  this.renderStatus(message);
138
136
  }
139
137
  renderStatus(completedTaskMessage) {
@@ -156,20 +154,31 @@ class BasicReporter {
156
154
  }
157
155
  const percentage = Math.round(completed / total * 100);
158
156
  output += `${timestamp} Completed: ${completed}/${total} (${percentage}%) [${running} running, ${pending} pending]`;
159
- process.stdout.write(output);
157
+ this.logStream.write(output);
158
+ }
159
+ print(message) {
160
+ this.logStream.write(message + "\n");
160
161
  }
161
162
  constructor(params = {}){
162
163
  _define_property(this, "taskData", new Map());
163
164
  _define_property(this, "updateTimer", void 0);
164
165
  _define_property(this, "startTimer", void 0);
166
+ _define_property(this, "logMemory", void 0);
167
+ _define_property(this, "logStream", void 0);
165
168
  const { concurrency = 0, version = "0.0.0", frequency = 500 } = params;
166
- print(`${fancy("lage")} - Version ${version} - ${concurrency} Workers`);
169
+ this.logMemory = !!params.logMemory;
170
+ this.logStream = params.logStream || process.stdout;
171
+ this.print(`${(0, _formatHelpers.fancyGradient)("lage")} - Version ${version} - ${concurrency} Workers`);
167
172
  this.startTimer = ()=>{
168
173
  this.updateTimer = setInterval(()=>this.renderStatus(), frequency);
169
174
  this.updateTimer.unref();
170
175
  this.startTimer = ()=>{};
171
176
  };
172
- process.stdout.write(terminal.hideCursor);
173
- process.on("exit", ()=>process.stdout.write(terminal.showCursor));
177
+ if (!params.logStream) {
178
+ // Only hide and show the cursor if writing to the default stdout
179
+ // (definitely don't want the exit handler if writing to a custom stream)
180
+ process.stdout.write(terminal.hideCursor);
181
+ process.on("exit", ()=>process.stdout.write(terminal.showCursor));
182
+ }
174
183
  }
175
184
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/BasicReporter.ts"],"sourcesContent":["import { type LogEntry, type Reporter } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport chalk from \"chalk\";\nimport { gradient } from \"./gradient.js\";\nimport { formatDuration, hrToSeconds } from \"@lage-run/format-hrtime\";\nimport { formatBytes } from \"./formatBytes.js\";\n\ntype CoarseStatus = \"completed\" | \"running\" | \"pending\";\n\nconst coarseStatus: Record<TargetStatus, CoarseStatus> = {\n success: \"completed\",\n failed: \"completed\",\n skipped: \"completed\",\n aborted: \"completed\",\n running: \"running\",\n pending: \"pending\",\n queued: \"pending\",\n};\n\ntype CompletionStatus = \"success\" | \"failed\" | \"skipped\" | \"aborted\";\nconst isCompletionStatus = (status: TargetStatus): status is CompletionStatus => coarseStatus[status] === \"completed\";\n\nconst colors = {\n label: chalk.white,\n timestamp: chalk.gray,\n duration: chalk.gray,\n success: chalk.green,\n failed: chalk.red,\n skipped: chalk.gray,\n aborted: chalk.yellow,\n summary: chalk.cyanBright,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n};\n\nconst hrLine = \"┈\".repeat(80);\n\nconst icons: Record<CompletionStatus, string> = {\n success: \"✓\",\n failed: \"✗\",\n skipped: \"-\",\n aborted: \"-\",\n};\n\nconst terminal = {\n hideCursor: \"\\x1b[?25l\",\n showCursor: \"\\x1b[?25h\",\n clearLine: \"\\x1b[2K\\r\",\n};\n\nconst fancy = (str: string) => gradient({ r: 237, g: 178, b: 77 }, \"cyan\")(str);\nconst print = (message: string) => process.stdout.write(message + \"\\n\");\n\nexport class BasicReporter implements Reporter {\n private taskData = new Map<string, { target: Target; status: TargetStatus; logEntries: LogEntry[] }>();\n private updateTimer: NodeJS.Timeout | undefined;\n private startTimer: () => void;\n\n constructor(params: { concurrency?: number; version?: string; frequency?: number } = {}) {\n const { concurrency = 0, version = \"0.0.0\", frequency = 500 } = params;\n print(`${fancy(\"lage\")} - Version ${version} - ${concurrency} Workers`);\n\n this.startTimer = () => {\n this.updateTimer = setInterval(() => this.renderStatus(), frequency);\n this.updateTimer.unref();\n this.startTimer = () => {};\n };\n\n process.stdout.write(terminal.hideCursor);\n process.on(\"exit\", () => process.stdout.write(terminal.showCursor));\n }\n\n public log(entry: LogEntry): void {\n const data = entry.data;\n if (!data?.target || data.target.hidden) return;\n\n let taskData = this.taskData.get(data.target.id);\n if (!taskData) {\n taskData = { target: data.target, status: \"pending\", logEntries: [] };\n this.taskData.set(data.target.id, taskData);\n }\n\n this.startTimer();\n taskData.logEntries.push(entry);\n\n if (data.status) {\n taskData.status = data.status;\n if (isCompletionStatus(data.status)) {\n this.reportCompletion({ target: data.target, status: data.status, duration: data.duration });\n }\n }\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n clearInterval(this.updateTimer);\n process.stdout.write(terminal.clearLine);\n\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n if (targetRuns.size > 0) {\n print(colors.summary(`\\nSummary`));\n print(hrLine);\n print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(schedulerRunSummary.maxWorkerMemoryUsage)}`\n );\n } else {\n print(\"Nothing has been run.\");\n }\n\n print(hrLine);\n\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n if (target) {\n const failureLogs = this.taskData.get(targetId)?.logEntries;\n\n print(`[${colors.pkg(target.packageName ?? \"<root>\")} ${colors.task(target.task)}] ${colors.failed(\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n print(entry.msg);\n }\n }\n print(hrLine);\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? fancy(`All targets skipped!`) : \"\";\n\n print(`Took a total of ${formatDuration(hrToSeconds(duration))} to complete. ${allCacheHitText}`);\n }\n\n private reportCompletion(completion: { target: Target; status: CompletionStatus; duration?: [number, number] }) {\n const icon = icons[completion.status];\n const statusColor = colors[completion.status];\n const durationText = completion.duration ? ` (${formatDuration(hrToSeconds(completion.duration))})` : \"\";\n\n const message = `${statusColor(`${icon} ${completion.status.padEnd(8)}`)} ${colors.label(completion.target.label)}${colors.duration(durationText)}`;\n this.renderStatus(message);\n }\n\n private renderStatus(completedTaskMessage?: string) {\n const counts: Record<CoarseStatus, number> = { completed: 0, running: 0, pending: 0 };\n for (const data of this.taskData.values()) {\n counts[coarseStatus[data.status]]++;\n }\n const { completed, running, pending } = counts;\n const total = this.taskData.size;\n const timestamp = colors.timestamp(`[${new Date().toLocaleTimeString(\"en-US\", { hour12: false })}]`);\n\n let output = terminal.clearLine;\n if (completedTaskMessage) {\n output += `${timestamp} ${completedTaskMessage}\\n`;\n }\n const percentage = Math.round((completed / total) * 100);\n output += `${timestamp} Completed: ${completed}/${total} (${percentage}%) [${running} running, ${pending} pending]`;\n process.stdout.write(output);\n }\n}\n"],"names":["BasicReporter","coarseStatus","success","failed","skipped","aborted","running","pending","queued","isCompletionStatus","status","colors","label","chalk","white","timestamp","gray","duration","green","red","yellow","summary","cyanBright","task","hex","pkg","hrLine","repeat","icons","terminal","hideCursor","showCursor","clearLine","fancy","str","gradient","r","g","b","print","message","process","stdout","write","log","entry","data","target","hidden","taskData","get","id","logEntries","set","startTimer","push","reportCompletion","summarize","schedulerRunSummary","clearInterval","updateTimer","targetRuns","targetRunByStatus","size","length","workerRestarts","formatBytes","maxWorkerMemoryUsage","targetId","failureLogs","packageName","msg","allCacheHits","values","filter","run","allCacheHitText","formatDuration","hrToSeconds","completion","icon","statusColor","durationText","padEnd","renderStatus","completedTaskMessage","counts","completed","total","Date","toLocaleTimeString","hour12","output","percentage","Math","round","params","Map","concurrency","version","frequency","setInterval","unref","on"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/BasicReporter.ts"],"sourcesContent":["import type { LogEntry, Reporter } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetStatus } from \"@lage-run/scheduler-types\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport type { Writable } from \"stream\";\nimport chalk from \"chalk\";\nimport { formatHrtime } from \"./formatDuration.js\";\nimport { fancyGradient, formatBytes, formatMemoryUsage, hrLine } from \"./formatHelpers.js\";\n\ntype CoarseStatus = \"completed\" | \"running\" | \"pending\";\n\nconst coarseStatus: Record<TargetStatus, CoarseStatus> = {\n success: \"completed\",\n failed: \"completed\",\n skipped: \"completed\",\n aborted: \"completed\",\n running: \"running\",\n pending: \"pending\",\n queued: \"pending\",\n};\n\ntype CompletionStatus = \"success\" | \"failed\" | \"skipped\" | \"aborted\";\nconst isCompletionStatus = (status: TargetStatus): status is CompletionStatus => coarseStatus[status] === \"completed\";\n\nconst colors = {\n label: chalk.white,\n timestamp: chalk.gray,\n duration: chalk.gray,\n success: chalk.green,\n failed: chalk.red,\n skipped: chalk.gray,\n aborted: chalk.yellow,\n summary: chalk.cyanBright,\n task: chalk.hex(\"#00DDDD\"),\n pkg: chalk.hex(\"#FFD66B\"),\n};\n\nconst icons: Record<CompletionStatus, string> = {\n success: \"✓\",\n failed: \"✗\",\n skipped: \"-\",\n aborted: \"-\",\n};\n\nconst terminal = {\n hideCursor: \"\\x1b[?25l\",\n showCursor: \"\\x1b[?25h\",\n clearLine: \"\\x1b[2K\\r\",\n};\n\n/**\n * Shows running/remaining target counts and completed targets, but does not display\n * the names of running targets for efficiency.\n */\nexport class BasicReporter implements Reporter {\n private taskData = new Map<string, { target: Target; status: TargetStatus; logEntries: LogEntry[] }>();\n private updateTimer: NodeJS.Timeout | undefined;\n private startTimer: () => void;\n private logMemory: boolean;\n private logStream: Writable;\n\n constructor(\n params: {\n concurrency?: number;\n version?: string;\n frequency?: number;\n /** Whether to capture and report main process memory usage on target completion */\n logMemory?: boolean;\n /** Stream for output (defaults to process.stdout) */\n logStream?: Writable;\n } = {}\n ) {\n const { concurrency = 0, version = \"0.0.0\", frequency = 500 } = params;\n this.logMemory = !!params.logMemory;\n this.logStream = params.logStream || process.stdout;\n this.print(`${fancyGradient(\"lage\")} - Version ${version} - ${concurrency} Workers`);\n\n this.startTimer = () => {\n this.updateTimer = setInterval(() => this.renderStatus(), frequency);\n this.updateTimer.unref();\n this.startTimer = () => {};\n };\n\n if (!params.logStream) {\n // Only hide and show the cursor if writing to the default stdout\n // (definitely don't want the exit handler if writing to a custom stream)\n process.stdout.write(terminal.hideCursor);\n process.on(\"exit\", () => process.stdout.write(terminal.showCursor));\n }\n }\n\n public log(entry: LogEntry): void {\n const data = entry.data;\n if (!data?.target || data.target.hidden) return;\n\n let taskData = this.taskData.get(data.target.id);\n if (!taskData) {\n taskData = { target: data.target, status: \"pending\", logEntries: [] };\n this.taskData.set(data.target.id, taskData);\n }\n\n this.startTimer();\n taskData.logEntries.push(entry);\n\n if (data.status) {\n taskData.status = data.status;\n if (isCompletionStatus(data.status)) {\n this.reportCompletion({ target: data.target, status: data.status, duration: data.duration, memoryUsage: data.memoryUsage });\n }\n }\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n clearInterval(this.updateTimer);\n this.logStream.write(terminal.clearLine);\n\n const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;\n const { failed, aborted, skipped, success, pending } = targetRunByStatus;\n\n if (targetRuns.size > 0) {\n this.print(colors.summary(`\\nSummary`));\n this.print(hrLine);\n this.print(\n `success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}, failed: ${failed.length}`\n );\n this.print(\n `worker restarts: ${schedulerRunSummary.workerRestarts}, max worker memory usage: ${formatBytes(schedulerRunSummary.maxWorkerMemoryUsage)}`\n );\n } else {\n this.print(\"Nothing has been run.\");\n }\n\n this.print(hrLine);\n\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n if (target) {\n const failureLogs = this.taskData.get(targetId)?.logEntries;\n\n this.print(`[${colors.pkg(target.packageName ?? \"<root>\")} ${colors.task(target.task)}] ${colors.failed(\"ERROR DETECTED\")}`);\n\n if (failureLogs) {\n for (const entry of failureLogs) {\n this.print(entry.msg);\n }\n }\n this.print(hrLine);\n }\n }\n\n const allCacheHits = [...targetRuns.values()].filter((run) => !run.target.hidden).length === skipped.length;\n const allCacheHitText = allCacheHits ? fancyGradient(`All targets skipped!`) : \"\";\n\n this.print(`Took a total of ${formatHrtime(duration)} to complete. ${allCacheHitText}`);\n }\n\n /** Clear the update timer */\n public cleanup(): void {\n clearInterval(this.updateTimer);\n this.updateTimer = undefined;\n }\n\n private reportCompletion(completion: {\n target: Target;\n status: CompletionStatus;\n duration?: [number, number];\n memoryUsage?: NodeJS.MemoryUsage;\n }) {\n const icon = icons[completion.status];\n const statusColor = colors[completion.status];\n const durationText = completion.duration ? ` (${formatHrtime(completion.duration)})` : \"\";\n const memText = formatMemoryUsage(completion.memoryUsage, this.logMemory);\n\n const message = `${statusColor(`${icon} ${completion.status.padEnd(8)}`)} ${colors.label(completion.target.label)}${colors.duration(durationText + memText)}`;\n this.renderStatus(message);\n }\n\n private renderStatus(completedTaskMessage?: string) {\n const counts: Record<CoarseStatus, number> = { completed: 0, running: 0, pending: 0 };\n for (const data of this.taskData.values()) {\n counts[coarseStatus[data.status]]++;\n }\n const { completed, running, pending } = counts;\n const total = this.taskData.size;\n const timestamp = colors.timestamp(`[${new Date().toLocaleTimeString(\"en-US\", { hour12: false })}]`);\n\n let output = terminal.clearLine;\n if (completedTaskMessage) {\n output += `${timestamp} ${completedTaskMessage}\\n`;\n }\n const percentage = Math.round((completed / total) * 100);\n output += `${timestamp} Completed: ${completed}/${total} (${percentage}%) [${running} running, ${pending} pending]`;\n this.logStream.write(output);\n }\n\n private print(message: string): void {\n this.logStream.write(message + \"\\n\");\n }\n}\n"],"names":["BasicReporter","coarseStatus","success","failed","skipped","aborted","running","pending","queued","isCompletionStatus","status","colors","label","chalk","white","timestamp","gray","duration","green","red","yellow","summary","cyanBright","task","hex","pkg","icons","terminal","hideCursor","showCursor","clearLine","log","entry","data","target","hidden","taskData","get","id","logEntries","set","startTimer","push","reportCompletion","memoryUsage","summarize","schedulerRunSummary","clearInterval","updateTimer","logStream","write","targetRuns","targetRunByStatus","size","print","hrLine","length","workerRestarts","formatBytes","maxWorkerMemoryUsage","targetId","failureLogs","packageName","msg","allCacheHits","values","filter","run","allCacheHitText","fancyGradient","formatHrtime","cleanup","undefined","completion","icon","statusColor","durationText","memText","formatMemoryUsage","logMemory","message","padEnd","renderStatus","completedTaskMessage","counts","completed","total","Date","toLocaleTimeString","hour12","output","percentage","Math","round","params","Map","concurrency","version","frequency","process","stdout","setInterval","unref","on"],"mappings":"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"}
@@ -6,6 +6,9 @@ export interface ChromeTraceEventsReporterOptions {
6
6
  concurrency: number;
7
7
  categorize?: (targetRun?: TargetRun) => string;
8
8
  }
9
+ /**
10
+ * Reporter that generates a Chrome dev tools profile file.
11
+ */
9
12
  export declare class ChromeTraceEventsReporter implements Reporter {
10
13
  private options;
11
14
  private consoleLogStream;
@@ -69,11 +69,10 @@ class ChromeTraceEventsReporter {
69
69
  }
70
70
  this.events.traceEvents.push(event);
71
71
  }
72
- if (!_fs.default.existsSync(_path.default.dirname(this.outputFile))) {
73
- _fs.default.mkdirSync(_path.default.dirname(this.outputFile), {
74
- recursive: true
75
- });
76
- }
72
+ // make the directory if it doesn't exist (no-op if exists)
73
+ _fs.default.mkdirSync(_path.default.dirname(this.outputFile), {
74
+ recursive: true
75
+ });
77
76
  _fs.default.writeFileSync(this.outputFile, JSON.stringify(this.events, null, 2));
78
77
  this.consoleLogStream.write(_chalk.default.blueBright(`\nProfiler output written to ${_chalk.default.underline(this.outputFile)}, open it with chrome://tracing or edge://tracing\n`));
79
78
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ChromeTraceEventsReporter.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport type { Reporter } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetRun } from \"@lage-run/scheduler-types\";\nimport type { Writable } from \"stream\";\n\ninterface TraceEventsObject {\n traceEvents: CompleteEvent[];\n displayTimeUnit: \"ms\" | \"ns\";\n}\n\ninterface CompleteEvent {\n name: string;\n cat: string; // status#task\n ph: \"X\";\n ts: number; // in microseconds\n pid: number;\n tid: number;\n dur: number;\n args?: Record<string, any>;\n}\n\nexport interface ChromeTraceEventsReporterOptions {\n outputFile?: string;\n concurrency: number;\n categorize?: (targetRun?: TargetRun) => string;\n}\n\nfunction hrTimeToMicroseconds(hr: [number, number]) {\n return hr[0] * 1e6 + hr[1] * 1e-3;\n}\n\nfunction getTimeBasedFilename(prefix: string) {\n const now = new Date(); // 2011-10-05T14:48:00.000Z\n const datetime = now.toISOString().split(\".\")[0]; // 2011-10-05T14:48:00\n const datetimeNormalized = datetime.replace(/-|:/g, \"\"); // 20111005T144800\n return `${prefix ? prefix + \"-\" : \"\"}${datetimeNormalized}.json`;\n}\n\nexport class ChromeTraceEventsReporter implements Reporter {\n private consoleLogStream: Writable;\n\n private events: TraceEventsObject = {\n traceEvents: [],\n displayTimeUnit: \"ms\",\n };\n private outputFile: string;\n\n constructor(\n private options: ChromeTraceEventsReporterOptions & {\n /** stream for testing */\n consoleLogStream?: Writable;\n }\n ) {\n this.outputFile = options.outputFile ?? getTimeBasedFilename(\"profile\");\n this.consoleLogStream = options.consoleLogStream ?? process.stdout;\n }\n\n public log(): void {\n // pass\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, startTime } = schedulerRunSummary;\n\n // categorize events\n const { categorize } = this.options;\n\n for (const targetRun of targetRuns.values()) {\n // Skip hidden targets because those should be hidden by reporters.\n // Hiding as well skipped targets to avoid polluting the profile.\n if (targetRun.target.hidden || targetRun.status === \"skipped\") {\n continue;\n }\n\n const event = {\n name: targetRun.target.id,\n cat: `${targetRun.status}#${targetRun.target.task}`,\n ph: \"X\",\n ts: hrTimeToMicroseconds(targetRun.startTime) - hrTimeToMicroseconds(startTime), // in microseconds\n dur: hrTimeToMicroseconds(targetRun.duration ?? [0, 1000]), // in microseconds\n pid: 1,\n tid: targetRun.threadId,\n } as CompleteEvent;\n\n if (categorize) {\n event.cat += `,${categorize(targetRun)}`;\n }\n\n this.events.traceEvents.push(event);\n }\n\n if (!fs.existsSync(path.dirname(this.outputFile))) {\n fs.mkdirSync(path.dirname(this.outputFile), { recursive: true });\n }\n\n fs.writeFileSync(this.outputFile, JSON.stringify(this.events, null, 2));\n\n this.consoleLogStream.write(\n chalk.blueBright(\n `\\nProfiler output written to ${chalk.underline(this.outputFile)}, open it with chrome://tracing or edge://tracing\\n`\n )\n );\n }\n}\n"],"names":["ChromeTraceEventsReporter","hrTimeToMicroseconds","hr","getTimeBasedFilename","prefix","now","Date","datetime","toISOString","split","datetimeNormalized","replace","log","summarize","schedulerRunSummary","targetRuns","startTime","categorize","options","targetRun","values","target","hidden","status","event","name","id","cat","task","ph","ts","dur","duration","pid","tid","threadId","events","traceEvents","push","fs","existsSync","path","dirname","outputFile","mkdirSync","recursive","writeFileSync","JSON","stringify","consoleLogStream","write","chalk","blueBright","underline","displayTimeUnit","process","stdout"],"mappings":";;;;+BAwCaA;;;eAAAA;;;8DAxCK;2DACH;6DACE;;;;;;;;;;;;;;;;;;;AA2BjB,SAASC,qBAAqBC,EAAoB;IAChD,OAAOA,EAAE,CAAC,EAAE,GAAG,MAAMA,EAAE,CAAC,EAAE,GAAG;AAC/B;AAEA,SAASC,qBAAqBC,MAAc;IAC1C,MAAMC,MAAM,IAAIC,QAAQ,2BAA2B;IACnD,MAAMC,WAAWF,IAAIG,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,sBAAsB;IACxE,MAAMC,qBAAqBH,SAASI,OAAO,CAAC,QAAQ,KAAK,kBAAkB;IAC3E,OAAO,GAAGP,SAASA,SAAS,MAAM,KAAKM,mBAAmB,KAAK,CAAC;AAClE;AAEO,MAAMV;IAmBJY,MAAY;IACjB,OAAO;IACT;IAEOC,UAAUC,mBAAwC,EAAQ;QAC/D,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAE,GAAGF;QAElC,oBAAoB;QACpB,MAAM,EAAEG,UAAU,EAAE,GAAG,IAAI,CAACC,OAAO;QAEnC,KAAK,MAAMC,aAAaJ,WAAWK,MAAM,GAAI;YAC3C,mEAAmE;YACnE,iEAAiE;YACjE,IAAID,UAAUE,MAAM,CAACC,MAAM,IAAIH,UAAUI,MAAM,KAAK,WAAW;gBAC7D;YACF;YAEA,MAAMC,QAAQ;gBACZC,MAAMN,UAAUE,MAAM,CAACK,EAAE;gBACzBC,KAAK,GAAGR,UAAUI,MAAM,CAAC,CAAC,EAAEJ,UAAUE,MAAM,CAACO,IAAI,EAAE;gBACnDC,IAAI;gBACJC,IAAI7B,qBAAqBkB,UAAUH,SAAS,IAAIf,qBAAqBe;gBACrEe,KAAK9B,qBAAqBkB,UAAUa,QAAQ,IAAI;oBAAC;oBAAG;iBAAK;gBACzDC,KAAK;gBACLC,KAAKf,UAAUgB,QAAQ;YACzB;YAEA,IAAIlB,YAAY;gBACdO,MAAMG,GAAG,IAAI,CAAC,CAAC,EAAEV,WAAWE,YAAY;YAC1C;YAEA,IAAI,CAACiB,MAAM,CAACC,WAAW,CAACC,IAAI,CAACd;QAC/B;QAEA,IAAI,CAACe,WAAE,CAACC,UAAU,CAACC,aAAI,CAACC,OAAO,CAAC,IAAI,CAACC,UAAU,IAAI;YACjDJ,WAAE,CAACK,SAAS,CAACH,aAAI,CAACC,OAAO,CAAC,IAAI,CAACC,UAAU,GAAG;gBAAEE,WAAW;YAAK;QAChE;QAEAN,WAAE,CAACO,aAAa,CAAC,IAAI,CAACH,UAAU,EAAEI,KAAKC,SAAS,CAAC,IAAI,CAACZ,MAAM,EAAE,MAAM;QAEpE,IAAI,CAACa,gBAAgB,CAACC,KAAK,CACzBC,cAAK,CAACC,UAAU,CACd,CAAC,6BAA6B,EAAED,cAAK,CAACE,SAAS,CAAC,IAAI,CAACV,UAAU,EAAE,mDAAmD,CAAC;IAG3H;IAvDA,YACE,AAAQzB,OAGP,CACD;;QAbF,uBAAQ+B,oBAAR,KAAA;QAEA,uBAAQb,UAAR,KAAA;QAIA,uBAAQO,cAAR,KAAA;aAGUzB,UAAAA;aAPFkB,SAA4B;YAClCC,aAAa,EAAE;YACfiB,iBAAiB;QACnB;QASE,IAAI,CAACX,UAAU,GAAGzB,QAAQyB,UAAU,IAAIxC,qBAAqB;QAC7D,IAAI,CAAC8C,gBAAgB,GAAG/B,QAAQ+B,gBAAgB,IAAIM,QAAQC,MAAM;IACpE;AAgDF"}
1
+ {"version":3,"sources":["../src/ChromeTraceEventsReporter.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport type { Reporter } from \"@lage-run/logger\";\nimport type { SchedulerRunSummary, TargetRun } from \"@lage-run/scheduler-types\";\nimport type { Writable } from \"stream\";\n\ninterface TraceEventsObject {\n traceEvents: CompleteEvent[];\n displayTimeUnit: \"ms\" | \"ns\";\n}\n\ninterface CompleteEvent {\n name: string;\n cat: string; // status#task\n ph: \"X\";\n ts: number; // in microseconds\n pid: number;\n tid: number;\n dur: number;\n args?: Record<string, any>;\n}\n\nexport interface ChromeTraceEventsReporterOptions {\n outputFile?: string;\n concurrency: number;\n categorize?: (targetRun?: TargetRun) => string;\n}\n\nfunction hrTimeToMicroseconds(hr: [number, number]) {\n return hr[0] * 1e6 + hr[1] * 1e-3;\n}\n\nfunction getTimeBasedFilename(prefix: string) {\n const now = new Date(); // 2011-10-05T14:48:00.000Z\n const datetime = now.toISOString().split(\".\")[0]; // 2011-10-05T14:48:00\n const datetimeNormalized = datetime.replace(/-|:/g, \"\"); // 20111005T144800\n return `${prefix ? prefix + \"-\" : \"\"}${datetimeNormalized}.json`;\n}\n\n/**\n * Reporter that generates a Chrome dev tools profile file.\n */\nexport class ChromeTraceEventsReporter implements Reporter {\n private consoleLogStream: Writable;\n\n private events: TraceEventsObject = {\n traceEvents: [],\n displayTimeUnit: \"ms\",\n };\n private outputFile: string;\n\n constructor(\n private options: ChromeTraceEventsReporterOptions & {\n /** stream for testing */\n consoleLogStream?: Writable;\n }\n ) {\n this.outputFile = options.outputFile ?? getTimeBasedFilename(\"profile\");\n this.consoleLogStream = options.consoleLogStream ?? process.stdout;\n }\n\n public log(): void {\n // pass\n }\n\n public summarize(schedulerRunSummary: SchedulerRunSummary): void {\n const { targetRuns, startTime } = schedulerRunSummary;\n\n // categorize events\n const { categorize } = this.options;\n\n for (const targetRun of targetRuns.values()) {\n // Skip hidden targets because those should be hidden by reporters.\n // Hiding as well skipped targets to avoid polluting the profile.\n if (targetRun.target.hidden || targetRun.status === \"skipped\") {\n continue;\n }\n\n const event: CompleteEvent = {\n name: targetRun.target.id,\n cat: `${targetRun.status}#${targetRun.target.task}`,\n ph: \"X\",\n ts: hrTimeToMicroseconds(targetRun.startTime) - hrTimeToMicroseconds(startTime), // in microseconds\n dur: hrTimeToMicroseconds(targetRun.duration ?? [0, 1000]), // in microseconds\n pid: 1,\n tid: targetRun.threadId,\n };\n\n if (categorize) {\n event.cat += `,${categorize(targetRun)}`;\n }\n\n this.events.traceEvents.push(event);\n }\n\n // make the directory if it doesn't exist (no-op if exists)\n fs.mkdirSync(path.dirname(this.outputFile), { recursive: true });\n\n fs.writeFileSync(this.outputFile, JSON.stringify(this.events, null, 2));\n\n this.consoleLogStream.write(\n chalk.blueBright(\n `\\nProfiler output written to ${chalk.underline(this.outputFile)}, open it with chrome://tracing or edge://tracing\\n`\n )\n );\n }\n}\n"],"names":["ChromeTraceEventsReporter","hrTimeToMicroseconds","hr","getTimeBasedFilename","prefix","now","Date","datetime","toISOString","split","datetimeNormalized","replace","log","summarize","schedulerRunSummary","targetRuns","startTime","categorize","options","targetRun","values","target","hidden","status","event","name","id","cat","task","ph","ts","dur","duration","pid","tid","threadId","events","traceEvents","push","fs","mkdirSync","path","dirname","outputFile","recursive","writeFileSync","JSON","stringify","consoleLogStream","write","chalk","blueBright","underline","displayTimeUnit","process","stdout"],"mappings":";;;;+BA2CaA;;;eAAAA;;;8DA3CK;2DACH;6DACE;;;;;;;;;;;;;;;;;;;AA2BjB,SAASC,qBAAqBC,EAAoB;IAChD,OAAOA,EAAE,CAAC,EAAE,GAAG,MAAMA,EAAE,CAAC,EAAE,GAAG;AAC/B;AAEA,SAASC,qBAAqBC,MAAc;IAC1C,MAAMC,MAAM,IAAIC,QAAQ,2BAA2B;IACnD,MAAMC,WAAWF,IAAIG,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,sBAAsB;IACxE,MAAMC,qBAAqBH,SAASI,OAAO,CAAC,QAAQ,KAAK,kBAAkB;IAC3E,OAAO,GAAGP,SAASA,SAAS,MAAM,KAAKM,mBAAmB,KAAK,CAAC;AAClE;AAKO,MAAMV;IAmBJY,MAAY;IACjB,OAAO;IACT;IAEOC,UAAUC,mBAAwC,EAAQ;QAC/D,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAE,GAAGF;QAElC,oBAAoB;QACpB,MAAM,EAAEG,UAAU,EAAE,GAAG,IAAI,CAACC,OAAO;QAEnC,KAAK,MAAMC,aAAaJ,WAAWK,MAAM,GAAI;YAC3C,mEAAmE;YACnE,iEAAiE;YACjE,IAAID,UAAUE,MAAM,CAACC,MAAM,IAAIH,UAAUI,MAAM,KAAK,WAAW;gBAC7D;YACF;YAEA,MAAMC,QAAuB;gBAC3BC,MAAMN,UAAUE,MAAM,CAACK,EAAE;gBACzBC,KAAK,GAAGR,UAAUI,MAAM,CAAC,CAAC,EAAEJ,UAAUE,MAAM,CAACO,IAAI,EAAE;gBACnDC,IAAI;gBACJC,IAAI7B,qBAAqBkB,UAAUH,SAAS,IAAIf,qBAAqBe;gBACrEe,KAAK9B,qBAAqBkB,UAAUa,QAAQ,IAAI;oBAAC;oBAAG;iBAAK;gBACzDC,KAAK;gBACLC,KAAKf,UAAUgB,QAAQ;YACzB;YAEA,IAAIlB,YAAY;gBACdO,MAAMG,GAAG,IAAI,CAAC,CAAC,EAAEV,WAAWE,YAAY;YAC1C;YAEA,IAAI,CAACiB,MAAM,CAACC,WAAW,CAACC,IAAI,CAACd;QAC/B;QAEA,2DAA2D;QAC3De,WAAE,CAACC,SAAS,CAACC,aAAI,CAACC,OAAO,CAAC,IAAI,CAACC,UAAU,GAAG;YAAEC,WAAW;QAAK;QAE9DL,WAAE,CAACM,aAAa,CAAC,IAAI,CAACF,UAAU,EAAEG,KAAKC,SAAS,CAAC,IAAI,CAACX,MAAM,EAAE,MAAM;QAEpE,IAAI,CAACY,gBAAgB,CAACC,KAAK,CACzBC,cAAK,CAACC,UAAU,CACd,CAAC,6BAA6B,EAAED,cAAK,CAACE,SAAS,CAAC,IAAI,CAACT,UAAU,EAAE,mDAAmD,CAAC;IAG3H;IAtDA,YACE,AAAQzB,OAGP,CACD;;QAbF,uBAAQ8B,oBAAR,KAAA;QAEA,uBAAQZ,UAAR,KAAA;QAIA,uBAAQO,cAAR,KAAA;aAGUzB,UAAAA;aAPFkB,SAA4B;YAClCC,aAAa,EAAE;YACfgB,iBAAiB;QACnB;QASE,IAAI,CAACV,UAAU,GAAGzB,QAAQyB,UAAU,IAAIxC,qBAAqB;QAC7D,IAAI,CAAC6C,gBAAgB,GAAG9B,QAAQ8B,gBAAgB,IAAIM,QAAQC,MAAM;IACpE;AA+CF"}
@@ -1,5 +1,8 @@
1
1
  import type { TargetRun } from "@lage-run/scheduler-types";
2
2
  import { GroupedReporter } from "./GroupedReporter.js";
3
+ /**
4
+ * Reporter that formats logs for GitHub Actions, optionally with grouping.
5
+ */
3
6
  export declare class GithubActionsReporter extends GroupedReporter {
4
7
  protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string;
5
8
  protected formatGroupEnd(): string;
@@ -8,11 +8,11 @@ Object.defineProperty(exports, "GithubActionsReporter", {
8
8
  return GithubActionsReporter;
9
9
  }
10
10
  });
11
- const _formathrtime = require("@lage-run/format-hrtime");
11
+ const _formatDuration = require("./formatDuration.js");
12
12
  const _GroupedReporter = require("./GroupedReporter.js");
13
13
  class GithubActionsReporter extends _GroupedReporter.GroupedReporter {
14
14
  formatGroupStart(packageName, task, status, duration) {
15
- return `::group::${packageName} ${task} ${status}${duration ? `, took ${(0, _formathrtime.formatDuration)((0, _formathrtime.hrToSeconds)(duration))}` : ""}\n`;
15
+ return `::group::${packageName} ${task} ${status}${duration ? `, took ${(0, _formatDuration.formatHrtime)(duration)}` : ""}\n`;
16
16
  }
17
17
  formatGroupEnd() {
18
18
  return `::endgroup::\n`;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/GithubActionsReporter.ts"],"sourcesContent":["import { formatDuration, hrToSeconds } from \"@lage-run/format-hrtime\";\nimport type { TargetRun } from \"@lage-run/scheduler-types\";\nimport { GroupedReporter } from \"./GroupedReporter.js\";\n\nexport class GithubActionsReporter extends GroupedReporter {\n protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string {\n return `::group::${packageName} ${task} ${status}${duration ? `, took ${formatDuration(hrToSeconds(duration))}` : \"\"}\\n`;\n }\n\n protected formatGroupEnd(): string {\n return `::endgroup::\\n`;\n }\n\n protected writeSummaryHeader(): void {\n this.logStream.write(`::group::Summary\\n`);\n }\n\n protected writeSummaryFooter(): void {\n this.logStream.write(`::endgroup::\\n`);\n }\n\n protected writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void {\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const taskLogs = this.logEntries.get(targetId);\n\n this.logStream.write(`::error title=${packageName} ${task}::Build failed\\n`);\n\n if (taskLogs) {\n for (const entry of taskLogs) {\n if (entry.msg.trim() !== \"\") {\n this.logStream.write(`::error::${entry.msg}\\n`);\n }\n }\n }\n }\n }\n }\n}\n"],"names":["GithubActionsReporter","GroupedReporter","formatGroupStart","packageName","task","status","duration","formatDuration","hrToSeconds","formatGroupEnd","writeSummaryHeader","logStream","write","writeSummaryFooter","writeFailures","failed","targetRuns","targetId","target","get","taskLogs","logEntries","entry","msg","trim"],"mappings":";;;;+BAIaA;;;eAAAA;;;8BAJ+B;iCAEZ;AAEzB,MAAMA,8BAA8BC,gCAAe;IAC9CC,iBAAiBC,WAAmB,EAAEC,IAAY,EAAEC,MAAc,EAAEC,QAA2B,EAAU;QACjH,OAAO,CAAC,SAAS,EAAEH,YAAY,CAAC,EAAEC,KAAK,CAAC,EAAEC,SAASC,WAAW,CAAC,OAAO,EAAEC,IAAAA,4BAAc,EAACC,IAAAA,yBAAW,EAACF,YAAY,GAAG,GAAG,EAAE,CAAC;IAC1H;IAEUG,iBAAyB;QACjC,OAAO,CAAC,cAAc,CAAC;IACzB;IAEUC,qBAA2B;QACnC,IAAI,CAACC,SAAS,CAACC,KAAK,CAAC,CAAC,kBAAkB,CAAC;IAC3C;IAEUC,qBAA2B;QACnC,IAAI,CAACF,SAAS,CAACC,KAAK,CAAC,CAAC,cAAc,CAAC;IACvC;IAEUE,cAAcC,MAAgB,EAAEC,UAA2C,EAAQ;QAC3F,KAAK,MAAMC,YAAYF,OAAQ;YAC7B,MAAMG,SAASF,WAAWG,GAAG,CAACF,WAAWC;YAEzC,IAAIA,QAAQ;gBACV,MAAM,EAAEf,WAAW,EAAEC,IAAI,EAAE,GAAGc;gBAC9B,MAAME,WAAW,IAAI,CAACC,UAAU,CAACF,GAAG,CAACF;gBAErC,IAAI,CAACN,SAAS,CAACC,KAAK,CAAC,CAAC,cAAc,EAAET,YAAY,CAAC,EAAEC,KAAK,gBAAgB,CAAC;gBAE3E,IAAIgB,UAAU;oBACZ,KAAK,MAAME,SAASF,SAAU;wBAC5B,IAAIE,MAAMC,GAAG,CAACC,IAAI,OAAO,IAAI;4BAC3B,IAAI,CAACb,SAAS,CAACC,KAAK,CAAC,CAAC,SAAS,EAAEU,MAAMC,GAAG,CAAC,EAAE,CAAC;wBAChD;oBACF;gBACF;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../src/GithubActionsReporter.ts"],"sourcesContent":["import { formatHrtime } from \"./formatDuration.js\";\nimport type { TargetRun } from \"@lage-run/scheduler-types\";\nimport { GroupedReporter } from \"./GroupedReporter.js\";\n\n/**\n * Reporter that formats logs for GitHub Actions, optionally with grouping.\n */\nexport class GithubActionsReporter extends GroupedReporter {\n protected formatGroupStart(packageName: string, task: string, status: string, duration?: [number, number]): string {\n return `::group::${packageName} ${task} ${status}${duration ? `, took ${formatHrtime(duration)}` : \"\"}\\n`;\n }\n\n protected formatGroupEnd(): string {\n return `::endgroup::\\n`;\n }\n\n protected writeSummaryHeader(): void {\n this.logStream.write(`::group::Summary\\n`);\n }\n\n protected writeSummaryFooter(): void {\n this.logStream.write(`::endgroup::\\n`);\n }\n\n protected writeFailures(failed: string[], targetRuns: Map<string, TargetRun<unknown>>): void {\n for (const targetId of failed) {\n const target = targetRuns.get(targetId)?.target;\n\n if (target) {\n const { packageName, task } = target;\n const taskLogs = this.logEntries.get(targetId);\n\n this.logStream.write(`::error title=${packageName} ${task}::Build failed\\n`);\n\n if (taskLogs) {\n for (const entry of taskLogs) {\n if (entry.msg.trim() !== \"\") {\n this.logStream.write(`::error::${entry.msg}\\n`);\n }\n }\n }\n }\n }\n }\n}\n"],"names":["GithubActionsReporter","GroupedReporter","formatGroupStart","packageName","task","status","duration","formatHrtime","formatGroupEnd","writeSummaryHeader","logStream","write","writeSummaryFooter","writeFailures","failed","targetRuns","targetId","target","get","taskLogs","logEntries","entry","msg","trim"],"mappings":";;;;+BAOaA;;;eAAAA;;;gCAPgB;iCAEG;AAKzB,MAAMA,8BAA8BC,gCAAe;IAC9CC,iBAAiBC,WAAmB,EAAEC,IAAY,EAAEC,MAAc,EAAEC,QAA2B,EAAU;QACjH,OAAO,CAAC,SAAS,EAAEH,YAAY,CAAC,EAAEC,KAAK,CAAC,EAAEC,SAASC,WAAW,CAAC,OAAO,EAAEC,IAAAA,4BAAY,EAACD,WAAW,GAAG,GAAG,EAAE,CAAC;IAC3G;IAEUE,iBAAyB;QACjC,OAAO,CAAC,cAAc,CAAC;IACzB;IAEUC,qBAA2B;QACnC,IAAI,CAACC,SAAS,CAACC,KAAK,CAAC,CAAC,kBAAkB,CAAC;IAC3C;IAEUC,qBAA2B;QACnC,IAAI,CAACF,SAAS,CAACC,KAAK,CAAC,CAAC,cAAc,CAAC;IACvC;IAEUE,cAAcC,MAAgB,EAAEC,UAA2C,EAAQ;QAC3F,KAAK,MAAMC,YAAYF,OAAQ;YAC7B,MAAMG,SAASF,WAAWG,GAAG,CAACF,WAAWC;YAEzC,IAAIA,QAAQ;gBACV,MAAM,EAAEd,WAAW,EAAEC,IAAI,EAAE,GAAGa;gBAC9B,MAAME,WAAW,IAAI,CAACC,UAAU,CAACF,GAAG,CAACF;gBAErC,IAAI,CAACN,SAAS,CAACC,KAAK,CAAC,CAAC,cAAc,EAAER,YAAY,CAAC,EAAEC,KAAK,gBAAgB,CAAC;gBAE3E,IAAIe,UAAU;oBACZ,KAAK,MAAME,SAASF,SAAU;wBAC5B,IAAIE,MAAMC,GAAG,CAACC,IAAI,OAAO,IAAI;4BAC3B,IAAI,CAACb,SAAS,CAACC,KAAK,CAAC,CAAC,SAAS,EAAEU,MAAMC,GAAG,CAAC,EAAE,CAAC;wBAChD;oBACF;gBACF;YACF;QACF;IACF;AACF"}
@@ -16,19 +16,16 @@ export declare const colors: {
16
16
  error: chalk.Chalk;
17
17
  warn: chalk.Chalk;
18
18
  };
19
- export declare const logLevelLabel: {
20
- 30: string;
21
- 20: string;
22
- 10: string;
23
- 50: string;
24
- 40: string;
25
- };
26
- export declare function getTaskLogPrefix(pkg: string, task: string): string;
27
- export declare function format(level: LogLevel, prefix: string, message: string): string;
19
+ /**
20
+ * Abstract reporter which optionally groups log entries by target.
21
+ * If grouping is enabled, it only flushes a target's log entries when it completes.
22
+ */
28
23
  export declare abstract class GroupedReporter implements Reporter {
29
24
  protected options: {
30
25
  logLevel?: LogLevel;
31
26
  grouped?: boolean;
27
+ /** Whether to capture and report main process memory usage on target completion */
28
+ logMemory?: boolean;
32
29
  /** stream for testing */
33
30
  logStream?: Writable;
34
31
  };
@@ -38,10 +35,13 @@ export declare abstract class GroupedReporter implements Reporter {
38
35
  constructor(options: {
39
36
  logLevel?: LogLevel;
40
37
  grouped?: boolean;
38
+ /** Whether to capture and report main process memory usage on target completion */
39
+ logMemory?: boolean;
41
40
  /** stream for testing */
42
41
  logStream?: Writable;
43
42
  });
44
43
  log(entry: LogEntry<any>): boolean | void;
44
+ /** Print the entry for a target */
45
45
  protected logTargetEntry(entry: LogEntry<TargetLogData>): boolean | void;
46
46
  private logTargetEntryByGroup;
47
47
  summarize(schedulerRunSummary: SchedulerRunSummary): void;
@@ -14,22 +14,15 @@ _export(exports, {
14
14
  },
15
15
  get colors () {
16
16
  return colors;
17
- },
18
- get format () {
19
- return format;
20
- },
21
- get getTaskLogPrefix () {
22
- return getTaskLogPrefix;
23
- },
24
- get logLevelLabel () {
25
- return logLevelLabel;
26
17
  }
27
18
  });
28
- const _formathrtime = require("@lage-run/format-hrtime");
19
+ const _formatDuration = require("./formatDuration.js");
29
20
  const _isTargetStatusLogEntry = require("./isTargetStatusLogEntry.js");
30
21
  const _logger = require("@lage-run/logger");
31
22
  const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
32
23
  const _slowestTargetRuns = require("./slowestTargetRuns.js");
24
+ const _formatHelpers = require("./formatHelpers.js");
25
+ const _LogReporter = require("./LogReporter.js");
33
26
  function _define_property(obj, key, value) {
34
27
  if (key in obj) {
35
28
  Object.defineProperty(obj, key, {
@@ -70,18 +63,6 @@ const logLevelLabel = {
70
63
  function getTaskLogPrefix(pkg, task) {
71
64
  return `${colors.pkg(pkg)} ${colors.task(task)}`;
72
65
  }
73
- function normalize(prefixOrMessage, message) {
74
- if (typeof message === "string") {
75
- return {
76
- prefix: prefixOrMessage,
77
- message
78
- };
79
- }
80
- return {
81
- prefix: "",
82
- message: prefixOrMessage
83
- };
84
- }
85
66
  function format(level, prefix, message) {
86
67
  return `${logLevelLabel[level]}: ${prefix} ${message}\n`;
87
68
  }
@@ -103,35 +84,41 @@ class GroupedReporter {
103
84
  return this.logTargetEntry(entry);
104
85
  }
105
86
  }
106
- logTargetEntry(entry) {
87
+ /** Print the entry for a target */ logTargetEntry(entry) {
107
88
  const colorFn = colors[entry.level];
108
89
  const data = entry.data;
109
- if ((0, _isTargetStatusLogEntry.isTargetStatusLogEntry)(data)) {
110
- const { target, hash, duration } = data;
111
- const { packageName, task } = target;
112
- const normalizedArgs = this.options.grouped ? normalize(entry.msg) : normalize(getTaskLogPrefix(packageName ?? "<root>", task), entry.msg);
113
- const pkgTask = this.options.grouped ? `${_chalk.default.magenta(packageName)} ${_chalk.default.cyan(task)}` : "";
114
- switch(data.status){
115
- case "running":
116
- return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("➔")} start ${pkgTask}`)));
117
- case "success":
118
- return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("✓")} done ${pkgTask} - ${(0, _formathrtime.formatDuration)((0, _formathrtime.hrToSeconds)(duration))}`)));
119
- case "failed":
120
- return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.error("✖")} fail ${pkgTask}`)));
121
- case "skipped":
122
- return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.ok("»")} skip ${pkgTask} - ${hash}`)));
123
- case "aborted":
124
- return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.warn("-")} aborted ${pkgTask}`)));
125
- case "queued":
126
- return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn(`${colors.warn("…")} queued ${pkgTask}`)));
90
+ if (!data?.target) {
91
+ if (entry.msg.trim()) {
92
+ this.logStream.write(format(entry.level, "", entry.msg));
127
93
  }
128
- } else if (entry?.data?.target) {
129
- const { target } = data;
130
- const { packageName, task } = target;
131
- const normalizedArgs = this.options.grouped ? normalize(entry.msg) : normalize(getTaskLogPrefix(packageName ?? "<root>", task), entry.msg);
132
- return this.logStream.write(format(entry.level, normalizedArgs.prefix, colorFn("| " + normalizedArgs.message)));
133
- } else if (entry?.msg.trim() !== "") {
134
- return this.logStream.write(format(entry.level, "", entry.msg));
94
+ return;
95
+ }
96
+ const { target } = data;
97
+ const { packageName, task } = target;
98
+ const prefix = this.options.grouped ? "" : getTaskLogPrefix(packageName ?? "<root>", task);
99
+ if (!(0, _isTargetStatusLogEntry.isTargetStatusLogEntry)(data)) {
100
+ return this.logStream.write(format(entry.level, prefix, colorFn("| " + entry.msg)));
101
+ }
102
+ const { hash, duration, memoryUsage, status } = data;
103
+ const mem = (0, _formatHelpers.formatMemoryUsage)(memoryUsage, this.options.logMemory);
104
+ const pkgTask = this.options.grouped ? `${_chalk.default.magenta(packageName)} ${_chalk.default.cyan(task)}` : "";
105
+ switch(status){
106
+ case "running":
107
+ return this.logStream.write(format(entry.level, prefix, colorFn(`${colors.ok("➔")} start ${pkgTask}`)));
108
+ case "success":
109
+ return this.logStream.write(format(entry.level, prefix, colorFn(`${colors.ok("✓")} done ${pkgTask} - ${(0, _formatDuration.formatHrtime)(duration)}${mem}`)));
110
+ case "failed":
111
+ return this.logStream.write(format(entry.level, prefix, colorFn(`${colors.error("✖")} fail ${pkgTask}${mem}`)));
112
+ case "skipped":
113
+ return this.logStream.write(format(entry.level, prefix, colorFn(`${colors.ok("»")} skip ${pkgTask} - ${hash}${mem}`)));
114
+ case "aborted":
115
+ return this.logStream.write(format(entry.level, prefix, colorFn(`${colors.warn("-")} aborted ${pkgTask}`)));
116
+ case "queued":
117
+ return this.logStream.write(format(entry.level, prefix, colorFn(`${colors.warn("…")} queued ${pkgTask}`)));
118
+ case "pending":
119
+ return;
120
+ default:
121
+ throw new Error(`Internal error: unhandled target status "${status}"`);
135
122
  }
136
123
  }
137
124
  logTargetEntryByGroup(entry) {
@@ -153,36 +140,28 @@ class GroupedReporter {
153
140
  }
154
141
  }
155
142
  summarize(schedulerRunSummary) {
156
- const { targetRuns, targetRunByStatus, duration } = schedulerRunSummary;
143
+ const { targetRuns, targetRunByStatus } = schedulerRunSummary;
157
144
  const { failed, aborted, skipped, success, pending } = targetRunByStatus;
158
- const statusColorFn = {
159
- success: _chalk.default.greenBright,
160
- failed: _chalk.default.redBright,
161
- skipped: _chalk.default.gray,
162
- running: _chalk.default.yellow,
163
- pending: _chalk.default.gray,
164
- aborted: _chalk.default.red,
165
- queued: _chalk.default.magenta
166
- };
167
145
  this.writeSummaryHeader();
168
146
  if (targetRuns.size > 0) {
169
147
  const slowestTargets = (0, _slowestTargetRuns.slowestTargetRuns)([
170
148
  ...targetRuns.values()
171
149
  ]);
172
150
  for (const wrappedTarget of slowestTargets){
173
- const colorFn = statusColorFn[wrappedTarget.status];
174
- const target = wrappedTarget.target;
175
- this.logStream.write(format(_logger.LogLevel.info, getTaskLogPrefix(target.packageName || "[GLOBAL]", target.task), colorFn(`${wrappedTarget.status}${wrappedTarget.duration ? `, took ${(0, _formathrtime.formatDuration)((0, _formathrtime.hrToSeconds)(wrappedTarget.duration))}` : ""}`)));
151
+ const { target, status, duration } = wrappedTarget;
152
+ const colorFn = _LogReporter.statusColorFn[status] ?? _chalk.default.white;
153
+ this.logStream.write(format(_logger.LogLevel.info, getTaskLogPrefix(target.packageName || "[GLOBAL]", target.task), colorFn(`${status}${duration ? `, took ${(0, _formatDuration.formatHrtime)(duration)}` : ""}`)));
176
154
  }
177
155
  this.logStream.write(`[Tasks Count] success: ${success.length}, skipped: ${skipped.length}, pending: ${pending.length}, aborted: ${aborted.length}\n`);
178
156
  } else {
179
157
  this.logStream.write("Nothing has been run.\n");
180
158
  }
181
159
  this.writeSummaryFooter();
182
- if (failed && failed.length > 0) {
160
+ if (failed.length > 0) {
183
161
  this.writeFailures(failed, targetRuns);
184
162
  }
185
- this.logStream.write(format(_logger.LogLevel.info, "", `Took a total of ${(0, _formathrtime.formatDuration)((0, _formathrtime.hrToSeconds)(duration))} to complete`));
163
+ const formattedDuration = (0, _formatDuration.formatHrtime)(schedulerRunSummary.duration);
164
+ this.logStream.write(format(_logger.LogLevel.info, "", `Took a total of ${formattedDuration} to complete`));
186
165
  }
187
166
  constructor(options){
188
167
  _define_property(this, "options", void 0);