Skip to content
Browse files

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
  • Loading branch information...
1 parent 4bd6436 commit 868d9f5a2c194d242e8679ada77dd6281af3c134 @jeremy jeremy committed Nov 2, 2006
Showing with 38 additions and 18 deletions.
  1. +2 −0 railties/CHANGELOG
  2. +36 −18 railties/lib/rails_generator/commands.rb
View
2 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]
View
54 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)

0 comments on commit 868d9f5

Please sign in to comment.
Something went wrong with that request. Please try again.