From 868d9f5a2c194d242e8679ada77dd6281af3c134 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 2 Nov 2006 08:36:41 +0000 Subject: [PATCH] Generator can show diff on file collision to help you decide whether to skip or overwrite. Closes #6364. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5397 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- railties/CHANGELOG | 2 + railties/lib/rails_generator/commands.rb | 54 ++++++++++++++++-------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 8cb4c01cfd..912d1947a7 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Generator can show diff on file collision to help you decide whether to skip or overwrite. #6364 [jeffw, Jeremy Kemper] + * Generated directories are recursively svn added, like mkdir -p. #6416 [NeilW] * resource and scaffold_resource generators add a restful route to config/routes.rb [Jeremy Kemper] diff --git a/railties/lib/rails_generator/commands.rb b/railties/lib/rails_generator/commands.rb index f72fb3d5c6..8db14302da 100644 --- a/railties/lib/rails_generator/commands.rb +++ b/railties/lib/rails_generator/commands.rb @@ -1,6 +1,7 @@ require 'delegate' require 'optparse' require 'fileutils' +require 'tempfile' require 'erb' module Rails @@ -91,9 +92,17 @@ def gsub_file(relative_destination, regexp, *args, &block) private # Ask the user interactively whether to force collision. - def force_file_collision?(destination) - $stdout.print "overwrite #{destination}? [Ynaq] " + def force_file_collision?(destination, src, dst, file_options = {}, &block) + $stdout.print "overwrite #{destination}? [Ynaqd] " case $stdin.gets + when /d/i + Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp| + temp.write render_file(src, file_options, &block) + temp.rewind + $stdout.puts `#{diff_cmd} #{dst} #{temp.path}` + end + puts "retrying" + raise 'retry diff' when /a/i $stdout.puts "forcing #{spec.name}" options[:collision] = :force @@ -107,6 +116,10 @@ def force_file_collision?(destination) retry end + def diff_cmd + ENV['RAILS_DIFF'] || 'diff -u' + end + def render_template_part(template_options) # Getting Sandbox to evaluate part template in it part_binding = template_options[:sandbox].call.sandbox_binding @@ -197,7 +210,7 @@ def file(relative_source, relative_destination, file_options = {}, &block) # Make a choice whether to overwrite the file. :force and # :skip already have their mind made up, but give :ask a shot. choice = case (file_options[:collision] || options[:collision]).to_sym #|| :ask - when :ask then force_file_collision?(relative_destination) + when :ask then force_file_collision?(relative_destination, source, destination, file_options, &block) when :force then :force when :skip then :skip else raise "Invalid collision option: #{options[:collision].inspect}" @@ -223,27 +236,15 @@ def file(relative_source, relative_destination, file_options = {}, &block) # if block given so templaters may render the source file. If a # shebang is requested, replace the existing shebang or insert a # new one. - File.open(destination, 'wb') do |df| - File.open(source, 'rb') do |sf| - if block_given? - df.write(yield(sf)) - else - if file_options[:shebang] - df.puts("#!#{file_options[:shebang]}") - if line = sf.gets - df.puts(line) if line !~ /^#!/ - end - end - df.write(sf.read) - end - end + File.open(destination, 'wb') do |dest| + dest.write render_file(source, file_options, &block) end # Optionally change permissions. if file_options[:chmod] FileUtils.chmod(file_options[:chmod], destination) end - + # Optionally add file to subversion system("svn add #{destination}") if options[:svn] end @@ -347,6 +348,23 @@ def route_resources(*resources) end private + def render_file(path, options = {}) + File.open(path, 'rb') do |file| + if block_given? + yield file + else + content = '' + if shebang = options[:shebang] + content << "#!#{shebang}\n" + if line = file.gets + content << "line\n" if line !~ /^#!/ + end + end + content << file.read + end + end + end + # Raise a usage error with an informative WordNet suggestion. # Thanks to Florian Gross (flgr). def raise_class_collision(class_name) -- GitLab