@@ -18,6 +18,7 @@ def __init__(self, parser):
1818 parser .add_argument ('-s' , '--structures-path' , type = str , help = 'Path to structure definitions' )
1919 parser .add_argument ('-n' , '--input-store' , type = str , help = 'Path to the input store' , default = '/tmp/struct/input.json' )
2020 parser .add_argument ('-d' , '--dry-run' , action = 'store_true' , help = 'Perform a dry run without creating any files or directories' )
21+ parser .add_argument ('--diff' , action = 'store_true' , help = 'Show unified diffs for files that would change during dry-run or console output' )
2122 parser .add_argument ('-v' , '--vars' , type = str , help = 'Template variables in the format KEY1=value1,KEY2=value2' )
2223 parser .add_argument ('-b' , '--backup' , type = str , help = 'Path to the backup folder' )
2324 parser .add_argument ('-f' , '--file-strategy' , type = str , choices = ['overwrite' , 'skip' , 'append' , 'rename' , 'backup' ], default = 'overwrite' , help = 'Strategy for handling existing files' ).completer = file_strategy_completer
@@ -189,18 +190,47 @@ def _create_structure(self, args, mappings=None):
189190 )
190191 file_item .apply_template_variables (template_vars )
191192
192- # Output mode logic
193+ # Output mode logic with diff support
193194 if hasattr (args , 'output' ) and args .output == 'console' :
194- # Print the file path and content to the console instead of creating the file
195195 print (f"=== { file_path_to_create } ===" )
196- print (file_item .content )
196+ if args .diff and existing_content is not None :
197+ import difflib
198+ new_content = file_item .content if file_item .content .endswith ("\n " ) else file_item .content + "\n "
199+ old_content = existing_content if existing_content .endswith ("\n " ) else existing_content + "\n "
200+ diff = difflib .unified_diff (
201+ old_content .splitlines (keepends = True ),
202+ new_content .splitlines (keepends = True ),
203+ fromfile = f"a/{ file_path_to_create } " ,
204+ tofile = f"b/{ file_path_to_create } " ,
205+ )
206+ print ("" .join (diff ))
207+ else :
208+ print (file_item .content )
197209 else :
198- file_item .create (
199- args .base_path ,
200- args .dry_run or False ,
201- args .backup or None ,
202- args .file_strategy or 'overwrite'
203- )
210+ # When dry-run with --diff and files mode, print action and diff instead of writing
211+ if args .dry_run and args .diff :
212+ action = "create"
213+ if existing_content is not None :
214+ action = "update"
215+ print (f"[DRY RUN] { action } : { file_path_to_create } " )
216+ import difflib
217+ new_content = file_item .content if file_item .content .endswith ("\n " ) else file_item .content + "\n "
218+ old_content = (existing_content if existing_content is not None else "" )
219+ old_content = old_content if old_content .endswith ("\n " ) else (old_content + ("\n " if old_content else "" ))
220+ diff = difflib .unified_diff (
221+ old_content .splitlines (keepends = True ),
222+ new_content .splitlines (keepends = True ),
223+ fromfile = f"a/{ file_path_to_create } " ,
224+ tofile = f"b/{ file_path_to_create } " ,
225+ )
226+ print ("" .join (diff ))
227+ else :
228+ file_item .create (
229+ args .base_path ,
230+ args .dry_run or False ,
231+ args .backup or None ,
232+ args .file_strategy or 'overwrite'
233+ )
204234
205235 for item in config_folders :
206236 for folder , content in item .items ():
0 commit comments