Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8439: generator_merging.patch

File generator_merging.patch, 4.5 kB (added by nicwilliams, 1 year ago)

Patch to provide a 'm'erge option for conflicting files during the create process of any generator

  • rails/railties/lib/rails_generator/commands.rb

    old new  
    9393        private 
    9494          # Ask the user interactively whether to force collision. 
    9595          def force_file_collision?(destination, src, dst, file_options = {}, &block) 
    96             $stdout.print "overwrite #{destination}? [Ynaqd] " 
     96            $stdout.print "overwrite #{destination}? [Ynaqdm] " 
    9797            case $stdin.gets 
    9898              when /d/i 
    9999                Tempfile.open(File.basename(destination), File.dirname(dst)) do |temp| 
    100                   temp.write render_file(src, file_options, &block) 
     100                  temp.write tmp_file = render_file(src, file_options, &block) 
    101101                  temp.rewind 
    102102                  $stdout.puts `#{diff_cmd} #{dst} #{temp.path}` 
    103103                end 
    104                 puts "retrying" 
     104                $stdout.puts "retrying" 
    105105                raise 'retry diff' 
     106                                          when /m/i 
     107                Tempfile.open(File.basename(destination), File.dirname(dst)) do |temp| 
     108                  temp.write tmp_file = render_file(src, file_options, &block) 
     109                  temp.rewind 
     110                  options[:generated] = tmp_file 
     111                  options[:merge] = `#{merge_cmd} #{temp.path} #{dst} #{temp.path}` # means the label is the original file path 
     112                  $stdout.puts options[:merge] 
     113                end 
     114                $stdout.puts "merging #{spec.name}" 
     115                :merge 
    106116              when /a/i 
    107117                $stdout.puts "forcing #{spec.name}" 
    108118                options[:collision] = :force 
     
    120130            ENV['RAILS_DIFF'] || 'diff -u' 
    121131          end 
    122132 
     133          def merge_cmd 
     134            ENV['RAILS_MERGE'] || 'diff3 -m' 
     135          end 
     136 
    123137          def render_template_part(template_options) 
    124138            # Getting Sandbox to evaluate part template in it 
    125139            part_binding = template_options[:sandbox].call.sandbox_binding 
     
    191205        #   file 'settings/server.yml', 'config/server.yml', :collision => :skip 
    192206        # 
    193207        # Collisions are handled by checking whether the destination file 
    194         # exists and either skipping the file, forcing overwrite, or asking 
     208        # exists and either skipping the file, forcing overwrite, merging, or asking 
    195209        # the user what to do. 
    196210        def file(relative_source, relative_destination, file_options = {}, &block) 
    197211          # Determine full paths for source and destination files. 
     
    220234            # skip the file; otherwise, log our transgression and continue. 
    221235            case choice 
    222236              when :force then logger.force(relative_destination) 
     237              when :merge then logger.merge(relative_destination) 
    223238              when :skip  then return(logger.skip(relative_destination)) 
    224239              else raise "Invalid collision choice: #{choice}.inspect" 
    225240            end 
     
    232247          # If we're pretending, back off now. 
    233248          return if options[:pretend] 
    234249 
     250          FileUtils.cp(destination, destination + ".original") if options[:merge] 
     251           
    235252          # Write destination file with optional shebang.  Yield for content 
    236253          # if block given so templaters may render the source file.  If a 
    237254          # shebang is requested, replace the existing shebang or insert a 
    238255          # new one. 
    239256          File.open(destination, 'wb') do |dest| 
    240             dest.write render_file(source, file_options, &block) 
     257            dest.write options[:merge] || render_file(source, file_options, &block) 
    241258          end 
     259         
     260          if options[:merge] 
     261            File.open(destination + ".generated", 'wb') do |dest| 
     262              dest.write options[:generated] 
     263            end 
     264          else 
     265            # Optionally change permissions. 
     266            if file_options[:chmod] 
     267              FileUtils.chmod(file_options[:chmod], destination) 
     268            end 
    242269 
    243           # Optionally change permissions. 
    244           if file_options[:chmod] 
    245             FileUtils.chmod(file_options[:chmod], destination) 
     270            # Optionally add file to subversion 
     271            system("svn add #{destination}") if options[:svn] 
    246272          end 
    247  
    248           # Optionally add file to subversion 
    249           system("svn add #{destination}") if options[:svn] 
    250273        end 
    251274 
    252275        # Checks if the source and the destination file are identical. If