Skip to content

Commit 4d4e8d5

Browse files
committed
feat: Improved log output
1 parent 876eb0e commit 4d4e8d5

8 files changed

Lines changed: 37 additions & 19 deletions

File tree

src/commands/apply.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ For more information, visit: https://codifycli.com/docs/commands/apply
3030
char: 'y',
3131
default: false,
3232
}),
33+
'verbose': Flags.boolean({
34+
char: 'v',
35+
description: 'Print plugin output (stdout/stderr) to the terminal.',
36+
}),
3337
}
3438

3539
static args = {
@@ -57,7 +61,7 @@ For more information, visit: https://codifycli.com/docs/commands/apply
5761

5862
await ApplyOrchestrator.run({
5963
path: flags.path ?? args.pathArgs,
60-
verbosityLevel: flags.debug ? 3 : 0,
64+
verbosityLevel: flags.debug || flags.verbose ? 3 : 0,
6165
autoApprove: flags.yes,
6266
// secure: flags.secure,
6367
}, this.reporter);

src/commands/destroy.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ For more information, visit: https://codifycli.com/docs/commands/destory`
3838
char: 'y',
3939
default: false,
4040
}),
41+
'verbose': Flags.boolean({
42+
char: 'v',
43+
description: 'Print plugin output (stdout/stderr) to the terminal.',
44+
}),
4145
}
4246

4347
public async run(): Promise<void> {
@@ -52,7 +56,7 @@ For more information, visit: https://codifycli.com/docs/commands/destory`
5256
.map((r) => r.input);
5357

5458
await DestroyOrchestrator.run({
55-
verbosityLevel: flags.debug ? 3 : 0,
59+
verbosityLevel: flags.debug || flags.verbose ? 3 : 0,
5660
typeIds: args,
5761
path: flags.path,
5862
autoApprove: flags.yes,

src/events/context.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ export const ctx = new class {
6565
}
6666

6767
log(...args: unknown[]) {
68-
this.emitter.emit(Event.STDOUT, ...args);
68+
const message = args.join(' ');
69+
this.emitter.emit(Event.STDOUT, message.endsWith('\n') ? message : message + '\n');
6970
}
7071

7172
pluginStdout(name: string, ...args: unknown[]) {
@@ -82,7 +83,8 @@ export const ctx = new class {
8283
return;
8384
}
8485

85-
this.emitter.emit(Event.DEBUG, ...args);
86+
const message = args.join(' ');
87+
this.emitter.emit(Event.DEBUG, message.endsWith('\n') ? message : message + '\n');
8688
}
8789

8890
async process<T>(name: string, fn: (() => Promise<T>)): Promise<T> {

src/ui/components/default-component.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Form, FormProps } from '@codifycli/ink-form';
2-
import chalk from 'chalk';
3-
import { Box, Static, Text } from 'ink';
2+
import { Box, Static, Text, useStdout } from 'ink';
43
import SelectInput from 'ink-select-input';
54
import { useAtom } from 'jotai';
65
import { EventEmitter } from 'node:events';
@@ -24,11 +23,17 @@ import { TextInput } from './widgets/TextInput.js';
2423

2524
export function DefaultComponent(props: {
2625
emitter: EventEmitter
26+
onWriteReady?: (write: (data: string) => void) => void
2727
}) {
28-
const { emitter } = props
28+
const { emitter, onWriteReady } = props
2929
const [{ status: renderStatus, data: renderData }] = useAtom(store.renderState);
30+
const { write } = useStdout();
3031

31-
return <Box flexDirection="column">
32+
useLayoutEffect(() => {
33+
onWriteReady?.(write);
34+
}, []);
35+
36+
return <Box flexDirection="column" marginTop={1}>
3237
{
3338
renderStatus === RenderStatus.DISPLAY_MESSAGE && (
3439
<Text>{renderData as string}</Text>

src/ui/components/progress/progress-display.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Box, Text, useInput } from 'ink';
22
import { useAtom } from 'jotai';
33
import { EventEmitter } from 'node:events';
4-
import React, { useLayoutEffect, useState } from 'react';
4+
import React, { useState } from 'react';
55

66
import { ProcessName } from '../../../events/context.js';
7+
import { VerbosityLevel } from '../../../utils/verbosity-level.js';
78
import { RenderEvent } from '../../reporters/reporter.js';
89
import { store } from '../../store/index.js';
910
import Spinner from './spinner.js';
@@ -27,7 +28,7 @@ export interface ProgressState {
2728
export function ProgressDisplay(props: { emitter: EventEmitter }) {
2829
const { emitter } = props;
2930
const [progress] = useAtom(store.progressState);
30-
const [isVerbose, setIsVerbose] = useState(false);
31+
const [isVerbose, setIsVerbose] = useState(() => VerbosityLevel.get() > 0);
3132
const [passwordSaved] = useAtom(store.isSudoPasswordCached);
3233

3334
const isApplyOrDestroy = progress?.name === ProcessName.APPLY || progress?.name === ProcessName.DESTROY;

src/ui/reporters/default-reporter.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,15 @@ const ProgressLabelMapping = {
4545

4646
export class DefaultReporter implements Reporter {
4747
private renderEmitter = new EventEmitter();
48+
private inkWrite: ((data: string) => void) | null = null;
4849
private progressState: ProgressState | null = null
4950
private verbosityToggleCallback: (() => void) | null = null;
5051
private sudoPasswordSubmittedCallback: ((password: string) => Promise<boolean>) | null = null;
5152
silent = false;
5253
rawOutput = false;
5354

5455
constructor() {
55-
render(<DefaultComponent emitter={this.renderEmitter}/>);
56+
render(<DefaultComponent emitter={this.renderEmitter} onWriteReady={(write) => { this.inkWrite = write; }}/>);
5657

5758
ctx.on(Event.OUTPUT, (args) => this.log(args));
5859
ctx.on(Event.PROCESS_START, (name) => this.onProcessStartEvent(name))
@@ -241,7 +242,7 @@ export class DefaultReporter implements Reporter {
241242
RenderEvent.PROMPT_RESULT
242243
)
243244

244-
this.log(result ? `${message} -> "Yes"` : `${message} -> "No"`)
245+
ctx.log(result ? `${message} -> "Yes"` : `${message} -> "No"`)
245246

246247
return result;
247248
}
@@ -254,7 +255,7 @@ export class DefaultReporter implements Reporter {
254255
RenderEvent.PROMPT_RESULT
255256
)
256257

257-
this.log(`${message} -> "${result}"`)
258+
ctx.log(`${message} -> "${result}"`)
258259

259260
await this.updateRenderState(prevRenderState.status, prevRenderState.data);
260261

@@ -268,7 +269,7 @@ export class DefaultReporter implements Reporter {
268269
private log(log: string): void {
269270
if (this.silent) return;
270271

271-
console.log(this.rawOutput ? log : chalk.cyan(log));
272+
this.inkWrite?.(this.rawOutput ? log : chalk.cyan(log));
272273
}
273274

274275
private onProcessStartEvent(name: ProcessName): void {
@@ -281,21 +282,21 @@ export class DefaultReporter implements Reporter {
281282
subProgresses: [],
282283
};
283284

284-
this.log(`${label} started`)
285+
ctx.log(`${label} started`)
285286
store.set(store.progressState, this.progressState);
286287
}
287288

288289
private onProcessFinishEvent(name: ProcessName): void {
289290
const label = ProgressLabelMapping[name];
290-
this.log(`${label} finished successfully`)
291+
ctx.log(`${label} finished successfully`)
291292

292293
this.progressState!.status = ProgressStatus.FINISHED;
293294
store.set(store.progressState, structuredClone(this.progressState));
294295
}
295296

296297
private onSubprocessStartEvent(name: SubProcessName, additionalName?: string): void {
297298
const label = ProgressLabelMapping[name] + (additionalName ? ' ' + additionalName : '');
298-
this.log(`${label} started`)
299+
ctx.log(`${label} started`)
299300

300301
this.progressState?.subProgresses?.push({
301302
label,
@@ -318,7 +319,7 @@ export class DefaultReporter implements Reporter {
318319

319320
subProgress.status = ProgressStatus.FINISHED;
320321

321-
this.log(`${label} finished successfully`)
322+
ctx.log(`${label} finished successfully`)
322323
store.set(store.progressState, structuredClone(this.progressState));
323324
}
324325

src/ui/reporters/plain-reporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class PlainReporter implements Reporter {
1717

1818
constructor(attachListeners = true) {
1919
if (attachListeners) {
20-
ctx.on(Event.OUTPUT, (...args) => !this.silent && console.log(...args))
20+
ctx.on(Event.OUTPUT, (args) => !this.silent && process.stdout.write(args))
2121
ctx.on(Event.PROCESS_START, (name) => !this.silent && console.log(name))
2222
ctx.on(Event.PROCESS_FINISH, (name) => !this.silent && console.log(name))
2323
ctx.on(Event.SUB_PROCESS_START, (name) => !this.silent && console.log(name))

src/ui/reporters/reporter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { PlainReporter } from './plain-reporter.js';
1212
import { StubReporter } from './stub-reporter.js';
1313

1414
export enum RenderEvent {
15+
LOG = 'log',
1516
PROGRESS_UPDATE = 'progressUpdate',
1617
PROMPT_RESULT = 'promptConfirmation',
1718
PROMPT_SUDO = 'promptSudo',

0 commit comments

Comments
 (0)