aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/generators/app_base.rb
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails/generators/app_base.rb')
-rw-r--r--railties/lib/rails/generators/app_base.rb133
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