@@ -242,6 +242,35 @@ def inject_into_module(path, module_name, *args, &block)
242242 insert_into_file ( path , *( args << config ) , &block )
243243 end
244244
245+ # Run a regular expression replacement on a file, raising an error if the
246+ # contents of the file are not changed.
247+ #
248+ # ==== Parameters
249+ # path<String>:: path of the file to be changed
250+ # flag<Regexp|String>:: the regexp or string to be replaced
251+ # replacement<String>:: the replacement, can be also given as a block
252+ # config<Hash>:: give :verbose => false to not log the status, and
253+ # :force => true, to force the replacement regardless of runner behavior.
254+ #
255+ # ==== Example
256+ #
257+ # gsub_file! 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
258+ #
259+ # gsub_file! 'README', /rake/, :green do |match|
260+ # match << " no more. Use thor!"
261+ # end
262+ #
263+ def gsub_file! ( path , flag , *args , &block )
264+ config = args . last . is_a? ( Hash ) ? args . pop : { }
265+
266+ return unless behavior == :invoke || config . fetch ( :force , false )
267+
268+ path = File . expand_path ( path , destination_root )
269+ say_status :gsub , relative_to_original_destination_root ( path ) , config . fetch ( :verbose , true )
270+
271+ actually_gsub_file ( path , flag , args , true , &block ) unless options [ :pretend ]
272+ end
273+
245274 # Run a regular expression replacement on a file.
246275 #
247276 # ==== Parameters
@@ -267,11 +296,7 @@ def gsub_file(path, flag, *args, &block)
267296 path = File . expand_path ( path , destination_root )
268297 say_status :gsub , relative_to_original_destination_root ( path ) , config . fetch ( :verbose , true )
269298
270- unless options [ :pretend ]
271- content = File . binread ( path )
272- content . gsub! ( flag , *args , &block )
273- File . open ( path , "wb" ) { |file | file . write ( content ) }
274- end
299+ actually_gsub_file ( path , flag , args , false , &block ) unless options [ :pretend ]
275300 end
276301
277302 # Uncomment all lines matching a given regex. Preserves indentation before
@@ -348,7 +373,7 @@ def capture(*args)
348373 end
349374
350375 def with_output_buffer ( buf = "" . dup ) #:nodoc:
351- raise ArgumentError , "Buffer can not be a frozen object" if buf . frozen?
376+ raise ArgumentError , "Buffer cannot be a frozen object" if buf . frozen?
352377 old_buffer = output_buffer
353378 self . output_buffer = buf
354379 yield
@@ -357,6 +382,17 @@ def with_output_buffer(buf = "".dup) #:nodoc:
357382 self . output_buffer = old_buffer
358383 end
359384
385+ def actually_gsub_file ( path , flag , args , error_on_no_change , &block )
386+ content = File . binread ( path )
387+ success = content . gsub! ( flag , *args , &block )
388+
389+ if success . nil? && error_on_no_change
390+ raise Bundler ::Thor ::Error , "The content of #{ path } did not change"
391+ end
392+
393+ File . open ( path , "wb" ) { |file | file . write ( content ) }
394+ end
395+
360396 # Bundler::Thor::Actions#capture depends on what kind of buffer is used in ERB.
361397 # Thus CapturableERB fixes ERB to use String buffer.
362398 class CapturableERB < ERB
0 commit comments