@@ -97,6 +97,10 @@ def initialize(env, binary_path, global_opts, logger)
9797
9898 # Execute a git command, wait for it to finish, and return the result
9999 #
100+ # Non-option the command line arguements to pass to git. If you collect
101+ # the command line arguments in an array, make sure you splat the array
102+ # into the parameter list.
103+ #
100104 # NORMALIZATION
101105 #
102106 # The command output is returned as a Unicde string containing the binary output
@@ -142,32 +146,30 @@ def initialize(env, binary_path, global_opts, logger)
142146 # stderr.string #=> "unknown revision or path not in the working tree.\n"
143147 # end
144148 #
145- # @param args [Array<String>] the command line arguements to pass to git
146- #
147- # This array should be splatted into the parameter list.
149+ # @param options_hash [Hash] the options to pass to the command
148150 #
149- # @param out [#write, nil] the object to write stdout to or nil to ignore stdout
151+ # @option options_hash [#write, nil] :out the object to write stdout to or nil to ignore stdout
150152 #
151153 # If this is a 'StringIO' object, then `stdout_writer.string` will be returned.
152154 #
153155 # In general, only specify a `stdout_writer` object when you want to redirect
154156 # stdout to a file or some other object that responds to `#write`. The default
155157 # behavior will return the output of the command.
156158 #
157- # @param err [#write] the object to write stderr to or nil to ignore stderr
159+ # @option options_hash [#write, nil] :err the object to write stderr to or nil to ignore stderr
158160 #
159161 # If this is a 'StringIO' object and `merged_output` is `true`, then
160162 # `stderr_writer.string` will be merged into the output returned by this method.
161163 #
162- # @param normalize [Boolean] whether to normalize the output to a valid encoding
164+ # @option options_hash [Boolean] :normalize whether to normalize the output of stdout and stderr
163165 #
164- # @param chomp [Boolean] whether to chomp the output
166+ # @option options_hash [Boolean] :chomp whether to chomp both stdout and stderr output
165167 #
166- # @param merge [Boolean] whether to merge stdout and stderr in the string returned
168+ # @option options_hash [Boolean] :merge whether to merge stdout and stderr in the string returned
167169 #
168- # @param chdir [String] the directory to run the command in
170+ # @option options_hash [String, nil] :chdir the directory to run the command in
169171 #
170- # @param timeout [Numeric, nil] the maximum seconds to wait for the command to complete
172+ # @option options_hash [Numeric, nil] :timeout the maximum seconds to wait for the command to complete
171173 #
172174 # If timeout is zero, the timeout will not be enforced.
173175 #
@@ -189,21 +191,50 @@ def initialize(env, binary_path, global_opts, logger)
189191 #
190192 # @raise [Git::TimeoutError] if the command times out
191193 #
192- def run ( *args , normalize :, chomp :, merge :, out : nil , err : nil , chdir : nil , timeout : nil )
194+ def run ( *, **options_hash )
195+ options_hash = RUN_ARGS . merge ( options_hash )
196+ extra_options = options_hash . keys - RUN_ARGS . keys
197+ raise ArgumentError , "Unknown options: #{ extra_options . join ( ', ' ) } " if extra_options . any?
198+
199+ result = run_with_capture ( *, **options_hash )
200+ process_result ( result , options_hash [ :normalize ] , options_hash [ :chomp ] , options_hash [ :timeout ] )
201+ end
202+
203+ # @return [Git::CommandLineResult] the result of running the command
204+ #
205+ # @api private
206+ #
207+ def run_with_capture ( *args , **options_hash )
193208 git_cmd = build_git_cmd ( args )
194- begin
195- options = { chdir : chdir || :not_set , timeout_after : timeout , raise_errors : false }
209+ options = run_with_capture_options ( **options_hash )
210+ ProcessExecuter . run_with_capture ( env , *git_cmd , **options )
211+ rescue ProcessExecuter ::ProcessIOError => e
212+ raise Git ::ProcessIOError . new ( e . message ) , cause : e . exception . cause
213+ end
214+
215+ def run_with_capture_options ( **options_hash )
216+ chdir = options_hash [ :chdir ] || :not_set
217+ timeout_after = options_hash [ :timeout ]
218+ out = options_hash [ :out ]
219+ err = options_hash [ :err ]
220+ merge_output = options_hash [ :merge ] || false
221+
222+ { chdir :, timeout_after :, merge_output :, raise_errors : false } . tap do |options |
196223 options [ :out ] = out unless out . nil?
197224 options [ :err ] = err unless err . nil?
198- options [ :merge_output ] = merge unless merge . nil?
199-
200- result = ProcessExecuter . run_with_capture ( env , *git_cmd , **options )
201- rescue ProcessExecuter ::ProcessIOError => e
202- raise Git ::ProcessIOError . new ( e . message ) , cause : e . exception . cause
203225 end
204- process_result ( result , normalize , chomp , timeout )
205226 end
206227
228+ RUN_ARGS = {
229+ normalize : false ,
230+ chomp : false ,
231+ merge : false ,
232+ out : nil ,
233+ err : nil ,
234+ chdir : nil ,
235+ timeout : nil
236+ } . freeze
237+
207238 private
208239
209240 # Build the git command line from the available sources to send to `Process.spawn`
0 commit comments