aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails_generator.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-02-07 13:14:05 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-02-07 13:14:05 +0000
commitdaee6fd92ac16878f6806c3382a9e74592aa9656 (patch)
treed477c6502960cb141403f8b4640dd483b487e5df /railties/lib/rails_generator.rb
parent838c5a3d82367977d13ced01f9e28c22ccff32ef (diff)
downloadrails-daee6fd92ac16878f6806c3382a9e74592aa9656.tar.gz
rails-daee6fd92ac16878f6806c3382a9e74592aa9656.tar.bz2
rails-daee6fd92ac16878f6806c3382a9e74592aa9656.zip
Added new generator framework that informs about its doings on generation and enables updating and destruction of generated artifacts. See the new script/destroy and script/update for more details #487 [bitsweat]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@518 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/lib/rails_generator.rb')
-rw-r--r--railties/lib/rails_generator.rb234
1 files changed, 33 insertions, 201 deletions
diff --git a/railties/lib/rails_generator.rb b/railties/lib/rails_generator.rb
index 83a404fc0a..0875a22dee 100644
--- a/railties/lib/rails_generator.rb
+++ b/railties/lib/rails_generator.rb
@@ -1,201 +1,33 @@
-require 'fileutils'
-
-module Rails
- module Generator
- class GeneratorError < StandardError; end
- class UsageError < GeneratorError; end
-
- CONTRIB_ROOT = "#{RAILS_ROOT}/script/generators"
- BUILTIN_ROOT = "#{File.dirname(__FILE__)}/../generators"
- DEFAULT_SEARCH_PATHS = [CONTRIB_ROOT, BUILTIN_ROOT]
-
- class << self
- def instance(name, args = [], search_paths = DEFAULT_SEARCH_PATHS)
- # RAILS_ROOT constant must be set.
- unless Object.const_get(:RAILS_ROOT)
- raise GeneratorError, "RAILS_ROOT must be set. Did you require 'config/environment'?"
- end
-
- # Force canonical name.
- name = Inflector.underscore(name.downcase)
-
- # Search for filesystem path to requested generator.
- unless path = find_generator_path(name, search_paths)
- raise GeneratorError, "#{name} generator not found."
- end
-
- # Check for templates directory.
- template_root = "#{path}/templates"
- unless File.directory?(template_root)
- raise GeneratorError, "missing template directory #{template_root}"
- end
-
- # Require class file according to naming convention.
- require "#{path}/#{name}_generator.rb"
-
- # Find class according to naming convention. Allow Nesting::In::Modules.
- class_name = Inflector.classify("#{name}_generator")
- unless klass = find_generator_class(name)
- raise GeneratorError, "no #{class_name} class defined in #{path}/#{name}_generator.rb"
- end
-
- # Instantiate and return generator.
- klass.new(template_root, RAILS_ROOT, search_paths, args)
- end
-
-
- def builtin_generators
- generators([BUILTIN_ROOT])
- end
-
- def contrib_generators
- generators([CONTRIB_ROOT])
- end
-
- def generators(search_paths)
- generator_paths(search_paths).keys.uniq.sort
- end
-
- # Find all generator paths.
- def generator_paths(search_paths)
- @paths ||= {}
- unless @paths[search_paths]
- paths = Hash.new { |h,k| h[k] = [] }
- search_paths.each do |path|
- Dir["#{path}/[a-z]*"].each do |dir|
- paths[File.basename(dir)] << dir if File.directory?(dir)
- end
- end
- @paths[search_paths] = paths
- end
- @paths[search_paths]
- end
-
- def find_generator_path(name, search_paths)
- generator_paths(search_paths)[name].first
- end
-
- # Find all generator classes.
- def generator_classes
- classes = Hash.new { |h,k| h[k] = [] }
- class_re = /([^:]+)Generator$/
- ObjectSpace.each_object(Class) do |object|
- if md = class_re.match(object.name) and object < Rails::Generator::Base
- classes[Inflector.underscore(md.captures.first)] << object
- end
- end
- classes
- end
-
- def find_generator_class(name)
- generator_classes[name].first
- end
- end
-
-
- # Talk about generators.
- class Base
- attr_reader :template_root, :destination_root, :args, :options,
- :class_name, :singular_name, :plural_name
-
- alias_method :file_name, :singular_name
- alias_method :table_name, :plural_name
-
- def self.generator_name
- Inflector.underscore(name.gsub('Generator', ''))
- end
-
- def initialize(template_root, destination_root, search_paths, args)
- @template_root, @destination_root = template_root, destination_root
- usage if args.empty?
- @search_paths, @original_args = search_paths, args.dup
- @class_name, @singular_name, @plural_name = inflect_names(args.shift)
- @options = extract_options!(args)
- @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 " +
- "'#{full_class_name}' because Ruby or Rails already has a #{type} with that name.\n" +
- "Please rerun the generator with a 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)
- Rails::Generator.instance(name, @original_args, @search_paths)
- end
-
- # Generate a file for a Rails application using an ERuby template.
- # Looks up and evalutes a template by name and writes the result
- # to a file relative to +destination_root+. The template
- # is evaluated in the context of the optional eval_binding argument.
- #
- # The ERB template uses explicit trim mode to best control the
- # proliferation of whitespace in generated code. <%- trims leading
- # whitespace; -%> trims trailing whitespace including one newline.
- def template(template_name, destination_path, eval_binding = nil)
- # Determine full paths for source and destination files.
- template_path = find_template_path(template_name)
- destination_path = File.join(destination_root, destination_path)
-
- # Create destination directories.
- FileUtils.mkdir_p(File.dirname(destination_path))
-
- # Render template and write result.
- eval_binding ||= binding
- contents = ERB.new(File.read(template_path), nil, '-').result(eval_binding)
- File.open(destination_path, 'w') { |file| file.write(contents) }
- end
-
- def usage
- raise UsageError.new, File.read(usage_path)
- end
-
- private
- def find_template_path(template_name)
- name, path = template_name.split('/', 2)
- if path.nil?
- File.join(template_root, name)
- elsif generator_path = Rails::Generator.find_generator_path(name, @search_paths)
- File.join(generator_path, 'templates', path)
- end
- end
-
- def inflect_names(name)
- camel = Inflector.camelize(Inflector.underscore(name))
- under = Inflector.underscore(camel)
- plural = Inflector.pluralize(under)
- [camel, under, plural]
- end
-
- def extract_options!(args)
- if args.last.is_a?(Hash) then args.pop else {} end
- end
-
- def usage_path
- "#{template_root}/../USAGE"
- end
- end
- end
-end
+#--
+# Copyright (c) 2004 Jeremy Kemper
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#++
+
+$:.unshift(File.dirname(__FILE__))
+
+require 'support/core_ext'
+
+require 'rails_generator/base'
+require 'rails_generator/lookup'
+require 'rails_generator/commands'
+
+Rails::Generator::Base.send(:include, Rails::Generator::Lookup)
+Rails::Generator::Base.send(:include, Rails::Generator::Commands)