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