@mpis/monorepo 0.0.3 → 0.0.5

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.
@@ -1,6 +1,8 @@
1
1
  import { argv } from '@idlebox/args/default';
2
+ import { prettyPrintError, registerGlobalLifecycle, toDisposable } from '@idlebox/common';
2
3
  import { logger } from '@idlebox/logger';
3
4
  import { shutdown } from '@idlebox/node';
5
+ import { debugMode } from './args.js';
4
6
  import { createMonorepoObject } from './workspace.js';
5
7
 
6
8
  export async function runBuild() {
@@ -11,17 +13,36 @@ export async function runBuild() {
11
13
 
12
14
  const repo = await createMonorepoObject();
13
15
 
14
- repo.onStateChange(() => {
15
- if (process.stderr.isTTY) process.stderr.write('\x1Bc');
16
+ if (!debugMode) {
17
+ repo.onStateChange(() => {
18
+ if (process.stderr.isTTY) process.stderr.write('\x1Bc');
19
+
20
+ repo.printScreen();
21
+ });
22
+ }
23
+
24
+ let completed = false;
25
+ registerGlobalLifecycle(
26
+ toDisposable(() => {
27
+ if (debugMode) {
28
+ repo.printScreen();
29
+ } else {
30
+ if (process.stderr.isTTY) process.stderr.write('\x1Bc');
31
+ repo.printScreen();
32
+ }
33
+ if (!completed && !process.exitCode) {
34
+ process.exitCode = 1;
35
+ }
36
+ }),
37
+ );
16
38
 
17
- repo.printScreen();
18
- });
19
39
  try {
20
40
  await repo.startup();
21
41
 
22
42
  logger.success('Monorepo started successfully');
43
+ completed = true;
23
44
  } catch (error: any) {
24
- console.error(error.message);
45
+ prettyPrintError('monorepo build', error);
25
46
  shutdown(1);
26
47
  }
27
48
  }
@@ -1,8 +1,10 @@
1
1
  import { argv } from '@idlebox/args/default';
2
+ import { prettyPrintError, registerGlobalLifecycle } from '@idlebox/common';
2
3
  import { logger } from '@idlebox/logger';
3
4
  import { shutdown } from '@idlebox/node';
4
- import { createMonorepoObject } from './workspace.js';
5
+ import { debugMode } from './args.js';
5
6
  import { startUi } from './user-interactive.js';
7
+ import { createMonorepoObject } from './workspace.js';
6
8
 
7
9
  export async function runWatch() {
8
10
  if (argv.unused().length) {
@@ -11,19 +13,39 @@ export async function runWatch() {
11
13
  }
12
14
 
13
15
  const repo = await createMonorepoObject();
16
+ const cls = process.stderr.isTTY && !debugMode;
17
+
18
+ registerGlobalLifecycle(repo);
14
19
 
15
20
  startUi(repo);
16
21
 
17
22
  process.on('SIGPIPE', () => {
18
- process.stderr.write('\x1Bc');
23
+ if (cls) process.stderr.write('\x1Bc');
19
24
  logger.info`SIGPIPE received, printing current state...`;
20
25
  repo.printScreen();
21
26
  });
22
- repo.onStateChange(() => {
23
- process.stderr.write('\x1Bc');
24
- repo.printScreen();
25
- });
26
27
 
27
- await repo.startup();
28
- shutdown(1);
28
+ if (!debugMode) {
29
+ repo.onStateChange(() => {
30
+ if (cls && !repo.hasDisposed) process.stderr.write('\x1Bc');
31
+ logger.info`State changed, printing current state...`;
32
+ repo.printScreen();
33
+ });
34
+ }
35
+
36
+ try {
37
+ await repo.startup();
38
+ } catch (e: any) {
39
+ if (debugMode) {
40
+ if (cls && !repo.hasDisposed) process.stderr.write('\x1Bc');
41
+ repo.printScreen();
42
+ }
43
+ prettyPrintError('watch mode error', e);
44
+ shutdown(1);
45
+ }
46
+
47
+ if (cls && !repo.hasDisposed) process.stderr.write('\x1Bc');
48
+ repo.printScreen();
49
+
50
+ // logger.fatal`watch mode exited`;
29
51
  }
@@ -1,6 +1,6 @@
1
1
  import { logger } from '@idlebox/logger';
2
2
  import { findUpUntilSync } from '@idlebox/node';
3
- import { dirname } from 'path';
3
+ import { dirname } from 'node:path';
4
4
 
5
5
  export const initialWorkingDirectory = process.cwd();
6
6
 
@@ -5,7 +5,7 @@ import type { IPnpmMonoRepo } from './workspace.js';
5
5
  export async function startUi(_repo: IPnpmMonoRepo) {
6
6
  registerGlobalLifecycle(
7
7
  toDisposable(async () => {
8
- logger.error`Exiting...`;
8
+ logger.error`(not error, not implemented) Exiting...`;
9
9
  }),
10
10
  );
11
11
  }
@@ -1,6 +1,6 @@
1
1
  import { createWorkspace, type IPackageInfo, type MonorepoWorkspace } from '@build-script/monorepo-lib';
2
2
  import { AsyncDisposable, Emitter, isWindows, PathArray } from '@idlebox/common';
3
- import { logger, type IMyLogger } from '@idlebox/logger';
3
+ import { CSI, logger, type IMyLogger } from '@idlebox/logger';
4
4
  import { getEnvironment } from '@idlebox/node';
5
5
  import { CompileError, ModeKind, ProcessIPCClient, WorkersManager } from '@mpis/server';
6
6
  import { RigConfig, type IRigConfig } from '@rushstack/rig-package';
@@ -27,6 +27,7 @@ class PnpmMonoRepo extends AsyncDisposable {
27
27
  public readonly onStateChange = this._onStateChange.event;
28
28
 
29
29
  private readonly mode: ModeKind;
30
+ private readonly packageToWorker = new Map<IPackageInfo, ProcessIPCClient>();
30
31
 
31
32
  constructor(
32
33
  public readonly logger: IMyLogger,
@@ -43,7 +44,6 @@ class PnpmMonoRepo extends AsyncDisposable {
43
44
 
44
45
  this.mode = currentCommand === 'watch' ? ModeKind.Watch : ModeKind.Build;
45
46
  this.workersManager = new WorkersManager(this.mode, logger);
46
- this.workersManager._register(this);
47
47
  }
48
48
 
49
49
  async initialize() {
@@ -56,7 +56,7 @@ class PnpmMonoRepo extends AsyncDisposable {
56
56
  if (exec) {
57
57
  this.workersManager.addWorker(exec, project.devDependencies);
58
58
  } else {
59
- this.workersManager.addEmptyWorker(project.packageJson.name);
59
+ this.workersManager.addEmptyNode(project.packageJson.name);
60
60
  }
61
61
  }
62
62
  }
@@ -66,19 +66,18 @@ class PnpmMonoRepo extends AsyncDisposable {
66
66
  }
67
67
 
68
68
  async startup() {
69
- this.workersManager.finalize();
69
+ const graph = this.workersManager.finalize();
70
70
  // this.dump();
71
- await this.workersManager.startup();
71
+ graph._register(this);
72
+ await graph.startup();
72
73
  }
73
74
 
74
75
  private makeExecuter(watchMode: boolean, project: IPackageInfo): undefined | ProcessIPCClient {
75
76
  if (project.packageJson.scripts?.watch === undefined) {
76
- this.logger
77
- .fatal`project ${project.packageJson.name} does not have a "watch" script. If it doesn't need, specify a empty string.`;
77
+ this.logger.fatal`project ${project.packageJson.name} does not have a "watch" script. If it doesn't need, specify a empty string.`;
78
78
  }
79
79
  if (project.packageJson.scripts?.build === undefined) {
80
- this.logger
81
- .fatal`project ${project.packageJson.name} does not have a "build" script. If it doesn't need, specify a empty string.`;
80
+ this.logger.fatal`project ${project.packageJson.name} does not have a "build" script. If it doesn't need, specify a empty string.`;
82
81
  }
83
82
  const script = watchMode ? project.packageJson.scripts.watch : project.packageJson.scripts.build;
84
83
 
@@ -101,7 +100,7 @@ class PnpmMonoRepo extends AsyncDisposable {
101
100
 
102
101
  exec.onFailure((e) => {
103
102
  if (e instanceof CompileError) {
104
- this.errorMessages.set(project, e.message + '\n' + (e.output ?? 'no output from process'));
103
+ this.errorMessages.set(project, `${e.message}\n${e.output ?? 'no output from process'}`);
105
104
  } else {
106
105
  this.errorMessages.set(project, e.stack || e.message);
107
106
  }
@@ -118,6 +117,9 @@ class PnpmMonoRepo extends AsyncDisposable {
118
117
  exec.onTerminate(() => {
119
118
  this._onStateChange.fireNoError();
120
119
  });
120
+
121
+ this.packageToWorker.set(project, exec);
122
+
121
123
  return exec;
122
124
  }
123
125
 
@@ -125,11 +127,27 @@ class PnpmMonoRepo extends AsyncDisposable {
125
127
  if (this.errorMessages.size === 0) return '';
126
128
  let output = '';
127
129
 
128
- const flush_line = ' '.repeat(process.stderr.columns || 80);
130
+ const lWidth = process.stderr.columns || 80;
131
+
132
+ const barC = '48;5;185';
133
+ const textC = '38;5;13';
134
+
135
+ function buildLine(txt: string) {
136
+ let psize = 4 + 2 + txt.length + 2;
137
+ if (psize >= lWidth) {
138
+ txt = txt.slice(Math.max(lWidth - 20), 20);
139
+ psize = 4 + 2 + txt.length + 2;
140
+ }
141
+ return `\n${CSI}${barC}m ${CSI}0;${textC}m ${txt} ${CSI}0${barC}m${' '.repeat(lWidth - psize)}${CSI}0m\n`;
142
+ }
143
+
129
144
  for (const [project, text] of this.errorMessages.entries()) {
130
- output += `\n\x1B[48;5;1m${flush_line}\r \x1B[0;38;5;9;1m below is output of ${project.packageJson.name} \x1B[0m\n`;
131
- output += text;
132
- output += `\x1B[48;5;1m${flush_line}\r \x1B[0;38;5;9;1m ending output of ${project.packageJson.name} \x1B[0m\n`;
145
+ const block = text.replace(/^\s*\n/, '').trimEnd();
146
+ const exec = this.packageToWorker.get(project)!;
147
+ output += buildLine(`[@mpis/monorepo] below is output in project ${project.packageJson.name}: ${exec.commandline.join(' ')}`);
148
+ output += ``;
149
+ output += `\n${block}\n`.replace('\x1bc', '').replace(/^/gm, `${CSI}${barC}m ${CSI}0m `);
150
+ output += buildLine(`[@mpis/monorepo] ending output in project ${project.packageJson.name}`);
133
151
  }
134
152
  return output;
135
153
  }
@@ -163,11 +181,14 @@ class PnpmMonoRepo extends AsyncDisposable {
163
181
  }
164
182
 
165
183
  dump(depth: number = 0) {
184
+ const graph = this.workersManager.finalize();
185
+ let graphTxt: string;
166
186
  if (depth <= 0) {
167
- return this.workersManager.formatDebugList();
187
+ graphTxt = graph.debugFormatList();
168
188
  } else {
169
- return this.workersManager.formatDebugGraph(depth);
189
+ graphTxt = graph.debugFormatGraph(depth);
170
190
  }
191
+ return graphTxt + '\n' + graph.debugFormatSummary();
171
192
  }
172
193
 
173
194
  printScreen() {