66
77from fdiff import __version__
88from fdiff .color import color_unified_diff_line
9- from fdiff .diff import u_diff
9+ from fdiff .diff import external_diff , u_diff
1010from fdiff .textiter import head , tail
1111from fdiff .utils import file_exists , get_tables_argument_list
1212
@@ -62,6 +62,7 @@ def run(argv):
6262 parser .add_argument (
6363 "--nomp" , action = "store_true" , help = "Do not use multi process optimizations"
6464 )
65+ parser .add_argument ("--external" , type = str , help = "Run external diff tool command" )
6566 parser .add_argument ("PREFILE" , help = "Font file path/URL 1" )
6667 parser .add_argument ("POSTFILE" , help = "Font file path/URL 2" )
6768
@@ -105,10 +106,6 @@ def run(argv):
105106 #
106107 # /////////////////////////////////////////////////////////
107108
108- # ---------------
109- # Unified diff
110- # ---------------
111-
112109 # parse explicitly included or excluded tables in
113110 # the command line arguments
114111 # set as a Python list if it was defined on the command line
@@ -117,44 +114,88 @@ def run(argv):
117114 exclude_list = get_tables_argument_list (args .exclude )
118115
119116 # flip logic of the command line flag for multi process
120- # optimizations for use as a u_diff function argument
117+ # optimization use
121118 use_mp = not args .nomp
122119
123- # perform the unified diff analysis
124- try :
125- diff = u_diff (
126- args .PREFILE ,
127- args .POSTFILE ,
128- context_lines = args .lines ,
129- include_tables = include_list ,
130- exclude_tables = exclude_list ,
131- use_multiprocess = use_mp ,
132- )
133- except Exception as e :
134- sys .stderr .write (f"[*] ERROR: { e } { os .linesep } " )
135- sys .exit (1 )
136-
137- # re-define the line contents of the diff iterable
138- # if head or tail is requested
139- if args .head :
140- iterable = head (diff , args .head )
141- elif args .tail :
142- iterable = tail (diff , args .tail )
143- else :
144- iterable = diff
145-
146- # print unified diff results to standard output stream
147- has_diff = False
148- if args .color :
149- for line in iterable :
150- has_diff = True
151- sys .stdout .write (color_unified_diff_line (line ))
120+ if args .external :
121+ # ------------------------------
122+ # External executable tool diff
123+ # ------------------------------
124+ # head and tail are not supported when external diff tool is called
125+ if args .head or args .tail :
126+ sys .stderr .write (
127+ f"[ERROR] The head and tail options are not supported with external diff executable calls.{ os .linesep } "
128+ )
129+ sys .exit (1 )
130+
131+ # lines of context filter is not supported when external diff tool is called
132+ if args .lines != 3 :
133+ sys .stderr .write (
134+ f"[ERROR] The lines option is not supported with external diff executable calls.{ os .linesep } "
135+ )
136+ sys .exit (1 )
137+
138+ try :
139+ diff = external_diff (
140+ args .external ,
141+ args .PREFILE ,
142+ args .POSTFILE ,
143+ include_tables = include_list ,
144+ exclude_tables = exclude_list ,
145+ use_multiprocess = use_mp ,
146+ )
147+
148+ # write stdout from external tool
149+ for line , exit_code in diff :
150+ # format with color if color flag is entered on command line
151+ if args .color :
152+ sys .stdout .write (color_unified_diff_line (line ))
153+ else :
154+ sys .stdout .write (line )
155+ if exit_code is not None :
156+ sys .exit (exit_code )
157+ except Exception as e :
158+ sys .stderr .write (f"[*] ERROR: { e } { os .linesep } " )
159+ sys .exit (1 )
152160 else :
153- for line in iterable :
154- has_diff = True
155- sys .stdout .write (line )
156-
157- # if no difference was found, tell the user instead of
158- # simply closing with zero exit status code.
159- if not has_diff :
160- print ("[*] There is no difference between the files." )
161+ # ---------------
162+ # Unified diff
163+ # ---------------
164+ # perform the unified diff analysis
165+ try :
166+ diff = u_diff (
167+ args .PREFILE ,
168+ args .POSTFILE ,
169+ context_lines = args .lines ,
170+ include_tables = include_list ,
171+ exclude_tables = exclude_list ,
172+ use_multiprocess = use_mp ,
173+ )
174+ except Exception as e :
175+ sys .stderr .write (f"[*] ERROR: { e } { os .linesep } " )
176+ sys .exit (1 )
177+
178+ # re-define the line contents of the diff iterable
179+ # if head or tail is requested
180+ if args .head :
181+ iterable = head (diff , args .head )
182+ elif args .tail :
183+ iterable = tail (diff , args .tail )
184+ else :
185+ iterable = diff
186+
187+ # print unified diff results to standard output stream
188+ has_diff = False
189+ if args .color :
190+ for line in iterable :
191+ has_diff = True
192+ sys .stdout .write (color_unified_diff_line (line ))
193+ else :
194+ for line in iterable :
195+ has_diff = True
196+ sys .stdout .write (line )
197+
198+ # if no difference was found, tell the user instead of
199+ # simply closing with zero exit status code.
200+ if not has_diff :
201+ print ("[*] There is no difference between the files." )
0 commit comments