Skip to content

Commit 996a95d

Browse files
committed
feat: Added integration tests for import command and fixed bugs
1 parent 98c581c commit 996a95d

File tree

8 files changed

+656
-48
lines changed

8 files changed

+656
-48
lines changed

src/entities/resource-info.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class ResourceInfo implements GetResourceInfoResponseData {
3535
const parameterInfo = this.getParameterInfo();
3636
parameterInfo.forEach((info) => {
3737
const matchedParameter = resource.parameters[info.name];
38-
if (matchedParameter) {
38+
if (matchedParameter !== undefined) {
3939
info.value = matchedParameter;
4040
}
4141
})

src/orchestrators/import.ts

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ResourceInfo } from '../entities/resource-info.js';
66
import { ProcessName, SubProcessName, ctx } from '../events/context.js';
77
import { CodifyParser } from '../parser/index.js';
88
import { DependencyMap, PluginManager } from '../plugins/plugin-manager.js';
9+
import { prettyFormatFileDiff } from '../ui/file-diff-pretty-printer.js';
910
import { PromptType, Reporter } from '../ui/reporters/reporter.js';
1011
import { FileUtils } from '../utils/file.js';
1112
import { FileModificationCalculator, ModificationType } from '../utils/file-modification-calculator.js';
@@ -18,7 +19,7 @@ export type UserSuppliedParameters = Map<string, Record<string, unknown>>;
1819
export type ImportResult = { result: ResourceConfig[], errors: string[] }
1920

2021
export interface ImportArgs {
21-
typeIds: string[];
22+
typeIds?: string[];
2223
path: string;
2324
secureMode?: boolean;
2425
}
@@ -58,11 +59,7 @@ export class ImportOrchestrator {
5859
throw new Error('At least one resource [type] must be specified. Ex: "codify import homebrew". Or the import command must be run in a directory with a valid codify file')
5960
}
6061

61-
if (!typeIds || typeIds.length === 0) {
62-
await ImportOrchestrator.runExistingProject(reporter, initializationResult)
63-
} else {
64-
await ImportOrchestrator.runNewImport(typeIds, reporter, initializationResult)
65-
}
62+
await (!typeIds || typeIds.length === 0 ? ImportOrchestrator.runExistingProject(reporter, initializationResult) : ImportOrchestrator.runNewImport(typeIds, reporter, initializationResult));
6663
}
6764

6865
/** Import new resources. Type ids supplied. This will ask for any required parameters */
@@ -95,6 +92,8 @@ export class ImportOrchestrator {
9592

9693
ctx.processFinished(ProcessName.IMPORT);
9794

95+
reporter.displayImportResult(importResult, false);
96+
9897
const resourceInfoList = await pluginManager.getMultipleResourceInfo(
9998
project.resourceConfigs.map((r) => r.type),
10099
);
@@ -222,30 +221,34 @@ ${JSON.stringify(unsupportedTypeIds)}`);
222221
'\nDo you want to save the results?',
223222
[
224223
projectExists ?
225-
multipleCodifyFiles ? `Update existing files (${project.codifyFiles})` : `Update existing file (${project.codifyFiles})`
224+
multipleCodifyFiles ? 'Update existing files' : `Update existing file (${project.codifyFiles})`
226225
: undefined,
227226
'In a new file',
228227
'No'
229228
].filter(Boolean) as string[]
230229
)
231230

232-
if (promptResult.startsWith('Update existing file')) {
231+
// Update an existing file
232+
if (projectExists && promptResult === 0) {
233233
const file = multipleCodifyFiles
234-
? await reporter.promptOptions('\nIf new resources are added, where to write them?', project.codifyFiles)
234+
? project.codifyFiles[await reporter.promptOptions('\nIf new resources are added, where to write them?', project.codifyFiles)]
235235
: project.codifyFiles[0];
236236
await ImportOrchestrator.updateExistingFiles(reporter, project, importResult, resourceInfoList, file);
237+
return;
238+
}
237239

238-
} else if (promptResult === 'In a new file') {
240+
// Write to a new file
241+
if ((!projectExists && promptResult === 0) || (projectExists && promptResult === 1)) {
239242
const newFileName = await ImportOrchestrator.generateNewImportFileName();
240-
await ImportOrchestrator.saveNewFile(newFileName, importResult);
243+
await ImportOrchestrator.saveNewFile(reporter, newFileName, importResult);
244+
return;
245+
}
241246

242-
} else if (promptResult === 'No') {
243-
reporter.displayImportResult(importResult, true);
244-
reporter.displayMessage('\n🎉 Imported completed 🎉')
247+
// No writes
248+
reporter.displayImportResult(importResult, true);
249+
reporter.displayMessage('\n🎉 Imported completed 🎉')
245250

246-
await sleep(100);
247-
process.exit(0);
248-
}
251+
await sleep(100);
249252
}
250253

251254
private static async updateExistingFiles(
@@ -262,8 +265,8 @@ ${JSON.stringify(unsupportedTypeIds)}`);
262265
// New resources exists (they don't belong to any existing files)
263266
if (groupedResults.unknown) {
264267
groupedResults[preferredFile] = [
265-
...groupedResults.unknown,
266-
...groupedResults[preferredFile],
268+
...(groupedResults.unknown ?? []),
269+
...(groupedResults[preferredFile] ?? []),
267270
]
268271
delete groupedResults.unknown;
269272
}
@@ -311,9 +314,27 @@ ${JSON.stringify(unsupportedTypeIds)}`);
311314
await sleep(100);
312315
}
313316

314-
private static async saveNewFile(filePath: string, importResult: ImportResult): Promise<void> {
315-
const newFile = JSON.stringify(importResult, null, 2);
317+
private static async saveNewFile(reporter: Reporter, filePath: string, importResult: ImportResult): Promise<void> {
318+
const newFile = JSON.stringify(importResult.result.map((r) => r.raw), null, 2);
319+
const diff = prettyFormatFileDiff('', newFile);
320+
321+
reporter.displayFileModifications([{ file: filePath, modification: { newFile, diff } }]);
322+
323+
const shouldSave = await reporter.promptConfirmation('Save the changes?');
324+
if (!shouldSave) {
325+
reporter.displayMessage('\nSkipping save! Exiting...');
326+
327+
// Wait for the message to display before we exit
328+
await sleep(100);
329+
return;
330+
}
331+
316332
await FileUtils.writeFile(filePath, newFile);
333+
334+
reporter.displayMessage('\n🎉 Imported completed and saved to file 🎉');
335+
336+
// Wait for the message to display before we exit
337+
await sleep(100);
317338
}
318339

319340
private static async generateNewImportFileName(): Promise<string> {

src/ui/reporters/default-reporter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,14 @@ export class DefaultReporter implements Reporter {
145145
return result;
146146
}
147147

148-
async promptOptions(message:string, options:string[]): Promise<string> {
148+
async promptOptions(message:string, options:string[]): Promise<number> {
149149
const result = await this.updateStateAndAwaitEvent<string>(
150150
() => this.updateRenderState(RenderStatus.PROMPT_OPTIONS, { message, options }),
151151
RenderEvent.PROMPT_RESULT
152152
)
153153

154154
this.log(`${message} -> "${result}"`)
155-
return result
155+
return options.indexOf(result);
156156
}
157157

158158
displayFileModifications(diff: Array<{ file: string; modification: FileModificationResult}>) {

src/ui/reporters/reporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export interface Reporter {
4444

4545
promptConfirmation(message: string): Promise<boolean>
4646

47-
promptOptions(message: string, options: string[]): Promise<string>;
47+
promptOptions(message: string, options: string[]): Promise<number>;
4848

4949
promptSudo(pluginName: string, data: SudoRequestData, secureMode: boolean): Promise<SudoRequestResponseData>;
5050

test/orchestrator/apply/apply.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('Apply orchestrator tests', () => {
2626
operation: ResourceOperation.CREATE,
2727
});
2828
},
29-
promptApplyConfirmation(): boolean {
29+
promptConfirmation(): boolean {
3030
return true;
3131
}
3232
});
@@ -63,7 +63,7 @@ describe('Apply orchestrator tests', () => {
6363
operation: ResourceOperation.CREATE,
6464
});
6565
},
66-
promptApplyConfirmation(): boolean {
66+
promptConfirmation(): boolean {
6767
return true;
6868
}
6969
});

0 commit comments

Comments
 (0)