diff options
Diffstat (limited to 'railties/lib/rails/generators/app_base.rb')
-rw-r--r-- | railties/lib/rails/generators/app_base.rb | 133 |
1 files changed, 116 insertions, 17 deletions
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 77995c9c5b..d79cf2b2f0 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -1,10 +1,10 @@ require 'digest/md5' -require 'securerandom' require 'active_support/core_ext/string/strip' require 'rails/version' unless defined?(Rails::VERSION) -require 'rbconfig' require 'open-uri' require 'uri' +require 'rails/generators' +require 'active_support/core_ext/array/extract_options' module Rails module Generators @@ -76,13 +76,48 @@ module Rails end def initialize(*args) - @original_wd = Dir.pwd + @original_wd = Dir.pwd + @gem_filter = lambda { |gem| true } + @extra_entries = [] super convert_database_option_for_jruby end protected + def gemfile_entry(name, *args) + options = args.extract_options! + version = args.first + github = options[:github] + path = options[:path] + + if github + @extra_entries << GemfileEntry.github(name, github) + elsif path + @extra_entries << GemfileEntry.path(name, path) + else + @extra_entries << GemfileEntry.version(name, version) + end + self + end + + def gemfile_entries + [ rails_gemfile_entry, + database_gemfile_entry, + assets_gemfile_entry, + javascript_gemfile_entry, + jbuilder_gemfile_entry, + sdoc_gemfile_entry, + platform_dependent_gemfile_entry, + @extra_entries].flatten.find_all(&@gem_filter) + end + + def add_gem_entry_filter + @gem_filter = lambda { |next_filter,entry| + yield(entry) && next_filter.call(entry) + }.curry[@gem_filter] + end + def builder @builder ||= begin builder_class = get_builder_class @@ -102,12 +137,73 @@ module Rails FileUtils.cd(destination_root) unless options[:pretend] end + class TemplateRecorder < ::BasicObject # :nodoc: + attr_reader :gems + + def initialize(target) + @target = target + # unfortunately, instance eval has access to these ivars + @app_const = target.send :app_const if target.respond_to?(:app_const, true) + @app_const_base = target.send :app_const_base if target.respond_to?(:app_const_base, true) + @app_name = target.send :app_name if target.respond_to?(:app_name, true) + @commands = [] + @gems = [] + end + + def gemfile_entry(*args) + @target.send :gemfile_entry, *args + end + + def add_gem_entry_filter(*args, &block) + @target.send :add_gem_entry_filter, *args, &block + end + + def method_missing(name, *args, &block) + @commands << [name, args, block] + end + + def respond_to_missing?(method, priv = false) + super || @target.respond_to?(method, priv) + end + + def replay! + @commands.each do |name, args, block| + @target.send name, *args, &block + end + end + end + def apply_rails_template - apply rails_template if rails_template + @recorder = TemplateRecorder.new self + + apply(rails_template, target: @recorder) if rails_template rescue Thor::Error, LoadError, Errno::ENOENT => e raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}" end + def replay_template + @recorder.replay! if @recorder + end + + def apply(path, config={}) + verbose = config.fetch(:verbose, true) + target = config.fetch(:target, self) + is_uri = path =~ /^https?\:\/\// + path = find_in_source_paths(path) unless is_uri + + say_status :apply, path, verbose + shell.padding += 1 if verbose + + if is_uri + contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read } + else + contents = open(path) {|io| io.read } + end + + target.instance_eval(contents, path) + shell.padding -= 1 if verbose + end + def set_default_accessors! self.destination_root = File.expand_path(app_path, destination_root) self.rails_template = case options[:template] @@ -134,21 +230,21 @@ module Rails options[value] ? '# ' : '' end - class GemfileEntry < Struct.new(:name, :comment, :version, :options, :commented_out) - def initialize(name, comment, version, options = {}, commented_out = false) + class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out) + def initialize(name, version, comment, options = {}, commented_out = false) super end def self.github(name, github, comment = nil) - new(name, comment, nil, github: github) + new(name, nil, comment, github: github) end def self.version(name, version, comment = nil) - new(name, comment, version) + new(name, version, comment) end def self.path(name, path, comment = nil) - new(name, comment, nil, path: path) + new(name, nil, comment, path: path) end def padding(max_width) @@ -219,19 +315,22 @@ module Rails gems end + def platform_dependent_gemfile_entry + gems = [] + if RUBY_ENGINE == 'rbx' + gems << GemfileEntry.version('rubysl', nil) + end + gems + end + def jbuilder_gemfile_entry comment = 'Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder' GemfileEntry.version('jbuilder', '~> 1.2', comment) end - def webconsole_gemfile_entry - comment = 'Run `rails console` in the browser. Read more: https://github.com/rails/web-console' - GemfileEntry.new('web-console', comment, nil, group: :development) - end - def sdoc_gemfile_entry comment = 'bundle exec rake doc:rails generates the API under doc/api.' - GemfileEntry.new('sdoc', comment, nil, { :group => :doc, :require => false }) + GemfileEntry.new('sdoc', nil, comment, { group: :doc, require: false }) end def coffee_gemfile_entry @@ -260,9 +359,9 @@ module Rails def javascript_runtime_gemfile_entry comment = 'See https://github.com/sstephenson/execjs#readme for more supported runtimes' if defined?(JRUBY_VERSION) - GemfileEntry.version 'therubyrhino', comment, nil + GemfileEntry.version 'therubyrhino', nil, comment else - GemfileEntry.new 'therubyracer', comment, nil, { :platforms => :ruby }, true + GemfileEntry.new 'therubyracer', nil, comment, { platforms: :ruby }, true end end |