diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2004-12-23 00:52:34 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2004-12-23 00:52:34 +0000 |
commit | 4ff4afa57949e6a7a4d3d200531932207f97da8e (patch) | |
tree | 3546444b022426e7324b667fe8662c88ed6b0775 | |
parent | 4ce65f434a29460aebcd2eaa511d85f0ff6bb18a (diff) | |
download | rails-4ff4afa57949e6a7a4d3d200531932207f97da8e.tar.gz rails-4ff4afa57949e6a7a4d3d200531932207f97da8e.tar.bz2 rails-4ff4afa57949e6a7a4d3d200531932207f97da8e.zip |
Added protection for creating a model through the generators with a name of an existing class, like Thread or Date. It'll even offer you a synonym using wordnet.princeton.edu as a look-up. No, I'm not kidding :) [Florian Gross]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@263 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | railties/CHANGELOG | 6 | ||||
-rwxr-xr-x | railties/bin/generate | 27 | ||||
-rw-r--r-- | railties/generators/controller/controller_generator.rb | 4 | ||||
-rw-r--r-- | railties/generators/controller/templates/controller.rb | 2 | ||||
-rw-r--r-- | railties/generators/controller/templates/functional_test.rb | 6 | ||||
-rw-r--r-- | railties/generators/scaffold/scaffold_generator.rb | 4 | ||||
-rw-r--r-- | railties/lib/rails_generator.rb | 27 |
7 files changed, 71 insertions, 5 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG index 75804bf3d9..f2fc996990 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,3 +1,9 @@ +*SVN* + +* Added protection for creating a model through the generators with a name of an existing class, like Thread or Date. + It'll even offer you a synonym using wordnet.princeton.edu as a look-up. No, I'm not kidding :) [Florian Gross] + + *0.9.2* * Fixed CTRL-C exists from the Breakpointer to be a clean affair without error dumping [Kent Sibilev] diff --git a/railties/bin/generate b/railties/bin/generate index 8f76e1fce3..ec6d04126e 100755 --- a/railties/bin/generate +++ b/railties/bin/generate @@ -4,10 +4,35 @@ require 'rails_generator' ARGV.shift unless ARGV.empty? or not ['--help', '-h'].include?(ARGV[0]) +def find_synonyms(word) + require 'open-uri' + uri = "http://wordnet.princeton.edu/cgi-bin/webwn2.0?stage=2" + + "&word=%s&posnumber=1&searchtypenumber=2&senses=&showglosses=1" + + open(uri % word) do |stream| + data = stream.read.gsub(" ", " ").gsub("<BR>", "") + data.scan(/^Sense \d+\n.+?\n\n/m) + end +rescue Exception + return nil +end + unless ARGV.empty? begin name = ARGV.shift - Rails::Generator.instance(name, ARGV).generate + generator = Rails::Generator.instance(name, ARGV) + + if msg = generator.collision_with_builtin? then + $stderr.puts msg + + if synonyms = find_synonyms(generator.class_name) then + $stderr.puts "", "Here's a few synonyms from WordNets.", + "Maybe they will help you find an alternative name." + "", synonyms + end + else + generator.generate + end rescue Rails::Generator::UsageError => e puts e.message end diff --git a/railties/generators/controller/controller_generator.rb b/railties/generators/controller/controller_generator.rb index 4b53741565..79f9a7e03b 100644 --- a/railties/generators/controller/controller_generator.rb +++ b/railties/generators/controller/controller_generator.rb @@ -19,4 +19,8 @@ class ControllerGenerator < Rails::Generator::Base template "view.rhtml", "app/views/#{file_name}/#{action}.rhtml", binding end end + + def full_class_name + class_name + "Controller" + end end diff --git a/railties/generators/controller/templates/controller.rb b/railties/generators/controller/templates/controller.rb index da71b5f057..0daf04b348 100644 --- a/railties/generators/controller/templates/controller.rb +++ b/railties/generators/controller/templates/controller.rb @@ -1,4 +1,4 @@ -class <%= class_name %>Controller < ApplicationController +class <%= full_class_name %> < ApplicationController <% if options[:scaffold] -%> scaffold :<%= singular_name %> <% end -%> diff --git a/railties/generators/controller/templates/functional_test.rb b/railties/generators/controller/templates/functional_test.rb index c975cb3ce3..df75ad57e9 100644 --- a/railties/generators/controller/templates/functional_test.rb +++ b/railties/generators/controller/templates/functional_test.rb @@ -2,11 +2,11 @@ require File.dirname(__FILE__) + '/../test_helper' require '<%= file_name %>_controller' # Re-raise errors caught by the controller. -class <%= class_name %>Controller; def rescue_action(e) raise e end; end +class <%= full_class_name %>; def rescue_action(e) raise e end; end -class <%= class_name %>ControllerTest < Test::Unit::TestCase +class <%= full_class_name %>Test < Test::Unit::TestCase def setup - @controller = <%= class_name %>Controller.new + @controller = <%= full_class_name %>.new @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new end diff --git a/railties/generators/scaffold/scaffold_generator.rb b/railties/generators/scaffold/scaffold_generator.rb index ee556e8a03..55bb835bb7 100644 --- a/railties/generators/scaffold/scaffold_generator.rb +++ b/railties/generators/scaffold/scaffold_generator.rb @@ -34,6 +34,10 @@ class ScaffoldGenerator < Rails::Generator::Base end end + def full_class_name + class_name + "Controller" + end + protected def scaffold_views %w(list show new edit) diff --git a/railties/lib/rails_generator.rb b/railties/lib/rails_generator.rb index 9e64f5f4c5..38b8daee49 100644 --- a/railties/lib/rails_generator.rb +++ b/railties/lib/rails_generator.rb @@ -114,6 +114,33 @@ module Rails @args = args end + # Checks whether the class name that was assigned to this generator + # would cause a collision with a Class, Module or other constant + # that is already used up by Ruby or RubyOnRails. + def collision_with_builtin? + builtin = Object.const_get(full_class_name) rescue nil + type = case builtin + when Class: "Class" + when Module: "Module" + else "Constant" + end + + if builtin then + "Sorry, you can't have a #{self.class.generator_name} named\n" + + "'#{full_class_name}' because Ruby or RubyOnRails already has\n" + + "a #{type} with that name. Please rerun the generator with a\n" + + "different name." + end + end + + # Returns the complete name that the resulting Class would have. + # Used in collision_with_builtin(). The default guess is that it is + # the same as class_name. Override this in your generator in case + # it is wrong. + def full_class_name + class_name + end + protected # Look up another generator with the same arguments. def generator(name) |