Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add a more restricted codepath for templates fixes #13390
  • Loading branch information
tenderlove committed Jan 8, 2014
1 parent e4e750b commit 2875b4a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
34 changes: 26 additions & 8 deletions railties/lib/rails/generators/app_base.rb
Expand Up @@ -14,6 +14,7 @@ class AppBase < Base # :nodoc:
DATABASES.concat(JDBC_DATABASES)

attr_accessor :rails_template
attr_accessor :app_template
add_shebang_option!

argument :app_path, type: :string
Expand All @@ -26,6 +27,9 @@ def self.add_shared_options_for(name)
class_option :template, type: :string, aliases: '-m',
desc: "Path to some #{name} template (can be a filesystem path or URL)"

class_option :app_template, type: :string, aliases: '-n',
desc: "Path to some #{name} template (can be a filesystem path or URL)"

class_option :skip_gemfile, type: :boolean, default: false,
desc: "Don't create a Gemfile"

Expand Down Expand Up @@ -122,6 +126,10 @@ def add_gem_entry_filter
}.curry[@gem_filter]
end

def remove_gem(name)
add_gem_entry_filter { |gem| gem.name != name }
end

def builder
@builder ||= begin
builder_class = get_builder_class
Expand Down Expand Up @@ -162,6 +170,10 @@ def add_gem_entry_filter(*args, &block)
@target.send :add_gem_entry_filter, *args, &block
end

def remove_gem(*args, &block)
@target.send :remove_gem, *args, &block
end

def method_missing(name, *args, &block)
@commands << [name, args, block]
end
Expand All @@ -180,7 +192,8 @@ def replay!
def apply_rails_template
@recorder = TemplateRecorder.new self

apply(rails_template, target: @recorder) if rails_template
apply(rails_template, target: self) if rails_template
apply(app_template, target: @recorder) if app_template
rescue Thor::Error, LoadError, Errno::ENOENT => e
raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
end
Expand Down Expand Up @@ -210,13 +223,18 @@ def apply(path, config={})

def set_default_accessors!
self.destination_root = File.expand_path(app_path, destination_root)
self.rails_template = case options[:template]
when /^https?:\/\//
options[:template]
when String
File.expand_path(options[:template], Dir.pwd)
else
options[:template]
self.rails_template = expand_template options[:template]
self.app_template = expand_template options[:app_template]
end

def expand_template(name)
case name
when /^https?:\/\//
name
when String
File.expand_path(name, Dir.pwd)
else
name
end
end

Expand Down
29 changes: 25 additions & 4 deletions railties/test/generators/app_generator_test.rb
Expand Up @@ -163,22 +163,43 @@ def test_config_database_is_added_by_default
end
end

def test_arbitrary_code
output = Tempfile.open('my_template') do |template|
template.puts 'puts "You are using Rails version #{Rails::VERSION::STRING}."'
template.close
run_generator([destination_root, "-m", template.path])
end
assert_match 'You are using', output
end

def test_add_gemfile_entry
Tempfile.open('my_template') do |template|
template.puts 'gemfile_entry "tenderlove"'
template.flush
template.close
run_generator([destination_root, "-m", template.path])
run_generator([destination_root, "-n", template.path])
assert_file "Gemfile", /tenderlove/
end
end

def test_add_skip_entry
Tempfile.open 'my_template' do |template|
template.puts 'add_gem_entry_filter { |gem| gem.name != "jbuilder" }'
template.flush
template.close

run_generator([destination_root, "-m", template.path])
run_generator([destination_root, "-n", template.path])
assert_file "Gemfile" do |contents|
assert_no_match 'jbuilder', contents
end
end
end

def test_remove_gem
Tempfile.open 'my_template' do |template|
template.puts 'remove_gem "jbuilder"'
template.close

run_generator([destination_root, "-n", template.path])
assert_file "Gemfile" do |contents|
assert_no_match 'jbuilder', contents
end
Expand All @@ -190,7 +211,7 @@ def test_skip_turbolinks_when_it_is_not_on_gemfile
template.puts 'add_gem_entry_filter { |gem| gem.name != "turbolinks" }'
template.flush

run_generator([destination_root, "-m", template.path])
run_generator([destination_root, "-n", template.path])
assert_file "Gemfile" do |contents|
assert_no_match 'turbolinks', contents
end
Expand Down

1 comment on commit 2875b4a

@DanielKehoe
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So there will be a new option -n that takes a new kind of template, which will have a defined API?

And the existing option -m will continue to be supported? Will it be deprecated in the future?

Please sign in to comment.