Skip to content

Commit 2f6c6bb

Browse files
committed
Added debug reporter. Improved error messages from plugin errors
1 parent aab2d6b commit 2f6c6bb

5 files changed

Lines changed: 63 additions & 12 deletions

File tree

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"@inkjs/ui": "^1.0.0",
1717
"react": "^18.3.1",
1818
"chalk": "^5.3.0",
19-
"parse-json": "^8.1.0"
19+
"parse-json": "^8.1.0",
20+
"debug": "^4.3.4"
2021
},
2122
"description": "Codify is a set up as code tool for developers",
2223
"devDependencies": {
@@ -30,6 +31,7 @@
3031
"@types/semver": "^7.5.4",
3132
"@types/react": "^18.3.1",
3233
"@types/chalk": "^2.2.0",
34+
"@types/debug": "^4.1.12",
3335
"eslint-config-prettier": "^9.0.0",
3436
"chai": "^4",
3537
"chai-as-promised": "^7.1.1",

src/commands/plan/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import chalk from 'chalk';
33
import * as path from 'node:path';
44

55
import { PlanOrchestrator } from '../../orchestrators/plan.js';
6-
import { DefaultReporter } from '../../ui/reporters/default-reporter.js';
6+
import { DebugReporter } from '../../ui/reporters/debug-reporter.js';
77

88
export default class Plan extends Command {
99
static args = {
@@ -32,7 +32,7 @@ export default class Plan extends Command {
3232

3333
public async run(): Promise<void> {
3434
const { flags } = await this.parse(Plan)
35-
const reporter = new DefaultReporter()
35+
const reporter = new DebugReporter()
3636

3737
if (flags.path) {
3838
this.log(`Applying Codify from: ${flags.path}`);

src/events/context.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ export const ctx = new class {
4343
this.emitter.emit(Event.STDOUT, ...args);
4444
}
4545

46-
pluginStdout(...args: unknown[]) {
47-
this.emitter.emit(Event.PLUGIN_STDOUT, ...args);
46+
pluginStdout(name: string, ...args: unknown[]) {
47+
this.emitter.emit(Event.PLUGIN_STDOUT, name, ...args);
4848
}
4949

50-
pluginStderr(...args: unknown[]) {
51-
this.emitter.emit(Event.PLUGIN_STDERR, ...args);
50+
pluginStderr(name: string, ...args: unknown[]) {
51+
this.emitter.emit(Event.PLUGIN_STDERR, name, ...args);
5252
}
5353

5454
debug(...args: unknown[]) {
@@ -87,8 +87,8 @@ export const ctx = new class {
8787
attachOutputEmitters() {
8888
this.emitter.prependListener(Event.STDOUT, (...args) => this.onOutputEvent(...args));
8989
this.emitter.prependListener(Event.STDERR, (...args) => this.onOutputEvent(...args));
90-
this.emitter.prependListener(Event.PLUGIN_STDOUT, (...args) => this.onOutputEvent(...args));
91-
this.emitter.prependListener(Event.PLUGIN_STDERR, (...args) => this.onOutputEvent(...args));
90+
this.emitter.prependListener(Event.PLUGIN_STDOUT, (name, ...args) => this.onOutputEvent(...args));
91+
this.emitter.prependListener(Event.PLUGIN_STDERR, (name, ...args) => this.onOutputEvent(...args));
9292
this.emitter.prependListener(Event.DEBUG, (...args) => this.onOutputEvent(...args));
9393
}
9494

src/plugins/plugin-process.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { IpcMessage, IpcMessageSchema } from 'codify-schemas';
22
import { ChildProcess, fork } from 'node:child_process';
3+
import { createRequire } from 'node:module';
34

45
import { ctx } from '../events/context.js';
56
import { ajv } from '../utils/ajv.js';
@@ -29,14 +30,14 @@ export class PluginProcess {
2930
pluginPath,
3031
[],
3132
{
32-
env: { ...process.env, FORCE_COLOR: '1' },
33+
env: { ...process.env, FORCE_COLOR: '1', DEBUG_COLORS: '1' },
3334
silent: true,
3435
...(isTypescript && { execArgv: ['--import', 'tsx'] }),
3536
},
3637
);
3738

38-
_process.stdout!.on('data', (message) => ctx.pluginStdout(message.toString('utf8')));
39-
_process.stderr!.on('data', (message) => ctx.pluginStderr(message.toString('utf8')));
39+
_process.stdout!.on('data', (message) => ctx.pluginStdout(name, message.toString('utf8')));
40+
_process.stderr!.on('data', (message) => ctx.pluginStderr(name, message.toString('utf8')));
4041
_process.on('exit', (code) => {
4142
throw new Error(`Plugin ${this.name} exited with code ${code}`);
4243
})
@@ -64,6 +65,7 @@ export class PluginProcess {
6465
// Tsx is only installed for dev builds. Only allow typescript plugins for testing.
6566
private static isTsxInstalled(): boolean {
6667
try {
68+
const require = createRequire(import.meta.url);
6769
require.resolve('tsx');
6870
} catch (e) {
6971
return false;

src/ui/reporters/debug-reporter.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { PlanResponseData } from 'codify-schemas';
2+
import readline from 'node:readline';
3+
import createDebug, { Debugger } from 'debug';
4+
5+
import { ctx, Event } from '../../events/context.js';
6+
import { Reporter } from './reporter.js';
7+
8+
const debug = createDebug('codify');
9+
10+
export class DebugReporter implements Reporter {
11+
private readonly rl = readline.createInterface(process.stdin, process.stdout);
12+
private debuggerCache = new Map<string, Debugger>();
13+
14+
constructor() {
15+
ctx.on(Event.PLUGIN_STDOUT, (name, args) => this.getPluginDebug(name)(args));
16+
ctx.on(Event.PLUGIN_STDERR, (name, args) => this.getPluginDebug(name)(args));
17+
ctx.on(Event.STDOUT, (args) => debug(args));
18+
ctx.on(Event.STDERR, (args) => debug(args));
19+
ctx.on(Event.DEBUG, (args) => debug(args));
20+
ctx.on(Event.PROCESS_START, (name) => debug(name))
21+
ctx.on(Event.PROCESS_FINISH, (name) => debug(name))
22+
ctx.on(Event.SUB_PROCESS_START, (name) => debug(name))
23+
ctx.on(Event.SUB_PROCESS_FINISH, (name) => debug(name))
24+
}
25+
26+
async promptApplyConfirmation(): Promise<boolean> {
27+
const response = await new Promise((resolve) => {
28+
this.rl.question('Is this okay?\n', (answer) => resolve(answer));
29+
});
30+
31+
return response === 'yes';
32+
}
33+
34+
displayPlan(plan: PlanResponseData[]): void {
35+
console.log(JSON.stringify(plan));
36+
}
37+
38+
private getPluginDebug(name: string): Debugger {
39+
const debuggerName = `plugin:${name}`;
40+
41+
if (!this.debuggerCache.has(name)) {
42+
this.debuggerCache.set(name, createDebug(debuggerName));
43+
}
44+
45+
return this.debuggerCache.get(name)!;
46+
}
47+
}

0 commit comments

Comments
 (0)