Skip to content

Commit 0dab34d

Browse files
committed
feat: Added support for new import prompts in debug and plain reporters. Fixed build errors and bugs
1 parent 77d6397 commit 0dab34d

File tree

7 files changed

+73
-106
lines changed

7 files changed

+73
-106
lines changed

src/orchestrators/import.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import { groupBy, sleep } from '../utils/index.js';
1414
import { wildCardMatch } from '../utils/wild-card-match.js';
1515
import { InitializationResult, InitializeOrchestrator } from './initialize.js';
1616

17-
export type RequiredParameters = Map<string, RequiredParameter[]>;
18-
export type UserSuppliedParameters = Map<string, Record<string, unknown>>;
1917
export type ImportResult = { result: ResourceConfig[], errors: string[] }
2018

2119
export interface ImportArgs {

src/plugins/plugin-manager.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { Plan, ResourcePlan } from '../entities/plan.js';
1010
import { Project } from '../entities/project.js';
1111
import { ResourceInfo } from '../entities/resource-info.js';
1212
import { SubProcessName, ctx } from '../events/context.js';
13-
import { RequiredParameter, RequiredParameters } from '../orchestrators/import.js';
1413
import { groupBy } from '../utils/index.js';
1514
import { Plugin } from './plugin.js';
1615
import { PluginResolver } from './resolver.js';

src/ui/components/default-component.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ export function DefaultComponent(props: {
6767
{
6868
renderStatus === RenderStatus.PROMPT_OPTIONS && (
6969
<Box flexDirection="column">
70-
<Text>{(renderData as any).message}</Text>
70+
<Text>{(renderData as { message: string, options: string[] }).message}</Text>
7171
<Select onChange={(value) => emitter.emit(RenderEvent.PROMPT_RESULT, value)} options={
72-
(renderData as any).options.map((option) => ({
72+
(renderData as { message: string, options: string[] }).options.map((option) => ({
7373
label: option, value: option
7474
}))
7575
}/>

src/ui/reporters/debug-reporter.ts

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
1-
import chalk from 'chalk';
2-
import { SudoRequestData, SudoRequestResponseData } from 'codify-schemas';
31
import createDebug, { Debugger } from 'debug';
4-
import readline from 'node:readline';
52

6-
import { Plan } from '../../entities/plan.js';
73
import { Event, ctx } from '../../events/context.js';
8-
import { ImportResult, RequiredParameters, UserSuppliedParameters } from '../../orchestrators/import.js';
9-
import { SudoUtils } from '../../utils/sudo.js';
10-
import { Reporter } from './reporter.js';
4+
import { PlainReporter } from './plain-reporter.js';
115

126
const debug = createDebug('codify');
137

14-
export class DebugReporter implements Reporter {
15-
private readonly rl = readline.createInterface(process.stdin, process.stdout);
8+
export class DebugReporter extends PlainReporter{
169
private debuggerCache = new Map<string, Debugger>();
1710

1811
constructor() {
12+
super(false);
13+
1914
ctx.on(Event.PLUGIN_STDOUT, (name, args) => this.getDebug(name)(args));
2015
ctx.on(Event.PLUGIN_STDERR, (name, args) => this.getDebug(name)(args));
2116
ctx.on(Event.STDOUT, (args) => debug(args));
@@ -27,68 +22,6 @@ export class DebugReporter implements Reporter {
2722
ctx.on(Event.SUB_PROCESS_FINISH, (name) => debug(name))
2823
}
2924

30-
async promptUserForParameterValues(requiredParameters: RequiredParameters): Promise<UserSuppliedParameters> {
31-
if (requiredParameters.size > 0 || [...requiredParameters.values()].reduce(
32-
(total, arr) => arr.length + total, 0
33-
)) {
34-
console.log('Some required information is needed for the import');
35-
}
36-
37-
const parameterInput = new Map<string, Record<string, unknown>>();
38-
39-
for (const [type, requiredParameter] of requiredParameters.entries()) {
40-
if (requiredParameter.length > 0) {
41-
console.log(`Resource: "${type}" requires additional information:`)
42-
}
43-
44-
for (const parameter of requiredParameter) {
45-
const response = await new Promise((resolve) => {
46-
this.rl.question(`${parameter.name} [${parameter.type}]: `, (answer) => resolve(answer));
47-
});
48-
49-
if (!parameterInput.has(type)) {
50-
parameterInput.set(type, {});
51-
}
52-
53-
parameterInput.get(type)![parameter.name] = response;
54-
}
55-
}
56-
57-
return parameterInput;
58-
}
59-
60-
displayImportResult(importResult: ImportResult) {
61-
console.log();
62-
console.log(JSON.stringify(importResult.result.map((r) => r.raw), null, 2));
63-
64-
if (importResult.errors.length > 0) {
65-
console.log('The following configs failed to import:')
66-
console.log(JSON.stringify(importResult.errors, null, 2));
67-
}
68-
}
69-
70-
async promptSudo(pluginName: string, data: SudoRequestData, secureMode: boolean): Promise<SudoRequestResponseData> {
71-
console.log(chalk.blue(`Plugin: "${pluginName}" requires root access to run command: "${data.command}"`));
72-
return SudoUtils.runCommand(data.command, data.options, secureMode, pluginName);
73-
}
74-
75-
async promptConfirmation(message: string): Promise<boolean> {
76-
const response = await new Promise((resolve) => {
77-
this.rl.question(`${message} (only 'yes' is accepted)`, (answer) => resolve(answer));
78-
});
79-
80-
return response === 'yes';
81-
}
82-
83-
displayPlan(plan: Plan): void {
84-
console.log(JSON.stringify(plan.raw, null, 2));
85-
}
86-
87-
displayApplyComplete(message: string[]): void {
88-
console.log('🎉 Finished applying 🎉');
89-
console.log('Open a new terminal or source \'.zshrc\' for the new changes to be reflected')
90-
}
91-
9225
private getDebug(name: string): Debugger {
9326
if (!this.debuggerCache.has(name)) {
9427
this.debuggerCache.set(name, createDebug(`plugin:${name}`));

src/ui/reporters/plain-reporter.ts

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,88 @@ import { SudoRequestData, SudoRequestResponseData } from 'codify-schemas';
33
import readline from 'node:readline';
44

55
import { Plan } from '../../entities/plan.js';
6+
import { ResourceConfig } from '../../entities/resource-config.js';
7+
import { ResourceInfo } from '../../entities/resource-info.js';
68
import { Event, ctx } from '../../events/context.js';
7-
import { ImportResult, RequiredParameters, UserSuppliedParameters } from '../../orchestrators/import.js';
9+
import { ImportResult } from '../../orchestrators/import.js';
10+
import { FileModificationResult } from '../../utils/file-modification-calculator.js';
811
import { SudoUtils } from '../../utils/sudo.js';
912
import { prettyFormatPlan } from '../plan-pretty-printer.js';
10-
import { Reporter } from './reporter.js';
13+
import { PromptType, Reporter } from './reporter.js';
1114

1215
export class PlainReporter implements Reporter {
1316
private readonly rl = readline.createInterface(process.stdin, process.stdout);
1417

15-
constructor() {
16-
ctx.on(Event.OUTPUT, (...args) => console.log(...args))
17-
ctx.on(Event.PROCESS_START, (name) => console.log(name))
18-
ctx.on(Event.PROCESS_FINISH, (name) => console.log(name))
19-
ctx.on(Event.SUB_PROCESS_START, (name) => console.log(name))
20-
ctx.on(Event.SUB_PROCESS_FINISH, (name) => console.log(name))
18+
constructor(attachListeners = true) {
19+
if (attachListeners) {
20+
ctx.on(Event.OUTPUT, (...args) => console.log(...args))
21+
ctx.on(Event.PROCESS_START, (name) => console.log(name))
22+
ctx.on(Event.PROCESS_FINISH, (name) => console.log(name))
23+
ctx.on(Event.SUB_PROCESS_START, (name) => console.log(name))
24+
ctx.on(Event.SUB_PROCESS_FINISH, (name) => console.log(name))
25+
}
2126
}
2227

23-
async promptUserForParameterValues(
24-
requiredParameters: RequiredParameters
25-
): Promise<UserSuppliedParameters> {
26-
if (requiredParameters.size > 0 || [...requiredParameters.values()].reduce(
27-
(total, arr) => arr.length + total, 0
28-
)) {
29-
console.log('Some required information is needed for the import');
28+
async promptOptions(message: string, options: string[]): Promise<number> {
29+
console.log(message);
30+
console.log('')
31+
32+
const response = await new Promise((resolve) => {
33+
this.rl.question(`${options.map((o, idx) => `[${idx}] ${o} ` ).join(' ')}\n`, (answer) => resolve(answer));
34+
});
35+
36+
const parsedNumber = Number.parseInt(response as string, 10);
37+
if (!Number.isInteger(parsedNumber) || parsedNumber < 0 || parsedNumber > options.length - 1) {
38+
throw new Error(`Invalid response ${response}`)
39+
}
40+
41+
return Number.parseInt(response as string, 10);
42+
}
43+
44+
displayFileModifications(diffs: { file: string; modification: FileModificationResult; }[]): void {
45+
console.log(chalk.bold('File modifications\n'))
46+
47+
for (const diff of diffs) {
48+
console.log(chalk.bold(diff.file))
49+
console.log('')
50+
console.log(diff.modification.diff)
51+
console.log('')
3052
}
53+
}
3154

32-
const parameterInput = new Map<string, Record<string, unknown>>();
55+
displayMessage(message: string): void {
56+
console.log(message);
57+
}
3358

34-
for (const [type, requiredParameter] of requiredParameters.entries()) {
35-
if (requiredParameter.length > 0) {
36-
console.log(`Resource: "${type}" requires additional information:`)
59+
async promptUserForValues(
60+
resourceInfoList: ResourceInfo[],
61+
promptType: PromptType
62+
): Promise<ResourceConfig[]> {
63+
const requiredParameters = resourceInfoList.flatMap((r) => r.getRequiredParameters())
64+
if (requiredParameters.length > 0) {
65+
console.log('Some required information is needed for the import');
66+
}
67+
68+
const result: ResourceConfig[] = [];
69+
for (const resourceInfo of resourceInfoList) {
70+
if (resourceInfo.getRequiredParameters().length > 0) {
71+
console.log(`Resource: "${resourceInfo.type}" requires additional information:`)
3772
}
3873

74+
const requiredParameter = resourceInfo.getRequiredParameters()
75+
const configJson: Record<string, unknown> = { type: resourceInfo.type }
3976
for (const parameter of requiredParameter) {
4077
const response = await new Promise((resolve) => {
4178
this.rl.question(`${parameter.name} [${parameter.type}]: `, (answer) => resolve(answer));
4279
});
4380

44-
if (!parameterInput.has(type)) {
45-
parameterInput.set(type, {});
46-
}
47-
48-
parameterInput.get(type)![parameter.name] = response;
81+
configJson[parameter.name] = response;
4982
}
83+
84+
result.push(new ResourceConfig(configJson as any))
5085
}
5186

52-
return parameterInput;
87+
return result;
5388
}
5489

5590
displayImportResult(importResult: ImportResult) {

src/ui/reporters/reporter.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { DefaultReporter } from './default-reporter.js';
66
import { ResourceInfo } from '../../entities/resource-info.js';
77
import { ResourceConfig } from '../../entities/resource-config.js';
88
import { FileModificationResult } from '../../utils/file-modification-calculator.js';
9+
import { PlainReporter } from './plain-reporter.js';
10+
import { DebugReporter } from './debug-reporter.js';
911

1012
export enum RenderEvent {
1113
LOG = 'log',
@@ -68,12 +70,12 @@ export const ReporterFactory = {
6870
create(type: ReporterType): Reporter {
6971
switch (type) {
7072
case ReporterType.DEBUG: {
71-
return new DefaultReporter();
73+
return new DebugReporter();
7274
}
7375

74-
// case ReporterType.PLAIN: {
75-
// return new PlainReporter();
76-
// }
76+
case ReporterType.PLAIN: {
77+
return new PlainReporter();
78+
}
7779

7880
case ReporterType.JSON: {
7981
return new DefaultReporter();

src/utils/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function deepEqual(obj1: unknown, obj2: unknown): boolean {
5151

5252
// Iterate through the keys and compare their values recursively.
5353
for (const key of keys1) {
54-
if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
54+
if (!keys2.includes(key) || !deepEqual((obj1 as Record<string, unknown>)[key], (obj2 as Record<string, unknown>)[key])) {
5555
return false;
5656
}
5757
}

0 commit comments

Comments
 (0)