diff options
Diffstat (limited to 'railties/lib/rails/generators')
112 files changed, 1195 insertions, 1265 deletions
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 5c4e81431c..366c72ebaa 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -4,6 +4,10 @@ require 'rbconfig' module Rails module Generators module Actions + def initialize(*) # :nodoc: + super + @in_group = nil + end # Adds an entry into Gemfile for the supplied gem. # @@ -78,11 +82,11 @@ module Rails # end # # environment(nil, env: "development") do - # "config.active_record.observers = :cacher" + # "config.autoload_paths += %W(#{config.root}/extras)" # end def environment(data=nil, options={}, &block) sentinel = /class [a-z_:]+ < Rails::Application/i - env_file_sentinel = /::Application\.configure do/ + env_file_sentinel = /Rails\.application\.configure do/ data = block.call if !data && block_given? in_root do @@ -186,7 +190,7 @@ module Rails log :generate, what argument = args.map {|arg| arg.to_s }.flatten.join(" ") - in_root { run_ruby_script("script/rails generate #{what} #{argument}", verbose: false) } + in_root { run_ruby_script("bin/rails generate #{what} #{argument}", verbose: false) } end # Runs the supplied rake task @@ -211,7 +215,7 @@ module Rails # Make an entry in Rails routing file config/routes.rb # - # route "root :to => 'welcome#index'" + # route "root 'welcome#index'" def route(routing_code) log :route, routing_code sentinel = /\.routes\.draw do\s*$/ diff --git a/railties/lib/rails/generators/active_model.rb b/railties/lib/rails/generators/active_model.rb index 0e51b9c568..6183944bb0 100644 --- a/railties/lib/rails/generators/active_model.rb +++ b/railties/lib/rails/generators/active_model.rb @@ -59,8 +59,8 @@ module Rails end # PATCH/PUT update - def update_attributes(params=nil) - "#{name}.update_attributes(#{params})" + def update(params=nil) + "#{name}.update(#{params})" end # POST create diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index e761e26b04..1a270a6c8c 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -5,6 +5,8 @@ require 'rails/version' unless defined?(Rails::VERSION) require 'rbconfig' require 'open-uri' require 'uri' +require 'rails/generators/base' +require 'active_support/core_ext/array/extract_options' module Rails module Generators @@ -18,17 +20,18 @@ module Rails argument :app_path, type: :string - def self.add_shared_options_for(name) - class_option :builder, type: :string, aliases: '-b', - desc: "Path to a #{name} builder (can be a filesystem path or URL)" + def self.strict_args_position + false + end + def self.add_shared_options_for(name) class_option :template, type: :string, aliases: '-m', - desc: "Path to an #{name} template (can be a filesystem path or URL)" + 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" - class_option :skip_bundle, type: :boolean, default: false, + class_option :skip_bundle, type: :boolean, aliases: '-B', default: false, desc: "Don't run bundle install" class_option :skip_git, type: :boolean, aliases: '-G', default: false, @@ -40,6 +43,9 @@ module Rails class_option :skip_active_record, type: :boolean, aliases: '-O', default: false, desc: 'Skip Active Record files' + class_option :skip_action_view, type: :boolean, aliases: '-V', default: false, + desc: 'Skip Action View files' + class_option :skip_sprockets, type: :boolean, aliases: '-S', default: false, desc: 'Skip Sprockets files' @@ -52,9 +58,6 @@ module Rails class_option :skip_javascript, type: :boolean, aliases: '-J', default: false, desc: 'Skip JavaScript files' - class_option :skip_index_html, type: :boolean, aliases: '-I', default: false, - desc: 'Skip public/index.html and app/assets/images/rails.png files' - class_option :dev, type: :boolean, default: false, desc: "Setup the #{name} with Gemfile pointing to your Rails checkout" @@ -64,31 +67,61 @@ module Rails class_option :skip_test_unit, type: :boolean, aliases: '-T', default: false, desc: 'Skip Test::Unit files' + class_option :rc, type: :string, default: false, + desc: "Path to file containing extra configuration options for rails command" + + class_option :no_rc, type: :boolean, default: false, + desc: 'Skip loading of extra configuration options from .railsrc file' + class_option :help, type: :boolean, aliases: '-h', group: :rails, desc: 'Show this help message and quit' 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, + webconsole_gemfile_entry, + sdoc_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 - if path = options[:builder] - if URI(path).is_a?(URI::HTTP) - contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read } - else - contents = open(File.expand_path(path, @original_wd)) {|io| io.read } - end - - prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1) - instance_eval(&prok) - end - builder_class = get_builder_class builder_class.send(:include, ActionMethods) builder_class.new(self) @@ -100,11 +133,9 @@ module Rails end def create_root - self.destination_root = File.expand_path(app_path, destination_root) valid_const? empty_directory '.' - set_default_accessors! FileUtils.cd(destination_root) unless options[:pretend] end @@ -115,6 +146,7 @@ module Rails end def set_default_accessors! + self.destination_root = File.expand_path(app_path, destination_root) self.rails_template = case options[:template] when /^https?:\/\// options[:template] @@ -126,37 +158,52 @@ module Rails end def database_gemfile_entry - options[:skip_active_record] ? "" : "gem '#{gem_for_database}'" + return [] if options[:skip_active_record] + GemfileEntry.version gem_for_database, nil, + "Use #{options[:database]} as the database for Active Record" end def include_all_railties? - !options[:skip_active_record] && !options[:skip_test_unit] && !options[:skip_sprockets] + !options[:skip_active_record] && !options[:skip_action_view] && !options[:skip_test_unit] && !options[:skip_sprockets] end def comment_if(value) options[value] ? '# ' : '' end + 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, nil, comment, github: github) + end + + def self.version(name, version, comment = nil) + new(name, version, comment) + end + + def self.path(name, path, comment = nil) + new(name, nil, comment, path: path) + end + + def padding(max_width) + ' ' * (max_width - name.length + 2) + end + end + def rails_gemfile_entry if options.dev? - <<-GEMFILE.strip_heredoc - gem 'rails', path: '#{Rails::Generators::RAILS_DEV_PATH}' - gem 'journey', github: 'rails/journey' - gem 'arel', github: 'rails/arel' - gem 'activerecord-deprecated_finders', github: 'rails/activerecord-deprecated_finders' - GEMFILE + [GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH), + GemfileEntry.github('arel', 'rails/arel')] elsif options.edge? - <<-GEMFILE.strip_heredoc - gem 'rails', github: 'rails/rails' - gem 'journey', github: 'rails/journey' - gem 'arel', github: 'rails/arel' - gem 'activerecord-deprecated_finders', github: 'rails/activerecord-deprecated_finders' - GEMFILE + [GemfileEntry.github('rails', 'rails/rails'), + GemfileEntry.github('arel', 'rails/arel')] else - <<-GEMFILE.strip_heredoc - # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' - gem 'rails', '#{Rails::VERSION::STRING}' - GEMFILE + [GemfileEntry.version('rails', + Rails::VERSION::STRING, + "Bundle edge Rails instead: gem 'rails', github: 'rails/rails'")] end end @@ -188,57 +235,71 @@ module Rails end def assets_gemfile_entry - return if options[:skip_sprockets] - - gemfile = if options.dev? || options.edge? - <<-GEMFILE - # Gems used only for assets and not required - # in production environments by default. - group :assets do - gem 'sprockets-rails', github: 'rails/sprockets-rails' - gem 'sass-rails', github: 'rails/sass-rails' - gem 'coffee-rails', github: 'rails/coffee-rails' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - #{javascript_runtime_gemfile_entry} - gem 'uglifier', '>= 1.0.3' - end - GEMFILE + return [] if options[:skip_sprockets] + + gems = [] + if options.dev? || options.edge? + gems << GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails', + 'Use edge version of sprockets-rails') + gems << GemfileEntry.github('sass-rails', 'rails/sass-rails', + 'Use SCSS for stylesheets') else - <<-GEMFILE - # Gems used only for assets and not required - # in production environments by default. - group :assets do - gem 'sprockets-rails', github: 'rails/sprockets-rails' - gem 'sass-rails', '~> 4.0.0.beta' - gem 'coffee-rails', '~> 4.0.0.beta' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - #{javascript_runtime_gemfile_entry} - gem 'uglifier', '>= 1.0.3' - end - GEMFILE + gems << GemfileEntry.version('sass-rails', + '~> 4.0.0.rc1', + 'Use SCSS for stylesheets') end - gemfile.strip_heredoc.gsub(/^[ \t]*$/, '') + gems << GemfileEntry.version('uglifier', + '>= 1.3.0', + 'Use Uglifier as compressor for JavaScript assets') + + 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', nil, comment, group: :development) + end + + def sdoc_gemfile_entry + comment = 'bundle exec rake doc:rails generates the API under doc/api.' + GemfileEntry.new('sdoc', nil, comment, { group: :doc, require: false }) + end + + def coffee_gemfile_entry + comment = 'Use CoffeeScript for .js.coffee assets and views' + if options.dev? || options.edge? + GemfileEntry.github 'coffee-rails', 'rails/coffee-rails', comment + else + GemfileEntry.version 'coffee-rails', '~> 4.0.0', comment + end end def javascript_gemfile_entry - unless options[:skip_javascript] - <<-GEMFILE.strip_heredoc - gem '#{options[:javascript]}-rails' + if options[:skip_javascript] + [] + else + gems = [coffee_gemfile_entry, javascript_runtime_gemfile_entry] + gems << GemfileEntry.version("#{options[:javascript]}-rails", nil, + "Use #{options[:javascript]} as the JavaScript library") - # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks - gem 'turbolinks' - GEMFILE + gems << GemfileEntry.version("turbolinks", nil, + "Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks") + gems end end def javascript_runtime_gemfile_entry + comment = 'See https://github.com/sstephenson/execjs#readme for more supported runtimes' if defined?(JRUBY_VERSION) - "gem 'therubyrhino'\n" + GemfileEntry.version 'therubyrhino', nil, comment else - "# gem 'therubyracer', platforms: :ruby\n" + GemfileEntry.new 'therubyracer', nil, comment, { platforms: :ruby }, true end end diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index 7e938fab47..dc1d4fa181 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -7,7 +7,7 @@ rescue LoadError exit end -require 'rails/generators/actions' +require 'rails/generators' module Rails module Generators @@ -168,15 +168,15 @@ module Rails as_hook = options.delete(:as) || generator_name names.each do |name| - defaults = if options[:type] == :boolean - { } - elsif [true, false].include?(default_value_for_option(name, options)) - { banner: "" } - else - { desc: "#{name.to_s.humanize} to be invoked", banner: "NAME" } - end - unless class_options.key?(name) + defaults = if options[:type] == :boolean + { } + elsif [true, false].include?(default_value_for_option(name, options)) + { banner: "" } + else + { desc: "#{name.to_s.humanize} to be invoked", banner: "NAME" } + end + class_option(name, defaults.merge!(options)) end @@ -211,7 +211,7 @@ module Rails return unless base_name && generator_name return unless default_generator_root path = File.join(default_generator_root, 'templates') - path if File.exists?(path) + path if File.exist?(path) end # Returns the base root for a common set of generators. This is used to dynamically @@ -255,12 +255,7 @@ module Rails # Split the class from its module nesting nesting = class_name.split('::') last_name = nesting.pop - - # Extract the last Module in the nesting - last = nesting.inject(Object) do |last_module, nest| - break unless last_module.const_defined?(nest, false) - last_module.const_get(nest) - end + last = extract_last_module(nesting) if last && last.const_defined?(last_name.camelize, false) raise Error, "The name '#{class_name}' is either already used in your application " << @@ -270,6 +265,14 @@ module Rails end end + # Takes in an array of nested modules and extracts the last module + def extract_last_module(nesting) + nesting.inject(Object) do |last_module, nest| + break unless last_module.const_defined?(nest, false) + last_module.const_get(nest) + end + end + # Use Rails default banner. def self.banner "rails generate #{namespace.sub(/^rails:/,'')} #{self.arguments.map{ |a| a.usage }.join(' ')} [options]".gsub(/\s+/, ' ') @@ -365,12 +368,12 @@ module Rails source_root && File.expand_path("../USAGE", source_root), default_generator_root && File.join(default_generator_root, "USAGE") ] - paths.compact.detect { |path| File.exists? path } + paths.compact.detect { |path| File.exist? path } end def self.default_generator_root path = File.expand_path(File.join(base_name, generator_name), base_root) - path if File.exists?(path) + path if File.exist?(path) end end diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb index 32546936e3..69c10efa47 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb @@ -13,8 +13,22 @@ <% attributes.each do |attribute| -%> <div class="field"> - <%%= f.label :<%= attribute.name %> %><br /> +<% if attribute.password_digest? -%> + <%%= f.label :password %><br> + <%%= f.password_field :password %> + </div> + <div> + <%%= f.label :password_confirmation %><br> + <%%= f.password_field :password_confirmation %> +<% else -%> + <%- if attribute.reference? -%> + <%%= f.label :<%= attribute.column_name %> %><br> + <%%= f.<%= attribute.field_type %> :<%= attribute.column_name %> %> + <%- else -%> + <%%= f.label :<%= attribute.name %> %><br> <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %> + <%- end -%> +<% end -%> </div> <% end -%> <div class="actions"> diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb index f5182bcc50..814d6fdb0e 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb @@ -3,27 +3,27 @@ <table> <thead> <tr> - <% attributes.each do |attribute| -%> +<% attributes.reject(&:password_digest?).each do |attribute| -%> <th><%= attribute.human_name %></th> - <% end -%> - <th></th> - <th></th> - <th></th> +<% end -%> + <th colspan="3"></th> </tr> </thead> <tbody> - <%%= content_tag_for(:tr, @<%= plural_table_name %>) do |<%= singular_table_name %>| %> - <% attributes.each do |attribute| -%> - <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td> - <% end -%> - <td><%%= link_to 'Show', <%= singular_table_name %> %></td> - <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td> - <td><%%= link_to 'Destroy', <%= singular_table_name %>, method: :delete, data: { confirm: 'Are you sure?' } %></td> + <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %> + <tr> +<% attributes.reject(&:password_digest?).each do |attribute| -%> + <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td> +<% end -%> + <td><%%= link_to 'Show', <%= singular_table_name %> %></td> + <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td> + <td><%%= link_to 'Destroy', <%= singular_table_name %>, method: :delete, data: { confirm: 'Are you sure?' } %></td> + </tr> <%% end %> </tbody> </table> -<br /> +<br> <%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path %> diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb index e15c963971..5e634153be 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb @@ -1,12 +1,11 @@ <p id="notice"><%%= notice %></p> -<% attributes.each do |attribute| -%> +<% attributes.reject(&:password_digest?).each do |attribute| -%> <p> <strong><%= attribute.human_name %>:</strong> <%%= @<%= singular_table_name %>.<%= attribute.name %> %> </p> <% end -%> - <%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>) %> | <%%= link_to 'Back', <%= index_helper %>_path %> diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb index d8a4f15b4b..5e2784c4b0 100644 --- a/railties/lib/rails/generators/generated_attribute.rb +++ b/railties/lib/rails/generators/generated_attribute.rb @@ -99,13 +99,17 @@ module Rails end def index_name - @index_name ||= if reference? - polymorphic? ? %w(id type).map { |t| "#{name}_#{t}" } : "#{name}_id" + @index_name ||= if polymorphic? + %w(id type).map { |t| "#{name}_#{t}" } else - name + column_name end end + def column_name + @column_name ||= reference? ? "#{name}_id" : name + end + def foreign_key? !!(name =~ /_id$/) end @@ -126,6 +130,10 @@ module Rails @has_uniq_index end + def password_digest? + name == 'password' && type == :digest + end + def inject_options "".tap { |s| @attr_options.each { |k,v| s << ", #{k}: #{v.inspect}" } } end diff --git a/railties/lib/rails/generators/migration.rb b/railties/lib/rails/generators/migration.rb index 5bf98bb6e0..3566f96f5e 100644 --- a/railties/lib/rails/generators/migration.rb +++ b/railties/lib/rails/generators/migration.rb @@ -1,15 +1,14 @@ +require 'active_support/concern' + module Rails module Generators # Holds common methods for migrations. It assumes that migrations has the # [0-9]*_name format and can be used by another frameworks (like Sequel) # just by implementing the next migration version method. module Migration + extend ActiveSupport::Concern attr_reader :migration_number, :migration_file_name, :migration_class_name - def self.included(base) #:nodoc: - base.extend ClassMethods - end - module ClassMethods def migration_lookup_at(dirname) #:nodoc: Dir.glob("#{dirname}/[0-9]*_*.rb") @@ -52,7 +51,7 @@ module Rails if destination && options.force? remove_file(destination) elsif destination - raise Error, "Another migration is already named #{@migration_file_name}: #{destination}" + raise Error, "Another migration is already named #{@migration_file_name}: #{destination}. Use --force to remove the old migration file and replace it." end destination = File.join(migration_dir, "#{@migration_number}_#{@migration_file_name}.rb") end diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 84f8f76838..e712c747b0 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -18,6 +18,8 @@ module Rails parse_attributes! if respond_to?(:attributes) end + # Defines the template that would be used for the migration file. + # The arguments include the source template file, the migration filename etc. no_tasks do def template(source, *args, &block) inside_template do @@ -40,7 +42,7 @@ module Rails def indent(content, multiplier = 2) spaces = " " * multiplier - content = content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join + content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join end def wrap_with_namespace(content) @@ -160,6 +162,14 @@ module Rails end end + def attributes_names + @attributes_names ||= attributes.each_with_object([]) do |a, names| + names << a.column_name + names << 'password_confirmation' if a.password_digest? + names << "#{a.name}_type" if a.polymorphic? + end + end + def pluralize_table_names? !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names end @@ -169,10 +179,10 @@ module Rails # # ==== Examples # - # check_class_collision suffix: "Observer" + # check_class_collision suffix: "Decorator" # # If the generator is invoked with class name Admin, it will check for - # the presence of "AdminObserver". + # the presence of "AdminDecorator". # def self.check_class_collision(options={}) define_method :check_class_collision do diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 18637451ac..3c62e7a4d2 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -38,7 +38,7 @@ module Rails end def readme - copy_file "README", "README.rdoc" + copy_file "README.rdoc", "README.rdoc" end def gemfile @@ -55,8 +55,20 @@ module Rails def app directory 'app' + + keep_file 'app/assets/images' keep_file 'app/mailers' keep_file 'app/models' + + keep_file 'app/controllers/concerns' + keep_file 'app/models/concerns' + end + + def bin + directory "bin" do |content| + "#{shebang}\n" + content + end + chmod "bin", 0755 & ~File.umask, verbose: false end def config @@ -81,10 +93,6 @@ module Rails directory "db" end - def doc - directory "doc" - end - def lib empty_directory 'lib' empty_directory_with_keep_file 'lib/tasks' @@ -97,18 +105,6 @@ module Rails def public_directory directory "public", "public", recursive: false - if options[:skip_index_html] - remove_file "public/index.html" - remove_file 'app/assets/images/rails.png' - keep_file 'app/assets/images' - end - end - - def script - directory "script" do |content| - "#{shebang}\n" + content - end - chmod "script", 0755, verbose: false end def test @@ -119,7 +115,6 @@ module Rails empty_directory_with_keep_file 'test/helpers' empty_directory_with_keep_file 'test/integration' - template 'test/performance/browsing_test.rb' template 'test/test_helper.rb' end @@ -134,7 +129,9 @@ module Rails end def vendor_javascripts - empty_directory_with_keep_file 'vendor/assets/javascripts' + unless options[:skip_javascript] + empty_directory_with_keep_file 'vendor/assets/javascripts' + end end def vendor_stylesheets @@ -146,7 +143,7 @@ module Rails # We need to store the RAILS_DEV_PATH in a constant, otherwise the path # can change in Ruby 1.8.7 when we FileUtils.cd. RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__)) - RESERVED_NAMES = %w[application destroy benchmarker profiler plugin runner test] + RESERVED_NAMES = %w[application destroy plugin runner test] class AppGenerator < AppBase # :nodoc: add_shared_options_for "application" @@ -156,15 +153,18 @@ module Rails desc: "Show Rails version number and quit" def initialize(*args) - raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank? - super + unless app_path + raise Error, "Application name should be provided in arguments. For details run: rails --help" + end + if !options[:skip_active_record] && !DATABASES.include?(options[:database]) raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}." end end + public_task :set_default_accessors! public_task :create_root def create_root_files @@ -179,6 +179,10 @@ module Rails build(:app) end + def create_bin_files + build(:bin) + end + def create_config_files build(:config) end @@ -196,10 +200,6 @@ module Rails build(:db) end - def create_doc_files - build(:doc) - end - def create_lib_files build(:lib) end @@ -212,10 +212,6 @@ module Rails build(:public_directory) end - def create_script_files - build(:script) - end - def create_test_files build(:test) unless options[:skip_test_unit] end @@ -232,6 +228,12 @@ module Rails build(:leftovers) end + def delete_js_folder_skipping_javascript + if options[:skip_javascript] + remove_dir 'app/assets/javascripts' + end + end + public_task :apply_rails_template, :run_bundle protected @@ -246,7 +248,7 @@ module Rails end def app_name - @app_name ||= defined_app_const_base? ? defined_app_name : File.basename(destination_root) + @app_name ||= (defined_app_const_base? ? defined_app_name : File.basename(destination_root)).tr('\\', '').tr(". ", "_") end def defined_app_name @@ -301,5 +303,76 @@ module Rails defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder end end + + # This class handles preparation of the arguments before the AppGenerator is + # called. The class provides version or help information if they were + # requested, and also constructs the railsrc file (used for extra configuration + # options). + # + # This class should be called before the AppGenerator is required and started + # since it configures and mutates ARGV correctly. + class ARGVScrubber # :nodoc + def initialize(argv = ARGV) + @argv = argv + end + + def prepare! + handle_version_request!(@argv.first) + handle_invalid_command!(@argv.first, @argv) do + handle_rails_rc!(@argv.drop(1)) + end + end + + def self.default_rc_file + File.join(File.expand_path('~'), '.railsrc') + end + + private + + def handle_version_request!(argument) + if ['--version', '-v'].include?(argument) + require 'rails/version' + puts "Rails #{Rails::VERSION::STRING}" + exit(0) + end + end + + def handle_invalid_command!(argument, argv) + if argument == "new" + yield + else + ['--help'] + argv.drop(1) + end + end + + def handle_rails_rc!(argv) + if argv.find { |arg| arg == '--no-rc' } + argv.reject { |arg| arg == '--no-rc' } + else + railsrc(argv) { |rc_argv, rc| insert_railsrc_into_argv!(rc_argv, rc) } + end + end + + def railsrc(argv) + if (customrc = argv.index{ |x| x.include?("--rc=") }) + fname = File.expand_path(argv[customrc].gsub(/--rc=/, "")) + yield(argv.take(customrc) + argv.drop(customrc + 1), fname) + else + yield argv, self.class.default_rc_file + end + end + + def read_rc_file(railsrc) + extra_args = File.readlines(railsrc).flat_map(&:split) + puts "Using #{extra_args.join(" ")} from #{railsrc}" + extra_args + end + + def insert_railsrc_into_argv!(argv, railsrc) + return argv unless File.exist?(railsrc) + extra_args = read_rc_file railsrc + argv.take(1) + extra_args + argv.drop(1) + end + end end end diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 30f8a5f75e..21dcba7947 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -1,25 +1,30 @@ source 'https://rubygems.org' -<%= rails_gemfile_entry -%> - -<%= database_gemfile_entry -%> - -<%= "gem 'jruby-openssl'\n" if defined?(JRUBY_VERSION) -%> - -<%= assets_gemfile_entry %> -<%= javascript_gemfile_entry %> - -# To use ActiveModel has_secure_password -# gem 'bcrypt-ruby', '~> 3.0.0' - -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -# gem 'jbuilder' +<% max_width = gemfile_entries.map { |g| g.name.length }.max -%> +<% gemfile_entries.each do |gem| -%> +<% if gem.comment -%> + +# <%= gem.comment %> +<% end -%> +<%= gem.commented_out ? '# ' : '' %>gem '<%= gem.name %>'<% if gem.version -%> +, '<%= gem.version %>' +<% elsif gem.options.any? -%> +,<%= gem.padding(max_width) %><%= gem.options.map { |k,v| + "#{k}: #{v.inspect}" }.join(', ') %> +<% else %> +<% end -%> +<% end -%> + +# Use ActiveModel has_secure_password +# gem 'bcrypt-ruby', '~> 3.1.2' # Use unicorn as the app server # gem 'unicorn' -# Deploy with Capistrano -# gem 'capistrano', group: :development +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development -# To use debugger -# gem 'debugger' +<% unless defined?(JRUBY_VERSION) -%> +# Use debugger +# gem 'debugger', group: [:development, :test] +<% end -%> diff --git a/railties/lib/rails/generators/rails/app/templates/README b/railties/lib/rails/generators/rails/app/templates/README deleted file mode 100644 index b5d7b6436b..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/README +++ /dev/null @@ -1,259 +0,0 @@ -== Welcome to Rails - -Rails is a web-application framework that includes everything needed to create -database-backed web applications according to the Model-View-Control pattern. - -This pattern splits the view (also called the presentation) into "dumb" -templates that are primarily responsible for inserting pre-built data in between -HTML tags. The model contains the "smart" domain objects (such as Account, -Product, Person, Post) that holds all the business logic and knows how to -persist themselves to a database. The controller handles the incoming requests -(such as Save New Account, Update Product, Show Post) by manipulating the model -and directing data to the view. - -In Rails, the model is handled by what's called an object-relational mapping -layer entitled Active Record. This layer allows you to present the data from -database rows as objects and embellish these data objects with business logic -methods. You can read more about Active Record in -link:files/vendor/rails/activerecord/README.html. - -The controller and view are handled by the Action Pack, which handles both -layers by its two parts: Action View and Action Controller. These two layers -are bundled in a single package due to their heavy interdependence. This is -unlike the relationship between the Active Record and Action Pack that is much -more separate. Each of these packages can be used independently outside of -Rails. You can read more about Action Pack in -link:files/vendor/rails/actionpack/README.html. - - -== Getting Started - -1. At the command prompt, create a new Rails application: - <tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name) - -2. Change directory to <tt>myapp</tt> and start the web server: - <tt>cd myapp; rails server</tt> (run with --help for options) - -3. Go to http://localhost:3000/ and you'll see: - "Welcome aboard: You're riding Ruby on Rails!" - -4. Follow the guidelines to start developing your application. You can find -the following resources handy: - -* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html -* Ruby on Rails Tutorial Book: http://www.railstutorial.org/ - - -== Debugging Rails - -Sometimes your application goes wrong. Fortunately there are a lot of tools that -will help you debug it and get it back on the rails. - -First area to check is the application log files. Have "tail -f" commands -running on the server.log and development.log. Rails will automatically display -debugging and runtime information to these files. Debugging info will also be -shown in the browser on requests from 127.0.0.1. - -You can also log your own messages directly into the log file from your code -using the Ruby logger class from inside your controllers. Example: - - class WeblogController < ActionController::Base - def destroy - @weblog = Weblog.find(params[:id]) - @weblog.destroy - logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") - end - end - -The result will be a message in your log file along the lines of: - - Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! - -More information on how to use the logger is at http://www.ruby-doc.org/core/ - -Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are -several books available online as well: - -* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) -* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) - -These two books will bring you up to speed on the Ruby language and also on -programming in general. - - -== Debugger - -Debugger support is available through the debugger command when you start your -Mongrel or WEBrick server with --debugger. This means that you can break out of -execution at any point in the code, investigate and change the model, and then, -resume execution! You need to install the 'debugger' gem to run the server in debugging -mode. Add gem 'debugger' to your Gemfile and run <tt>bundle</tt> to install it. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.all - debugger - end - end - -So the controller will accept the action, run the first line, then present you -with a IRB prompt in the server window. Here you can do things like: - - >> @posts.inspect - => "[#<Post:0x14a6be8 - @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>, - #<Post:0x14a6620 - @attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]" - >> @posts.first.title = "hello from a debugger" - => "hello from a debugger" - -...and even better, you can examine how your runtime objects actually work: - - >> f = @posts.first - => #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}> - >> f. - Display all 152 possibilities? (y or n) - -Finally, when you're ready to resume execution, you can enter "cont". - - -== Console - -The console is a Ruby shell, which allows you to interact with your -application's domain model. Here you'll have all parts of the application -configured, just like it is when the application is running. You can inspect -domain models, change values, and save to the database. Starting the script -without arguments will launch it in the development environment. - -To start the console, run <tt>rails console</tt> from the application -directory. - -Options: - -* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications - made to the database. -* Passing an environment name as an argument will load the corresponding - environment. Example: <tt>rails console production</tt>. - -To reload your controllers and models after launching the console run -<tt>reload!</tt> - -More information about irb can be found at: -link:http://www.rubycentral.org/pickaxe/irb.html - - -== dbconsole - -You can go to the command line of your database directly through <tt>rails -dbconsole</tt>. You would be connected to the database with the credentials -defined in database.yml. Starting the script without arguments will connect you -to the development database. Passing an argument will connect you to a different -database, like <tt>rails dbconsole production</tt>. Currently works for MySQL, -PostgreSQL and SQLite 3. - -== Description of Contents - -The default directory structure of a generated Ruby on Rails application: - - |-- app - | |-- assets - | |-- images - | |-- javascripts - | `-- stylesheets - | |-- controllers - | |-- helpers - | |-- mailers - | |-- models - | `-- views - | `-- layouts - |-- config - | |-- environments - | |-- initializers - | `-- locales - |-- db - |-- doc - |-- lib - | `-- tasks - |-- log - |-- public - |-- script - |-- test - | |-- fixtures - | |-- functional - | |-- integration - | |-- performance - | `-- unit - |-- tmp - | |-- cache - | |-- pids - | |-- sessions - | `-- sockets - `-- vendor - |-- assets - `-- stylesheets - -app - Holds all the code that's specific to this particular application. - -app/assets - Contains subdirectories for images, stylesheets, and JavaScript files. - -app/controllers - Holds controllers that should be named like weblogs_controller.rb for - automated URL mapping. All controllers should descend from - ApplicationController which itself descends from ActionController::Base. - -app/models - Holds models that should be named like post.rb. Models descend from - ActiveRecord::Base by default. - -app/views - Holds the template files for the view that should be named like - weblogs/index.html.erb for the WeblogsController#index action. All views use - eRuby syntax by default. - -app/views/layouts - Holds the template files for layouts to be used with views. This models the - common header/footer method of wrapping views. In your views, define a layout - using the <tt>layout :default</tt> and create a file named default.html.erb. - Inside default.html.erb, call <% yield %> to render the view using this - layout. - -app/helpers - Holds view helpers that should be named like weblogs_helper.rb. These are - generated for you automatically when using generators for controllers. - Helpers can be used to wrap functionality for your views into methods. - -config - Configuration files for the Rails environment, the routing map, the database, - and other dependencies. - -db - Contains the database schema in schema.rb. db/migrate contains all the - sequence of Migrations for your schema. - -doc - This directory is where your application documentation will be stored when - generated using <tt>rake doc:app</tt> - -lib - Application specific libraries. Basically, any kind of custom code that - doesn't belong under controllers, models, or helpers. This directory is in - the load path. - -public - The directory available for the web server. Also contains the dispatchers and the - default HTML files. This should be set as the DOCUMENT_ROOT of your web - server. - -script - Helper scripts for automation and generation. - -test - Unit and functional tests along with fixtures. When using the rails generate - command, template test files will be generated for you and placed in this - directory. - -vendor - External libraries that the application depends on. If the app has frozen rails, - those gems also go here, under vendor/rails/. This directory is in the load path. diff --git a/railties/lib/rails/generators/rails/app/templates/README.rdoc b/railties/lib/rails/generators/rails/app/templates/README.rdoc new file mode 100644 index 0000000000..dd4e97e22e --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/README.rdoc @@ -0,0 +1,28 @@ +== README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... + + +Please feel free to use a different markup language if you do not plan to run +<tt>rake doc:app</tt>. diff --git a/railties/lib/rails/generators/rails/app/templates/Rakefile b/railties/lib/rails/generators/rails/app/templates/Rakefile index 6eb23f68a3..ba6b733dd2 100644 --- a/railties/lib/rails/generators/rails/app/templates/Rakefile +++ b/railties/lib/rails/generators/rails/app/templates/Rakefile @@ -3,4 +3,4 @@ require File.expand_path('../config/application', __FILE__) -<%= app_const %>.load_tasks +Rails.application.load_tasks diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png b/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png Binary files differdeleted file mode 100644 index d5edc04e65..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png +++ /dev/null diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt index 7342bffd9d..8b91313e51 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt @@ -7,8 +7,8 @@ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // compiled file. // -// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD -// GO AFTER THE REQUIRES BELOW. +// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details +// about supported directives. // <% unless options[:skip_javascript] -%> //= require <%= options[:javascript] %> diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css index 3192ec897b..a443db3401 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css @@ -5,9 +5,11 @@ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. * - * You're free to add application-wide styles to this file and they'll appear at the top of the - * compiled file, but it's generally better to create a new file per style scope. + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any styles + * defined in the other CSS/SCSS files in this directory. It is generally better to create a new + * file per style scope. * - *= require_self *= require_tree . + *= require_self */ diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt index e0539aa8bb..4cf47bd0a0 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt @@ -2,8 +2,12 @@ <html> <head> <title><%= camelized %></title> + <%- if options[:skip_javascript] -%> <%%= stylesheet_link_tag "application", media: "all" %> - <%%= javascript_include_tag "application" %> + <%- else -%> + <%%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> + <%%= javascript_include_tag "application", "data-turbolinks-track" => true %> + <%- end -%> <%%= csrf_meta_tags %> </head> <body> diff --git a/railties/lib/rails/generators/rails/app/templates/bin/bundle b/railties/lib/rails/generators/rails/app/templates/bin/bundle new file mode 100644 index 0000000000..1123dcf501 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/bin/bundle @@ -0,0 +1,2 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/railties/lib/rails/generators/rails/app/templates/bin/rails b/railties/lib/rails/generators/rails/app/templates/bin/rails new file mode 100644 index 0000000000..6a128b95e5 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/bin/rails @@ -0,0 +1,3 @@ +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/railties/lib/rails/generators/rails/app/templates/bin/rake b/railties/lib/rails/generators/rails/app/templates/bin/rake new file mode 100644 index 0000000000..d14fc8395b --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/bin/rake @@ -0,0 +1,3 @@ +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru index fcfbc6b07a..5bc2a619e8 100644 --- a/railties/lib/rails/generators/rails/app/templates/config.ru +++ b/railties/lib/rails/generators/rails/app/templates/config.ru @@ -1,4 +1,4 @@ # This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) -run <%= app_const %> +run Rails.application diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb index fb43c90e21..ac41a0cadb 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -4,15 +4,18 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' <% else -%> # Pick the frameworks you want: +require "active_model/railtie" <%= comment_if :skip_active_record %>require "active_record/railtie" require "action_controller/railtie" require "action_mailer/railtie" -<%= comment_if :skip_sprockets %>require "sprockets/rails/railtie" +<%= comment_if :skip_action_view %>require "action_view/railtie" +<%= comment_if :skip_sprockets %>require "sprockets/railtie" <%= comment_if :skip_test_unit %>require "rails/test_unit/railtie" <% end -%> -# Assets should be precompiled for production (so we don't need the gems loaded then) -Bundler.require(*Rails.groups(assets: %w(development test))) +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(:default, Rails.env) module <%= app_const_base %> class Application < Rails::Application @@ -20,23 +23,17 @@ module <%= app_const_base %> # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. - # Custom directories with classes and modules you want to be autoloadable. - # config.autoload_paths += %W(#{config.root}/extras) + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' - # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password] + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de +<% if options.skip_sprockets? -%> - # Use SQL instead of Active Record's schema dumper when creating the database. - # This is necessary if your schema can't be completely dumped by the schema dumper, - # like if you have constraints or database-specific column types. - # config.active_record.schema_format = :sql - -<% unless options.skip_sprockets? -%> - # Enable the asset pipeline. - config.assets.enabled = true - - # Version of your assets, change this if you want to expire all your assets. - config.assets.version = '1.0' + # Disable the asset pipeline. + config.assets.enabled = false <% end -%> end end diff --git a/railties/lib/rails/generators/rails/app/templates/config/boot.rb b/railties/lib/rails/generators/rails/app/templates/config/boot.rb index 3596736667..5e5f0c1fac 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/boot.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/boot.rb @@ -1,4 +1,4 @@ # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) -require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) +require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml index 22c9194fad..0194dce6f3 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml @@ -26,7 +26,7 @@ development: # domain socket that doesn't need configuration. Windows does not have # domain sockets, so uncomment these lines. #host: localhost - + # The TCP port the server listens on. Defaults to 5432. # If your server runs on a different port number, change accordingly. #port: 5432 @@ -55,6 +55,8 @@ production: adapter: postgresql encoding: unicode database: <%= app_name %>_production + # For details on connection pooling, see rails configration guide + # http://guides.rubyonrails.org/configuring.html#database-pooling pool: 5 username: <%= app_name %> password: diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml new file mode 100644 index 0000000000..7ef89d6608 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml @@ -0,0 +1,57 @@ +# SQL Server (2005 or higher recommended) +# +# Install the adapters and driver +# gem install tiny_tds +# gem install activerecord-sqlserver-adapter +# +# Ensure the activerecord adapter and db driver gems are defined in your Gemfile +# gem 'tiny_tds' +# gem 'activerecord-sqlserver-adapter' +# +# You should make sure freetds is configured correctly first. +# freetds.conf contains host/port/protocol_versions settings. +# http://freetds.schemamania.org/userguide/freetdsconf.htm +# +# A typical Microsoft server +# [mssql] +# host = mssqlserver.yourdomain.com +# port = 1433 +# tds version = 7.1 + +# If you can connect with "tsql -S servername", your basic FreeTDS installation is working. +# 'man tsql' for more info +# Set timeout to a larger number if valid queries against a live db fail + +development: + adapter: sqlserver + encoding: utf8 + reconnect: false + database: <%= app_name %>_development + username: <%= app_name %> + password: + timeout: 25 + dataserver: from_freetds.conf + + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + adapter: sqlserver + encoding: utf8 + reconnect: false + database: <%= app_name %>_test + username: <%= app_name %> + password: + timeout: 25 + dataserver: from_freetds.conf + +production: + adapter: sqlserver + encoding: utf8 + reconnect: false + database: <%= app_name %>_production + username: <%= app_name %> + password: + timeout: 25 + dataserver: from_freetds.conf diff --git a/railties/lib/rails/generators/rails/app/templates/config/environment.rb b/railties/lib/rails/generators/rails/app/templates/config/environment.rb index e080ebd74e..ee8d90dc65 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environment.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/environment.rb @@ -1,5 +1,5 @@ -# Load the rails application. +# Load the Rails application. require File.expand_path('../application', __FILE__) -# Initialize the rails application. -<%= app_const %>.initialize! +# Initialize the Rails application. +Rails.application.initialize! diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt index 6b5b3a0b1f..cff570a631 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt @@ -1,4 +1,4 @@ -<%= app_const %>.configure do +Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # In the development environment your application's code is reloaded on @@ -19,23 +19,15 @@ # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log - # Only use best-standards-support built into browsers. - config.action_dispatch.best_standards_support = :builtin - <%- unless options.skip_active_record? -%> - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL). - config.active_record.auto_explain_threshold_in_seconds = 0.5 - - # Raise an error on page load if there are pending migrations + # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load <%- end -%> <%- unless options.skip_sprockets? -%> - # Do not compress assets. - config.assets.compress = false - # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. config.assets.debug = true <%- end -%> end diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 8aaaba628c..1dfc9f136b 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -1,4 +1,4 @@ -<%= app_const %>.configure do +Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # Code is not reloaded between requests. @@ -24,13 +24,17 @@ <%- unless options.skip_sprockets? -%> # Compress JavaScripts and CSS. - config.assets.compress = true + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass - # Don't fallback to assets pipeline if a precompiled asset is missed. + # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false # Generate digests for assets URLs. config.assets.digest = true + + # Version of your assets, change this if you want to expire all your assets. + config.assets.version = '1.0' <%- end -%> # Specifies the header that your server uses for sending files. @@ -56,17 +60,15 @@ # config.action_controller.asset_host = "http://assets.example.com" <%- unless options.skip_sprockets? -%> - # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added). + # Precompile additional assets. + # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. # config.assets.precompile += %w( search.js ) <%- end -%> # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false - # Enable threaded mode. - # config.threadsafe! - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found). config.i18n.fallbacks = true @@ -74,19 +76,9 @@ # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify - <%- unless options.skip_active_record? -%> - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL). - # config.active_record.auto_explain_threshold_in_seconds = 0.5 - <%- end -%> - # Disable automatic flushing of the log to improve performance. # config.autoflush_log = false # Use default logging formatter so that PID and timestamp are not suppressed. config.log_formatter = ::Logger::Formatter.new - - # Default the production mode queue to an synchronous queue. You will probably - # want to replace this with an out-of-process queueing solution. - # config.queue = ActiveSupport::SynchronousQueue.new end diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt index a5ef0cd9cd..ba0742f97f 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt @@ -1,4 +1,4 @@ -<%= app_const %>.configure do +Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # The test environment is used exclusively to run your application's @@ -13,7 +13,7 @@ config.eager_load = false # Configure static asset server for tests with Cache-Control for performance. - config.serve_static_assets = true + config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" # Show full error reports and disable caching. @@ -33,7 +33,4 @@ # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - - # Use the synchronous queue to run jobs immediately. - config.queue = ActiveSupport::SynchronousQueue.new end diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000000..4a994e1e7b --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb index 9262c3379f..ac033bf9dc 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb @@ -9,7 +9,7 @@ # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end -# + # These inflection rules are supported but not enabled by default: # ActiveSupport::Inflector.inflections(:en) do |inflect| # inflect.acronym 'RESTful' diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/locale.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/locale.rb deleted file mode 100644 index a8285f88ca..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/locale.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. -# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. -# Rails.application.config.time_zone = 'Central Time (US & Canada)' - -# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. -# Rails.application.config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] -# Rails.application.config.i18n.default_locale = :de diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt index 3c5611ca59..f3cc6098a3 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt @@ -1,12 +1,12 @@ # Be sure to restart your server when you modify this file. -# Your secret key for verifying the integrity of signed cookies. +# Your secret key is used for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. # You can use `rake secret` to generate a secure secret key. -# Make sure your secret_token is kept private +# Make sure your secret_key_base is kept private # if you're sharing your code publicly. -<%= app_const %>.config.secret_token = '<%= app_secret %>' +Rails.application.config.secret_key_base = '<%= app_secret %>' diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt index 4a099a4ce2..2bb9b82c61 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt @@ -1,3 +1,3 @@ # Be sure to restart your server when you modify this file. -<%= app_const %>.config.session_store :cookie_store, key: <%= "'_#{app_name}_session'" %> +Rails.application.config.session_store :cookie_store, key: <%= "'_#{app_name}_session'" %> diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt index 280f777cc0..f2110c2c70 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt @@ -1,5 +1,5 @@ # Be sure to restart your server when you modify this file. -# + # This file contains settings for ActionController::ParamsWrapper which # is enabled by default. @@ -7,8 +7,8 @@ ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] if respond_to?(:wrap_parameters) end - <%- unless options.skip_active_record? -%> + # To enable root element in JSON for ActiveRecord objects. # ActiveSupport.on_load(:active_record) do # self.include_root_in_json = true diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb index 631543c705..3f66539d54 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb @@ -1,9 +1,9 @@ -<%= app_const %>.routes.draw do +Rails.application.routes.draw do # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". - # You can have the root of your site routed with "root" just remember to delete public/index.html. - # root to: 'welcome#index' + # You can have the root of your site routed with "root" + # root 'welcome#index' # Example of regular route: # get 'products/:id' => 'catalog#view' @@ -40,6 +40,13 @@ # end # end + # Example resource route with concerns: + # concern :toggleable do + # post 'toggle' + # end + # resources :posts, concerns: :toggleable + # resources :photos, concerns: :toggleable + # Example resource route within a namespace: # namespace :admin do # # Directs /admin/products/* to Admin::ProductsController diff --git a/railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP b/railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP deleted file mode 100644 index fe41f5cc24..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP +++ /dev/null @@ -1,2 +0,0 @@ -Use this README file to introduce your application and point to useful places in the API for learning more. -Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore index 8910bf5a06..6a502e997f 100644 --- a/railties/lib/rails/generators/rails/app/templates/gitignore +++ b/railties/lib/rails/generators/rails/app/templates/gitignore @@ -1,10 +1,10 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. +# See https://help.github.com/articles/ignoring-files for more about ignoring files. # # If you find yourself ignoring temporary files generated by your text editor # or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile ~/.gitignore_global +# git config --global core.excludesfile '~/.gitignore_global' -# Ignore bundler config +# Ignore bundler config. /.bundle # Ignore the default SQLite database. diff --git a/railties/lib/rails/generators/rails/app/templates/public/404.html b/railties/lib/rails/generators/rails/app/templates/public/404.html index 3d875c342e..a0daa0c156 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/404.html +++ b/railties/lib/rails/generators/rails/app/templates/public/404.html @@ -3,16 +3,47 @@ <head> <title>The page you were looking for doesn't exist (404)</title> <style> - body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; } - div.dialog { - width: 25em; - padding: 0 4em; - margin: 4em auto 0 auto; - border: 1px solid #ccc; - border-right-color: #999; - border-bottom-color: #999; - } - h1 { font-size: 100%; color: #f00; line-height: 1.5em; } + body { + background-color: #EFEFEF; + color: #2E2F30; + text-align: center; + font-family: arial, sans-serif; + } + + div.dialog { + width: 25em; + margin: 4em auto 0 auto; + border: 1px solid #CCC; + border-right-color: #999; + border-left-color: #999; + border-bottom-color: #BBB; + border-top: #B00100 solid 4px; + border-top-left-radius: 9px; + border-top-right-radius: 9px; + background-color: white; + padding: 7px 4em 0 4em; + } + + h1 { + font-size: 100%; + color: #730E15; + line-height: 1.5em; + } + + body > p { + width: 33em; + margin: 0 auto 1em; + padding: 1em 0; + background-color: #F7F7F7; + border: 1px solid #CCC; + border-right-color: #999; + border-bottom-color: #999; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-top-color: #DADADA; + color: #666; + box-shadow:0 3px 8px rgba(50, 50, 50, 0.17); + } </style> </head> diff --git a/railties/lib/rails/generators/rails/app/templates/public/422.html b/railties/lib/rails/generators/rails/app/templates/public/422.html index 3f1bfb3417..fbb4b84d72 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/422.html +++ b/railties/lib/rails/generators/rails/app/templates/public/422.html @@ -3,16 +3,47 @@ <head> <title>The change you wanted was rejected (422)</title> <style> - body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; } - div.dialog { - width: 25em; - padding: 0 4em; - margin: 4em auto 0 auto; - border: 1px solid #ccc; - border-right-color: #999; - border-bottom-color: #999; - } - h1 { font-size: 100%; color: #f00; line-height: 1.5em; } + body { + background-color: #EFEFEF; + color: #2E2F30; + text-align: center; + font-family: arial, sans-serif; + } + + div.dialog { + width: 25em; + margin: 4em auto 0 auto; + border: 1px solid #CCC; + border-right-color: #999; + border-left-color: #999; + border-bottom-color: #BBB; + border-top: #B00100 solid 4px; + border-top-left-radius: 9px; + border-top-right-radius: 9px; + background-color: white; + padding: 7px 4em 0 4em; + } + + h1 { + font-size: 100%; + color: #730E15; + line-height: 1.5em; + } + + body > p { + width: 33em; + margin: 0 auto 1em; + padding: 1em 0; + background-color: #F7F7F7; + border: 1px solid #CCC; + border-right-color: #999; + border-bottom-color: #999; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-top-color: #DADADA; + color: #666; + box-shadow:0 3px 8px rgba(50, 50, 50, 0.17); + } </style> </head> @@ -22,5 +53,6 @@ <h1>The change you wanted was rejected.</h1> <p>Maybe you tried to change something you didn't have access to.</p> </div> + <p>If you are the application owner check the logs for more information.</p> </body> </html> diff --git a/railties/lib/rails/generators/rails/app/templates/public/500.html b/railties/lib/rails/generators/rails/app/templates/public/500.html index 012977d3d2..e9052d35bf 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/500.html +++ b/railties/lib/rails/generators/rails/app/templates/public/500.html @@ -3,16 +3,47 @@ <head> <title>We're sorry, but something went wrong (500)</title> <style> - body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; } - div.dialog { - width: 25em; - padding: 0 4em; - margin: 4em auto 0 auto; - border: 1px solid #ccc; - border-right-color: #999; - border-bottom-color: #999; - } - h1 { font-size: 100%; color: #f00; line-height: 1.5em; } + body { + background-color: #EFEFEF; + color: #2E2F30; + text-align: center; + font-family: arial, sans-serif; + } + + div.dialog { + width: 25em; + margin: 4em auto 0 auto; + border: 1px solid #CCC; + border-right-color: #999; + border-left-color: #999; + border-bottom-color: #BBB; + border-top: #B00100 solid 4px; + border-top-left-radius: 9px; + border-top-right-radius: 9px; + background-color: white; + padding: 7px 4em 0 4em; + } + + h1 { + font-size: 100%; + color: #730E15; + line-height: 1.5em; + } + + body > p { + width: 33em; + margin: 0 auto 1em; + padding: 1em 0; + background-color: #F7F7F7; + border: 1px solid #CCC; + border-right-color: #999; + border-bottom-color: #999; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-top-color: #DADADA; + color: #666; + box-shadow:0 3px 8px rgba(50, 50, 50, 0.17); + } </style> </head> diff --git a/railties/lib/rails/generators/rails/app/templates/public/index.html b/railties/lib/rails/generators/rails/app/templates/public/index.html deleted file mode 100644 index dd09a96de9..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/public/index.html +++ /dev/null @@ -1,241 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Ruby on Rails: Welcome aboard</title> - <style media="screen"> - body { - margin: 0; - margin-bottom: 25px; - padding: 0; - background-color: #f0f0f0; - font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana"; - font-size: 13px; - color: #333; - } - - h1 { - font-size: 28px; - color: #000; - } - - a {color: #03c} - a:hover { - background-color: #03c; - color: white; - text-decoration: none; - } - - - #page { - background-color: #f0f0f0; - width: 750px; - margin: 0; - margin-left: auto; - margin-right: auto; - } - - #content { - float: left; - background-color: white; - border: 3px solid #aaa; - border-top: none; - padding: 25px; - width: 500px; - } - - #sidebar { - float: right; - width: 175px; - } - - #footer { - clear: both; - } - - #header, #about, #getting-started { - padding-left: 75px; - padding-right: 30px; - } - - - #header { - background-image: url("assets/rails.png"); - background-repeat: no-repeat; - background-position: top left; - height: 64px; - } - #header h1, #header h2 {margin: 0} - #header h2 { - color: #888; - font-weight: normal; - font-size: 16px; - } - - - #about h3 { - margin: 0; - margin-bottom: 10px; - font-size: 14px; - } - - #about-content { - background-color: #ffd; - border: 1px solid #fc0; - margin-left: -55px; - margin-right: -10px; - } - #about-content table { - margin-top: 10px; - margin-bottom: 10px; - font-size: 11px; - border-collapse: collapse; - } - #about-content td { - padding: 10px; - padding-top: 3px; - padding-bottom: 3px; - } - #about-content td.name {color: #555} - #about-content td.value {color: #000} - - #about-content ul { - padding: 0; - list-style-type: none; - } - - #about-content.failure { - background-color: #fcc; - border: 1px solid #f00; - } - #about-content.failure p { - margin: 0; - padding: 10px; - } - - - #getting-started { - border-top: 1px solid #ccc; - margin-top: 25px; - padding-top: 15px; - } - #getting-started h1 { - margin: 0; - font-size: 20px; - } - #getting-started h2 { - margin: 0; - font-size: 14px; - font-weight: normal; - color: #333; - margin-bottom: 25px; - } - #getting-started ol { - margin-left: 0; - padding-left: 0; - } - #getting-started li { - font-size: 18px; - color: #888; - margin-bottom: 25px; - } - #getting-started li h2 { - margin: 0; - font-weight: normal; - font-size: 18px; - color: #333; - } - #getting-started li p { - color: #555; - font-size: 13px; - } - - - #sidebar ul { - margin-left: 0; - padding-left: 0; - } - #sidebar ul h3 { - margin-top: 25px; - font-size: 16px; - padding-bottom: 10px; - border-bottom: 1px solid #ccc; - } - #sidebar li { - list-style-type: none; - } - #sidebar ul.links li { - margin-bottom: 5px; - } - - .filename { - font-style: italic; - } - </style> - <script> - function about() { - info = document.getElementById('about-content'); - if (window.XMLHttpRequest) - { xhr = new XMLHttpRequest(); } - else - { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } - xhr.open("GET","rails/info/properties",false); - xhr.send(""); - info.innerHTML = xhr.responseText; - info.style.display = 'block' - } - </script> - </head> - <body> - <div id="page"> - <div id="sidebar"> - <ul id="sidebar-items"> - <li> - <h3>Browse the documentation</h3> - <ul class="links"> - <li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li> - <li><a href="http://api.rubyonrails.org/">Rails API</a></li> - <li><a href="http://www.ruby-doc.org/core/">Ruby core</a></li> - <li><a href="http://www.ruby-doc.org/stdlib/">Ruby standard library</a></li> - </ul> - </li> - </ul> - </div> - - <div id="content"> - <div id="header"> - <h1>Welcome aboard</h1> - <h2>You’re riding Ruby on Rails!</h2> - </div> - - <div id="about"> - <h3><a href="rails/info/properties" onclick="about(); return false">About your application’s environment</a></h3> - <div id="about-content" style="display: none"></div> - </div> - - <div id="getting-started"> - <h1>Getting started</h1> - <h2>Here’s how to get rolling:</h2> - - <ol> - <li> - <h2>Use <code>rails generate</code> to create your models and controllers</h2> - <p>To see all available options, run it without parameters.</p> - </li> - - <li> - <h2>Set up a default route and remove <span class="filename">public/index.html</span></h2> - <p>Routes are set up in <span class="filename">config/routes.rb</span>.</p> - </li> - - <li> - <h2>Create your database</h2> - <p>Run <code>rake db:create</code> to create your database. If you're not using SQLite (the default), edit <span class="filename">config/database.yml</span> with your username and password.</p> - </li> - </ol> - </div> - </div> - - <div id="footer"> </div> - </div> - </body> -</html> diff --git a/railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory b/railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/app/templates/script/rails b/railties/lib/rails/generators/rails/app/templates/script/rails deleted file mode 100644 index 11bc1edde9..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/script/rails +++ /dev/null @@ -1,5 +0,0 @@ -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. - -APP_PATH = File.expand_path('../../config/application', __FILE__) -require File.expand_path('../../config/boot', __FILE__) -require 'rails/commands' diff --git a/railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb deleted file mode 100644 index d09ce5ad34..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'test_helper' -require 'rails/performance_test_help' - -class BrowsingTest < ActionDispatch::PerformanceTest - # Refer to the documentation for all available options - # self.profile_options = { runs: 5, metrics: [:wall_time, :memory], - # output: 'tmp/performance', formats: [:flat] } - - test "homepage" do - get '/' - end -end diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb index 9afda2d0df..4fd060341e 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb @@ -1,4 +1,4 @@ -ENV["RAILS_ENV"] = "test" +ENV["RAILS_ENV"] ||= "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' diff --git a/railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory b/railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/controller/USAGE b/railties/lib/rails/generators/rails/controller/USAGE index 9def4af65c..de33900e0a 100644 --- a/railties/lib/rails/generators/rails/controller/USAGE +++ b/railties/lib/rails/generators/rails/controller/USAGE @@ -6,7 +6,7 @@ Description: path like 'parent_module/controller_name'. This generates a controller class in app/controllers and invokes helper, - template engine and test framework generators. + template engine, assets, and test framework generators. Example: `rails generate controller CreditCards open debit credit close` @@ -16,3 +16,4 @@ Example: Test: test/controllers/credit_cards_controller_test.rb Views: app/views/credit_cards/debit.html.erb [...] Helper: app/helpers/credit_cards_helper.rb + Test: test/helpers/credit_cards_helper_test.rb diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb index bae54623c6..ef84447df9 100644 --- a/railties/lib/rails/generators/rails/controller/controller_generator.rb +++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb @@ -10,11 +10,45 @@ module Rails def add_routes actions.reverse.each do |action| - route %{get "#{file_name}/#{action}"} + route generate_routing_code(action) end end hook_for :template_engine, :test_framework, :helper, :assets + + private + + # This method creates nested route entry for namespaced resources. + # For eg. rails g controller foo/bar/baz index + # Will generate - + # namespace :foo do + # namespace :bar do + # get "baz/index" + # end + # end + def generate_routing_code(action) + depth = class_path.length + # Create 'namespace' ladder + # namespace :foo do + # namespace :bar do + namespace_ladder = class_path.each_with_index.map do |ns, i| + indent("namespace :#{ns} do\n", i * 2) + end.join + + # Create route + # get "baz/index" + route = indent(%{get "#{file_name}/#{action}"\n}, depth * 2) + + # Create `end` ladder + # end + # end + end_ladder = (1..depth).reverse_each.map do |i| + indent("end\n", i * 2) + end.join + + # Combine the 3 parts to generate complete route entry + namespace_ladder + route + end_ladder + end end end end diff --git a/railties/lib/rails/generators/rails/generator/USAGE b/railties/lib/rails/generators/rails/generator/USAGE index d28eb3d7d8..799383050c 100644 --- a/railties/lib/rails/generators/rails/generator/USAGE +++ b/railties/lib/rails/generators/rails/generator/USAGE @@ -10,3 +10,4 @@ Example: lib/generators/awesome/awesome_generator.rb lib/generators/awesome/USAGE lib/generators/awesome/templates/ + test/lib/generators/awesome_generator_test.rb diff --git a/railties/lib/rails/generators/rails/generator/generator_generator.rb b/railties/lib/rails/generators/rails/generator/generator_generator.rb index 9a7a516b5b..15d88f06ac 100644 --- a/railties/lib/rails/generators/rails/generator/generator_generator.rb +++ b/railties/lib/rails/generators/rails/generator/generator_generator.rb @@ -10,6 +10,8 @@ module Rails directory '.', generator_dir end + hook_for :test_framework + protected def generator_dir diff --git a/railties/lib/rails/generators/rails/migration/USAGE b/railties/lib/rails/generators/rails/migration/USAGE index af74963b01..baf3d9894f 100644 --- a/railties/lib/rails/generators/rails/migration/USAGE +++ b/railties/lib/rails/generators/rails/migration/USAGE @@ -15,15 +15,21 @@ Example: `rails generate migration AddTitleBodyToPost title:string body:text published:boolean` - This will create the AddTitleBodyToPost in db/migrate/20080514090912_add_title_body_to_post.rb with - this in the Up migration: + This will create the AddTitleBodyToPost in db/migrate/20080514090912_add_title_body_to_post.rb with this in the Change migration: add_column :posts, :title, :string add_column :posts, :body, :text add_column :posts, :published, :boolean - And this in the Down migration: +Migration names containing JoinTable will generate join tables for use with +has_and_belongs_to_many associations. - remove_column :posts, :published - remove_column :posts, :body - remove_column :posts, :title +Example: + `rails g migration CreateMediaJoinTable artists musics:uniq` + + will create the migration + + create_join_table :artists, :musics do |t| + # t.index [:artist_id, :music_id] + t.index [:music_id, :artist_id], unique: true + end diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE index e29e19490e..833b7beb7f 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/rails/generators/rails/model/USAGE @@ -21,12 +21,12 @@ Description: Available field types: - Just after the field name you can specify a type like text or boolean. + Just after the field name you can specify a type like text or boolean. It will generate the column with the associated SQL type. For instance: `rails generate model post title:string body:text` - will generate a title column with a varchar type and a body column with a text + will generate a title column with a varchar type and a body column with a text type. You can use the following types: integer @@ -46,27 +46,33 @@ Available field types: `rails generate model photo title:string album:references` - It will generate an album_id column. You should generate this kind of fields when - you will use a `belongs_to` association for instance. `references` also support - the polymorphism, you could enable the polymorphism like this: + It will generate an `album_id` column. You should generate these kinds of fields when + you will use a `belongs_to` association, for instance. `references` also supports + polymorphism, you can enable polymorphism like this: `rails generate model product supplier:references{polymorphic}` - You can also specify some options just after the field type. You can use the - following options: + For integer, string, text and binary fields, an integer in curly braces will + be set as the limit: - limit Set the maximum size of the field giving a number between curly braces - default Set a default value for the field - precision Defines the precision for the decimal fields - scale Defines the scale for the decimal fields - uniq Defines the field values as unique - index Will add an index on the field + `rails generate model user pseudo:string{30}` - Examples: + For decimal, two integers separated by a comma in curly braces will be used + for precision and scale: + + `rails generate model product 'price:decimal{10,2}'` + + You can add a `:uniq` or `:index` suffix for unique or standard indexes + respectively: - `rails generate model user pseudo:string{30}` `rails generate model user pseudo:string:uniq` - + `rails generate model user pseudo:string:index` + + You can combine any single curly brace option with the index options: + + `rails generate model user username:string{30}:uniq` + `rails generate model product supplier:references{polymorphic}:index` + Examples: `rails generate model account` @@ -76,7 +82,7 @@ Examples: Model: app/models/account.rb Test: test/models/account_test.rb Fixtures: test/fixtures/accounts.yml - Migration: db/migrate/XXX_add_accounts.rb + Migration: db/migrate/XXX_create_accounts.rb `rails generate model post title:string body:text published:boolean` @@ -90,5 +96,5 @@ Examples: Model: app/models/admin/account.rb Test: test/models/admin/account_test.rb Fixtures: test/fixtures/admin/accounts.yml - Migration: db/migrate/XXX_add_admin_accounts.rb + Migration: db/migrate/XXX_create_admin_accounts.rb diff --git a/railties/lib/rails/generators/rails/observer/USAGE b/railties/lib/rails/generators/rails/observer/USAGE deleted file mode 100644 index 177ff49e4a..0000000000 --- a/railties/lib/rails/generators/rails/observer/USAGE +++ /dev/null @@ -1,12 +0,0 @@ -Description: - Stubs out a new observer. Pass the observer name, either CamelCased or - under_scored, as an argument. - - This generator only invokes your ORM and test framework generators. - -Example: - `rails generate observer Account` - - For ActiveRecord and TestUnit it creates: - Observer: app/models/account_observer.rb - TestUnit: test/models/account_observer_test.rb diff --git a/railties/lib/rails/generators/rails/observer/observer_generator.rb b/railties/lib/rails/generators/rails/observer/observer_generator.rb deleted file mode 100644 index 7a4d701ac6..0000000000 --- a/railties/lib/rails/generators/rails/observer/observer_generator.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Rails - module Generators - class ObserverGenerator < NamedBase # :nodoc: - hook_for :orm, required: true - end - end -end diff --git a/railties/lib/rails/generators/rails/performance_test/USAGE b/railties/lib/rails/generators/rails/performance_test/USAGE deleted file mode 100644 index 9dc799559c..0000000000 --- a/railties/lib/rails/generators/rails/performance_test/USAGE +++ /dev/null @@ -1,10 +0,0 @@ -Description: - Stubs out a new performance test. Pass the name of the test, either - CamelCased or under_scored, as an argument. - - This generator invokes the current performance tool, which defaults to - TestUnit. - -Example: - `rails generate performance_test GeneralStories` creates a GeneralStories - performance test in test/performance/general_stories_test.rb diff --git a/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb b/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb deleted file mode 100644 index 56cd562f3d..0000000000 --- a/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Rails - module Generators - class PerformanceTestGenerator < NamedBase # :nodoc: - hook_for :performance_tool, as: :performance - end - end -end diff --git a/railties/lib/rails/generators/rails/plugin_new/USAGE b/railties/lib/rails/generators/rails/plugin/USAGE index 9a7bf9f396..9a7bf9f396 100644 --- a/railties/lib/rails/generators/rails/plugin_new/USAGE +++ b/railties/lib/rails/generators/rails/plugin/USAGE diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index 4a0bcc35a4..f6f529b80a 100644 --- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -53,13 +53,11 @@ module Rails template "lib/%name%.rb" template "lib/tasks/%name%_tasks.rake" template "lib/%name%/version.rb" - if full? - template "lib/%name%/engine.rb" - end + template "lib/%name%/engine.rb" if engine? end def config - template "config/routes.rb" if full? + template "config/routes.rb" if engine? end def test @@ -70,7 +68,7 @@ module Rails task default: :test EOF - if full? + if engine? template "test/integration/navigation_test.rb" end end @@ -96,6 +94,11 @@ task default: :test end end + def test_dummy_assets + template "rails/javascripts.js", "#{dummy_path}/app/assets/javascripts/application.js", force: true + template "rails/stylesheets.css", "#{dummy_path}/app/assets/stylesheets/application.css", force: true + end + def test_dummy_clean inside dummy_path do remove_file ".gitignore" @@ -103,8 +106,6 @@ task default: :test remove_file "doc" remove_file "Gemfile" remove_file "lib/tasks" - remove_file "app/assets/images/rails.png" - remove_file "public/index.html" remove_file "public/robots.txt" remove_file "README" remove_file "test" @@ -114,7 +115,7 @@ task default: :test def stylesheets if mountable? - copy_file "#{app_templates_dir}/app/assets/stylesheets/application.css", + copy_file "rails/stylesheets.css", "app/assets/stylesheets/#{name}/application.css" elsif full? empty_directory_with_keep_file "app/assets/stylesheets/#{name}" @@ -125,20 +126,20 @@ task default: :test return if options.skip_javascript? if mountable? - template "#{app_templates_dir}/app/assets/javascripts/application.js.tt", - "app/assets/javascripts/#{name}/application.js" + template "rails/javascripts.js", + "app/assets/javascripts/#{name}/application.js" elsif full? empty_directory_with_keep_file "app/assets/javascripts/#{name}" end end - def script(force = false) - return unless full? + def bin(force = false) + return unless engine? - directory "script", force: force do |content| + directory "bin", force: force do |content| "#{shebang}\n" + content end - chmod "script", 0755, verbose: false + chmod "bin", 0755, verbose: false end def gemfile_entry @@ -153,7 +154,7 @@ task default: :test end module Generators - class PluginNewGenerator < AppBase # :nodoc: + class PluginGenerator < AppBase # :nodoc: add_shared_options_for "plugin" alias_method :plugin_path, :app_path @@ -175,12 +176,15 @@ task default: :test "skip adding entry to Gemfile" def initialize(*args) - raise Error, "Options should be given after the plugin name. For details run: rails plugin --help" if args[0].blank? - @dummy_path = nil super + + unless plugin_path + raise Error, "Plugin name should be provided in arguments. For details run: rails plugin new --help" + end end + public_task :set_default_accessors! public_task :create_root def create_root_files @@ -216,8 +220,8 @@ task default: :test build(:images) end - def create_script_files - build(:script) + def create_bin_files + build(:bin) end def create_test_files @@ -225,7 +229,7 @@ task default: :test end def create_test_dummy_files - return if options[:skip_test_unit] && options[:dummy_path] == 'test/dummy' + return unless with_dummy_app? create_dummy_app end @@ -265,20 +269,29 @@ task default: :test build(:generate_test_dummy) store_application_definition! build(:test_dummy_config) + build(:test_dummy_assets) build(:test_dummy_clean) - # ensure that script/rails has proper dummy_path - build(:script, true) + # ensure that bin/rails has proper dummy_path + build(:bin, true) end end + def engine? + full? || mountable? + end + def full? - options[:full] || options[:mountable] + options[:full] end def mountable? options[:mountable] end + def with_dummy_app? + options[:skip_test_unit].blank? || options[:dummy_path] != 'test/dummy' + end + def self.banner "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]" end @@ -307,7 +320,7 @@ task default: :test @application_definition ||= begin dummy_application_path = File.expand_path("#{dummy_path}/config/application.rb", destination_root) - unless options[:pretend] || !File.exists?(dummy_application_path) + unless options[:pretend] || !File.exist?(dummy_application_path) contents = File.read(dummy_application_path) contents[(contents.index(/module ([\w]+)\n(.*)class Application/m))..-1] end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec index 568ed653b7..5fdf0e1554 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +++ b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec @@ -12,6 +12,7 @@ Gem::Specification.new do |s| s.homepage = "TODO" s.summary = "TODO: Summary of <%= camelized %>." s.description = "TODO: Description of <%= camelized %>." + s.license = "MIT" s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"] <% unless options.skip_test_unit? -%> @@ -19,9 +20,6 @@ Gem::Specification.new do |s| <% end -%> <%= '# ' if options.dev? || options.edge? -%>s.add_dependency "rails", "~> <%= Rails::VERSION::STRING %>" -<% if full? && !options[:skip_javascript] -%> - # s.add_dependency "<%= "#{options[:javascript]}-rails" %>" -<% end -%> <% unless options[:skip_active_record] -%> s.add_development_dependency "<%= gem_for_database %>" diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin/templates/Gemfile index 7448b386c5..d576784415 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile +++ b/railties/lib/rails/generators/rails/plugin/templates/Gemfile @@ -1,10 +1,7 @@ -source "http://rubygems.org" +source "https://rubygems.org" <% if options[:skip_gemspec] -%> <%= '# ' if options.dev? || options.edge? -%>gem "rails", "~> <%= Rails::VERSION::STRING %>" -<% if full? && !options[:skip_javascript] -%> -# gem "<%= "#{options[:javascript]}-rails" %>" -<% end -%> <% else -%> # Declare your gem's dependencies in <%= name %>.gemspec. # Bundler will treat runtime dependencies like base dependencies, and @@ -12,11 +9,6 @@ source "http://rubygems.org" gemspec <% end -%> -<% unless options[:javascript] == 'jquery' -%> -# jquery-rails is used by the dummy application -gem "jquery-rails" - -<% end -%> <% if options[:skip_gemspec] -%> group :development do gem "<%= gem_for_database %>" @@ -31,7 +23,20 @@ end <% if options.dev? || options.edge? -%> # Your gem is dependent on dev or edge Rails. Once you can lock this # dependency down to a specific version, move it to your gemspec. -<%= rails_gemfile_entry -%> +<% max_width = gemfile_entries.map { |g| g.name.length }.max -%> +<% gemfile_entries.each do |gem| -%> +<% if gem.comment -%> + +# <%= gem.comment %> +<% end -%> +<%= gem.commented_out ? '# ' : '' %>gem '<%= gem.name %>'<% if gem.version -%> +, '<%= gem.version %>' +<% elsif gem.options.any? -%> +,<%= gem.padding(max_width) %><%= gem.options.map { |k,v| + "#{k}: #{v.inspect}" }.join(', ') %> +<% else %> +<% end -%> +<% end -%> <% end -%> # To use debugger diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE index d7a9109894..d7a9109894 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE +++ b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc b/railties/lib/rails/generators/rails/plugin/templates/README.rdoc index 301d647731..301d647731 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc +++ b/railties/lib/rails/generators/rails/plugin/templates/README.rdoc diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin/templates/Rakefile index 1369140537..0ba899176c 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile +++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile @@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc| rdoc.rdoc_files.include('lib/**/*.rb') end -<% if full? && !options[:skip_active_record] && !options[:skip_test_unit] -%> +<% if engine? && !options[:skip_active_record] && with_dummy_app? -%> APP_RAKEFILE = File.expand_path("../<%= dummy_path -%>/Rakefile", __FILE__) load 'rails/tasks/engine.rake' <% end %> diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%name%/application_controller.rb.tt index 448ad7f989..448ad7f989 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%name%/application_controller.rb.tt diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/helpers/%name%/application_helper.rb.tt index 40ae9f52c2..40ae9f52c2 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/helpers/%name%/application_helper.rb.tt diff --git a/railties/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +++ b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory diff --git a/railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory b/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory +++ b/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/views/layouts/%name%/application.html.erb.tt index 1d380420b4..1d380420b4 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/views/layouts/%name%/application.html.erb.tt diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt b/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt index aa87d1b50c..c8de9f3e0f 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt @@ -1,4 +1,4 @@ -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. +# This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application. ENGINE_ROOT = File.expand_path('../..', __FILE__) ENGINE_PATH = File.expand_path('../../lib/<%= name -%>/engine', __FILE__) diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb b/railties/lib/rails/generators/rails/plugin/templates/config/routes.rb index 8e158d5831..8e158d5831 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/config/routes.rb diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/gitignore b/railties/lib/rails/generators/rails/plugin/templates/gitignore index 086d87818a..086d87818a 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/gitignore +++ b/railties/lib/rails/generators/rails/plugin/templates/gitignore diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%name%.rb index 2d3bdc510c..40c074cced 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%name%.rb @@ -1,4 +1,4 @@ -<% if full? -%> +<% if engine? -%> require "<%= name %>/engine" <% end -%> diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%name%/engine.rb index 967668fe66..967668fe66 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%name%/engine.rb diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/version.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%name%/version.rb index ef07ef2e19..ef07ef2e19 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/version.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%name%/version.rb diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake b/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%name%_tasks.rake index 7121f5ae23..7121f5ae23 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%name%_tasks.rake diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb index 2f9b7fc962..5508829f6b 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb @@ -7,11 +7,12 @@ require 'rails/all' <%= comment_if :skip_active_record %>require "active_record/railtie" require "action_controller/railtie" require "action_mailer/railtie" -<%= comment_if :skip_sprockets %>require "sprockets/rails/railtie" +<%= comment_if :skip_action_view %>require "action_view/railtie" +<%= comment_if :skip_sprockets %>require "sprockets/railtie" <%= comment_if :skip_test_unit %>require "rails/test_unit/railtie" <% end -%> -Bundler.require +Bundler.require(*Rails.groups) require "<%= name %>" <%= application_definition %> diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb new file mode 100644 index 0000000000..6266cfc509 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb @@ -0,0 +1,5 @@ +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) + +require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) +$LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__) diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js new file mode 100644 index 0000000000..5bc2e1c8b5 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js @@ -0,0 +1,13 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. +// +// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require_tree . diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb index 730ee31c3d..730ee31c3d 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css new file mode 100644 index 0000000000..a443db3401 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, + * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any styles + * defined in the other CSS/SCSS files in this directory. It is generally better to create a new + * file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb b/railties/lib/rails/generators/rails/plugin/templates/test/%name%_test.rb index 0a8bbd4aaf..0a8bbd4aaf 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/test/%name%_test.rb diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb b/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb index 824caecb24..824caecb24 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb index 1e26a313cd..1e26a313cd 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/mailers/.empty_directory b/railties/lib/rails/generators/rails/plugin_new/templates/app/mailers/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/plugin_new/templates/app/mailers/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory b/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb deleted file mode 100644 index c78bfb7f63..0000000000 --- a/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb +++ /dev/null @@ -1,9 +0,0 @@ -gemfile = File.expand_path('../../../../Gemfile', __FILE__) - -if File.exist?(gemfile) - ENV['BUNDLE_GEMFILE'] = gemfile - require 'bundler' - Bundler.setup -end - -$:.unshift File.expand_path('../../../../lib', __FILE__)
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb index 121205b254..a0e5553e44 100644 --- a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb +++ b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb @@ -32,7 +32,7 @@ module Rails # route prepends two spaces onto the front of the string that is passed, this corrects that route route_string[2..-1] end - + private def route_string @route_string ||= "" diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb index b4f466fbd8..e89789e72b 100644 --- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb @@ -2,12 +2,19 @@ require 'rails/generators/rails/resource/resource_generator' module Rails module Generators - class ScaffoldGenerator < ResourceGenerator # :nodoc: + class ScaffoldGenerator < ResourceGenerator # :nodoc: remove_hook_for :resource_controller remove_class_option :actions class_option :stylesheets, type: :boolean, desc: "Generate Stylesheets" class_option :stylesheet_engine, desc: "Engine for Stylesheets" + class_option :assets, type: :boolean + class_option :resource_route, type: :boolean + + def handle_skip + @options = @options.merge(stylesheets: false) unless options[:assets] + @options = @options.merge(stylesheet_engine: false) unless options[:stylesheets] + end hook_for :scaffold_controller, required: true @@ -16,7 +23,9 @@ module Rails end hook_for :stylesheet_engine do |stylesheet_engine| - invoke stylesheet_engine, [controller_name] if options[:stylesheets] && behavior == :invoke + if behavior == :invoke + invoke stylesheet_engine, [controller_name] + end end end end diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb index 4f36b612ae..6bf0a33a5f 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb @@ -13,7 +13,7 @@ module Rails argument :attributes, type: :array, default: [], banner: "field:type field:type" def create_controller_files - template "controller.rb", File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb") + template "controller.rb", File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb") end hook_for :template_engine, :test_framework, as: :scaffold diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb index d6bce40b0c..0e69aa101f 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb @@ -4,97 +4,64 @@ require_dependency "<%= namespaced_file_path %>/application_controller" <% end -%> <% module_namespacing do -%> class <%= controller_class_name %>Controller < ApplicationController + before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy] + # GET <%= route_url %> - # GET <%= route_url %>.json def index @<%= plural_table_name %> = <%= orm_class.all(class_name) %> - - respond_to do |format| - format.html # index.html.erb - format.json { render json: <%= "@#{plural_table_name}" %> } - end end # GET <%= route_url %>/1 - # GET <%= route_url %>/1.json def show - @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> - - respond_to do |format| - format.html # show.html.erb - format.json { render json: <%= "@#{singular_table_name}" %> } - end end # GET <%= route_url %>/new - # GET <%= route_url %>/new.json def new @<%= singular_table_name %> = <%= orm_class.build(class_name) %> - - respond_to do |format| - format.html # new.html.erb - format.json { render json: <%= "@#{singular_table_name}" %> } - end end # GET <%= route_url %>/1/edit def edit - @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> end # POST <%= route_url %> - # POST <%= route_url %>.json def create @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %> - respond_to do |format| - if @<%= orm_instance.save %> - format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %> } - format.json { render json: <%= "@#{singular_table_name}" %>, status: :created, location: <%= "@#{singular_table_name}" %> } - else - format.html { render action: "new" } - format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity } - end + if @<%= orm_instance.save %> + redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %> + else + render action: 'new' end end # PATCH/PUT <%= route_url %>/1 - # PATCH/PUT <%= route_url %>/1.json def update - @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> - - respond_to do |format| - if @<%= orm_instance.update_attributes("#{singular_table_name}_params") %> - format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %> } - format.json { head :no_content } - else - format.html { render action: "edit" } - format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity } - end + if @<%= orm_instance.update("#{singular_table_name}_params") %> + redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %> + else + render action: 'edit' end end # DELETE <%= route_url %>/1 - # DELETE <%= route_url %>/1.json def destroy - @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> @<%= orm_instance.destroy %> - - respond_to do |format| - format.html { redirect_to <%= index_helper %>_url } - format.json { head :no_content } - end + redirect_to <%= index_helper %>_url, notice: <%= "'#{human_name} was successfully destroyed.'" %> end private + # Use callbacks to share common setup or constraints between actions. + def set_<%= singular_table_name %> + @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %> + end - # Use this method to whitelist the permissible parameters. Example: params.require(:person).permit(:name, :age) - # Also, you can specialize this method with per-user checking of permissible attributes. + # Only allow a trusted parameter "white list" through. def <%= "#{singular_table_name}_params" %> - <%- if attributes.empty? -%> - params[<%= ":#{singular_table_name}" %>] + <%- if attributes_names.empty? -%> + params[:<%= singular_table_name %>] <%- else -%> - params.require(<%= ":#{singular_table_name}" %>).permit(<%= attributes.map {|a| ":#{a.name}" }.join(', ') %>) + params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>) <%- end -%> end end diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb index 7fd5c00768..a01eb57651 100644 --- a/railties/lib/rails/generators/resource_helpers.rb +++ b/railties/lib/rails/generators/resource_helpers.rb @@ -9,11 +9,19 @@ module Rails def self.included(base) #:nodoc: base.class_option :force_plural, type: :boolean, desc: "Forces the use of a plural ModelName" + base.class_option :model_name, type: :string, desc: "ModelName to be used" end # Set controller variables on initialization. def initialize(*args) #:nodoc: super + if options[:model_name] + controller_name = name + self.name = options[:model_name] + assign_names!(self.name) + else + controller_name = name + end if name == name.pluralize && name.singularize != name.pluralize && !options[:force_plural] unless ResourceHelpers.skip_warn @@ -24,19 +32,26 @@ module Rails assign_names!(name) end - @controller_name = name.pluralize + assign_controller_names!(controller_name.pluralize) end protected - attr_reader :controller_name + attr_reader :controller_name, :controller_file_name def controller_class_path - class_path + if options[:model_name] + @controller_class_path + else + class_path + end end - def controller_file_name - @controller_file_name ||= file_name.pluralize + def assign_controller_names!(name) + @controller_name = name + @controller_class_path = name.include?('/') ? name.split('/') : name.split('::') + @controller_class_path.map! { |m| m.underscore } + @controller_file_name = @controller_class_path.pop end def controller_file_path diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb index 24308dcf6c..58592b4f8e 100644 --- a/railties/lib/rails/generators/test_case.rb +++ b/railties/lib/rails/generators/test_case.rb @@ -1,8 +1,7 @@ -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/module/delegation' -require 'active_support/core_ext/hash/reverse_merge' -require 'active_support/core_ext/kernel/reporting' require 'rails/generators' +require 'rails/generators/testing/behaviour' +require 'rails/generators/testing/setup_and_teardown' +require 'rails/generators/testing/assertions' require 'fileutils' module Rails @@ -27,215 +26,11 @@ module Rails # setup :prepare_destination # end class TestCase < ActiveSupport::TestCase + include Rails::Generators::Testing::Behaviour + include Rails::Generators::Testing::SetupAndTeardown + include Rails::Generators::Testing::Assertions include FileUtils - class_attribute :destination_root, :current_path, :generator_class, :default_arguments - - # Generators frequently change the current path using +FileUtils.cd+. - # So we need to store the path at file load and revert back to it after each test. - self.current_path = File.expand_path(Dir.pwd) - self.default_arguments = [] - - def setup # :nodoc: - destination_root_is_set? - ensure_current_path - super - end - - def teardown # :nodoc: - ensure_current_path - super - end - - # Sets which generator should be tested: - # - # tests AppGenerator - def self.tests(klass) - self.generator_class = klass - end - - # Sets default arguments on generator invocation. This can be overwritten when - # invoking it. - # - # arguments %w(app_name --skip-active-record) - def self.arguments(array) - self.default_arguments = array - end - - # Sets the destination of generator files: - # - # destination File.expand_path("../tmp", File.dirname(__FILE__)) - def self.destination(path) - self.destination_root = path - end - - # Asserts a given file exists. You need to supply an absolute path or a path relative - # to the configured destination: - # - # assert_file "config/environment.rb" - # - # You can also give extra arguments. If the argument is a regexp, it will check if the - # regular expression matches the given file content. If it's a string, it compares the - # file with the given string: - # - # assert_file "config/environment.rb", /initialize/ - # - # Finally, when a block is given, it yields the file content: - # - # assert_file "app/controllers/products_controller.rb" do |controller| - # assert_instance_method :index, controller do |index| - # assert_match(/Product\.all/, index) - # end - # end - def assert_file(relative, *contents) - absolute = File.expand_path(relative, destination_root) - assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" - - read = File.read(absolute) if block_given? || !contents.empty? - yield read if block_given? - - contents.each do |content| - case content - when String - assert_equal content, read - when Regexp - assert_match content, read - end - end - end - alias :assert_directory :assert_file - - # Asserts a given file does not exist. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_no_file "config/random.rb" - def assert_no_file(relative) - absolute = File.expand_path(relative, destination_root) - assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" - end - alias :assert_no_directory :assert_no_file - - # Asserts a given migration exists. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_migration "db/migrate/create_products.rb" - # - # This method manipulates the given path and tries to find any migration which - # matches the migration name. For example, the call above is converted to: - # - # assert_file "db/migrate/003_create_products.rb" - # - # Consequently, assert_migration accepts the same arguments has assert_file. - def assert_migration(relative, *contents, &block) - file_name = migration_file_name(relative) - assert file_name, "Expected migration #{relative} to exist, but was not found" - assert_file file_name, *contents, &block - end - - # Asserts a given migration does not exist. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_no_migration "db/migrate/create_products.rb" - def assert_no_migration(relative) - file_name = migration_file_name(relative) - assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" - end - - # Asserts the given class method exists in the given content. This method does not detect - # class methods inside (class << self), only class methods which starts with "self.". - # When a block is given, it yields the content of the method. - # - # assert_migration "db/migrate/create_products.rb" do |migration| - # assert_class_method :up, migration do |up| - # assert_match(/create_table/, up) - # end - # end - def assert_class_method(method, content, &block) - assert_instance_method "self.#{method}", content, &block - end - - # Asserts the given method exists in the given content. When a block is given, - # it yields the content of the method. - # - # assert_file "app/controllers/products_controller.rb" do |controller| - # assert_instance_method :index, controller do |index| - # assert_match(/Product\.all/, index) - # end - # end - def assert_instance_method(method, content) - assert content =~ /def #{method}(\(.+\))?(.*?)\n end/m, "Expected to have method #{method}" - yield $2.strip if block_given? - end - alias :assert_method :assert_instance_method - - # Asserts the given attribute type gets translated to a field type - # properly: - # - # assert_field_type :date, :date_select - def assert_field_type(attribute_type, field_type) - assert_equal(field_type, create_generated_attribute(attribute_type).field_type) - end - - # Asserts the given attribute type gets a proper default value: - # - # assert_field_default_value :string, "MyString" - def assert_field_default_value(attribute_type, value) - assert_equal(value, create_generated_attribute(attribute_type).default) - end - - # Runs the generator configured for this class. The first argument is an array like - # command line arguments: - # - # class AppGeneratorTest < Rails::Generators::TestCase - # tests AppGenerator - # destination File.expand_path("../tmp", File.dirname(__FILE__)) - # teardown :cleanup_destination_root - # - # test "database.yml is not created when skipping Active Record" do - # run_generator %w(myapp --skip-active-record) - # assert_no_file "config/database.yml" - # end - # end - # - # You can provide a configuration hash as second argument. This method returns the output - # printed by the generator. - def run_generator(args=self.default_arguments, config={}) - capture(:stdout) { self.generator_class.start(args, config.reverse_merge(destination_root: destination_root)) } - end - - # Instantiate the generator. - def generator(args=self.default_arguments, options={}, config={}) - @generator ||= self.generator_class.new(args, options, config.reverse_merge(destination_root: destination_root)) - end - - # Create a Rails::Generators::GeneratedAttribute by supplying the - # attribute type and, optionally, the attribute name: - # - # create_generated_attribute(:string, 'name') - def create_generated_attribute(attribute_type, name = 'test', index = nil) - Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':')) - end - - protected - - def destination_root_is_set? # :nodoc: - raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root - end - - def ensure_current_path # :nodoc: - cd current_path - end - - def prepare_destination # :nodoc: - rm_rf(destination_root) - mkdir_p(destination_root) - end - - def migration_file_name(relative) # :nodoc: - absolute = File.expand_path(relative, destination_root) - dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') - Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first - end end end end diff --git a/railties/lib/rails/generators/test_unit/generator/generator_generator.rb b/railties/lib/rails/generators/test_unit/generator/generator_generator.rb new file mode 100644 index 0000000000..d7307398ce --- /dev/null +++ b/railties/lib/rails/generators/test_unit/generator/generator_generator.rb @@ -0,0 +1,26 @@ +require 'rails/generators/test_unit' + +module TestUnit # :nodoc: + module Generators # :nodoc: + class GeneratorGenerator < Base # :nodoc: + check_class_collision suffix: "GeneratorTest" + + class_option :namespace, type: :boolean, default: true, + desc: "Namespace generator under lib/generators/name" + + def create_generator_files + template 'generator_test.rb', File.join('test/lib/generators', class_path, "#{file_name}_generator_test.rb") + end + + protected + + def generator_path + if options[:namespace] + File.join("generators", regular_class_path, file_name, "#{file_name}_generator") + else + File.join("generators", regular_class_path, "#{file_name}_generator") + end + end + end + end +end diff --git a/railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb b/railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb new file mode 100644 index 0000000000..a7f1fc4fba --- /dev/null +++ b/railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb @@ -0,0 +1,16 @@ +require 'test_helper' +require '<%= generator_path %>' + +<% module_namespacing do -%> +class <%= class_name %>GeneratorTest < Rails::Generators::TestCase + tests <%= class_name %>Generator + destination Rails.root.join('tmp/generators') + setup :prepare_destination + + # test "generator runs without errors" do + # assert_nothing_raised do + # run_generator ["arguments"] + # end + # end +end +<% end -%> diff --git a/railties/lib/rails/generators/test_unit/model/model_generator.rb b/railties/lib/rails/generators/test_unit/model/model_generator.rb index 2801749ffe..2826a3ffa1 100644 --- a/railties/lib/rails/generators/test_unit/model/model_generator.rb +++ b/railties/lib/rails/generators/test_unit/model/model_generator.rb @@ -3,6 +3,9 @@ require 'rails/generators/test_unit' module TestUnit # :nodoc: module Generators # :nodoc: class ModelGenerator < Base # :nodoc: + + RESERVED_YAML_KEYWORDS = %w(y yes n no true false on off null) + argument :attributes, type: :array, default: [], banner: "field:type field:type" class_option :fixture, type: :boolean @@ -19,6 +22,15 @@ module TestUnit # :nodoc: template 'fixtures.yml', File.join('test/fixtures', class_path, "#{plural_file_name}.yml") end end + + private + def yaml_key_value(key, value) + if RESERVED_YAML_KEYWORDS.include?(key.downcase) + "'#{key}': #{value}" + else + "#{key}: #{value}" + end + end end end end diff --git a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml index 5c8780aa64..f19e9d1d87 100644 --- a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml +++ b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml @@ -1,16 +1,20 @@ -# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html <% unless attributes.empty? -%> -one: +<% %w(one two).each do |name| %> +<%= name %>: <% attributes.each do |attribute| -%> - <%= attribute.name %>: <%= attribute.default %> + <%- if attribute.password_digest? -%> + password_digest: <%%= BCrypt::Password.create('secret') %> + <%- else -%> + <%= yaml_key_value(attribute.column_name, attribute.default) %> + <%- end -%> + <%- if attribute.polymorphic? -%> + <%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %> + <%- end -%> <% end -%> - -two: -<% attributes.each do |attribute| -%> - <%= attribute.name %>: <%= attribute.default %> <% end -%> <% else -%> + # This model initially had no columns defined. If you add columns to the # model remove the '{}' from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below diff --git a/railties/lib/rails/generators/test_unit/observer/observer_generator.rb b/railties/lib/rails/generators/test_unit/observer/observer_generator.rb deleted file mode 100644 index 64fe694a8b..0000000000 --- a/railties/lib/rails/generators/test_unit/observer/observer_generator.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails/generators/test_unit' - -module TestUnit # :nodoc: - module Generators # :nodoc: - class ObserverGenerator < Base # :nodoc: - check_class_collision suffix: "ObserverTest" - - def create_test_files - template 'unit_test.rb', File.join('test/models', class_path, "#{file_name}_observer_test.rb") - end - end - end -end diff --git a/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb b/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb deleted file mode 100644 index 28aa23626a..0000000000 --- a/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'test_helper' - -<% module_namespacing do -%> -class <%= class_name %>ObserverTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end -<% end -%> diff --git a/railties/lib/rails/generators/test_unit/performance/performance_generator.rb b/railties/lib/rails/generators/test_unit/performance/performance_generator.rb deleted file mode 100644 index 5552edeee4..0000000000 --- a/railties/lib/rails/generators/test_unit/performance/performance_generator.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails/generators/test_unit' - -module TestUnit # :nodoc: - module Generators # :nodoc: - class PerformanceGenerator < Base # :nodoc: - check_class_collision suffix: "Test" - - def create_test_files - template 'performance_test.rb', File.join('test/performance', class_path, "#{file_name}_test.rb") - end - end - end -end diff --git a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb b/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb deleted file mode 100644 index 2bcb482d68..0000000000 --- a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'test_helper' -require 'rails/performance_test_help' - -class <%= class_name %>Test < ActionDispatch::PerformanceTest - # Refer to the documentation for all available options - # self.profile_options = { runs: 5, metrics: [:wall_time, :memory], - # output: 'tmp/performance', formats: [:flat] } - - test "homepage" do - get '/' - end -end diff --git a/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb b/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb index c9af2ca832..30a861f09d 100644 --- a/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +++ b/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb @@ -1,2 +1,2 @@ -require 'minitest/autorun' +require 'active_support/testing/autorun' require 'active_support' diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb index 3b4fec2e83..2e1f55f2a6 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb @@ -18,17 +18,16 @@ module TestUnit # :nodoc: private def attributes_hash - return if accessible_attributes.empty? - - accessible_attributes.map do |a| - name = a.name - "#{name}: @#{singular_table_name}.#{name}" + return if attributes_names.empty? + + attributes_names.map do |name| + if %w(password password_confirmation).include?(name) && attributes.any?(&:password_digest?) + "#{name}: 'secret'" + else + "#{name}: @#{singular_table_name}.#{name}" + end end.sort.join(', ') end - - def accessible_attributes - attributes.reject(&:reference?) - end end end end diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb index 30e1650555..18bd1ece9d 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb @@ -36,7 +36,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase end test "should update <%= singular_table_name %>" do - put :update, id: <%= "@#{singular_table_name}" %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %> + patch :update, id: <%= "@#{singular_table_name}" %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %> assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>)) end diff --git a/railties/lib/rails/generators/testing/assertions.rb b/railties/lib/rails/generators/testing/assertions.rb new file mode 100644 index 0000000000..2e877f8762 --- /dev/null +++ b/railties/lib/rails/generators/testing/assertions.rb @@ -0,0 +1,121 @@ +module Rails + module Generators + module Testing + module Assertions + # Asserts a given file exists. You need to supply an absolute path or a path relative + # to the configured destination: + # + # assert_file "config/environment.rb" + # + # You can also give extra arguments. If the argument is a regexp, it will check if the + # regular expression matches the given file content. If it's a string, it compares the + # file with the given string: + # + # assert_file "config/environment.rb", /initialize/ + # + # Finally, when a block is given, it yields the file content: + # + # assert_file "app/controllers/products_controller.rb" do |controller| + # assert_instance_method :index, controller do |index| + # assert_match(/Product\.all/, index) + # end + # end + def assert_file(relative, *contents) + absolute = File.expand_path(relative, destination_root).shellescape + assert File.exist?(absolute), "Expected file #{relative.inspect} to exist, but does not" + + read = File.read(absolute) if block_given? || !contents.empty? + yield read if block_given? + + contents.each do |content| + case content + when String + assert_equal content, read + when Regexp + assert_match content, read + end + end + end + alias :assert_directory :assert_file + + # Asserts a given file does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_file "config/random.rb" + def assert_no_file(relative) + absolute = File.expand_path(relative, destination_root) + assert !File.exist?(absolute), "Expected file #{relative.inspect} to not exist, but does" + end + alias :assert_no_directory :assert_no_file + + # Asserts a given migration exists. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_migration "db/migrate/create_products.rb" + # + # This method manipulates the given path and tries to find any migration which + # matches the migration name. For example, the call above is converted to: + # + # assert_file "db/migrate/003_create_products.rb" + # + # Consequently, assert_migration accepts the same arguments has assert_file. + def assert_migration(relative, *contents, &block) + file_name = migration_file_name(relative) + assert file_name, "Expected migration #{relative} to exist, but was not found" + assert_file file_name, *contents, &block + end + + # Asserts a given migration does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_migration "db/migrate/create_products.rb" + def assert_no_migration(relative) + file_name = migration_file_name(relative) + assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" + end + + # Asserts the given class method exists in the given content. This method does not detect + # class methods inside (class << self), only class methods which starts with "self.". + # When a block is given, it yields the content of the method. + # + # assert_migration "db/migrate/create_products.rb" do |migration| + # assert_class_method :up, migration do |up| + # assert_match(/create_table/, up) + # end + # end + def assert_class_method(method, content, &block) + assert_instance_method "self.#{method}", content, &block + end + + # Asserts the given method exists in the given content. When a block is given, + # it yields the content of the method. + # + # assert_file "app/controllers/products_controller.rb" do |controller| + # assert_instance_method :index, controller do |index| + # assert_match(/Product\.all/, index) + # end + # end + def assert_instance_method(method, content) + assert content =~ /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m, "Expected to have method #{method}" + yield $3.strip if block_given? + end + alias :assert_method :assert_instance_method + + # Asserts the given attribute type gets translated to a field type + # properly: + # + # assert_field_type :date, :date_select + def assert_field_type(attribute_type, field_type) + assert_equal(field_type, create_generated_attribute(attribute_type).field_type) + end + + # Asserts the given attribute type gets a proper default value: + # + # assert_field_default_value :string, "MyString" + def assert_field_default_value(attribute_type, value) + assert_equal(value, create_generated_attribute(attribute_type).default) + end + end + end + end +end diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb new file mode 100644 index 0000000000..7576eba6e0 --- /dev/null +++ b/railties/lib/rails/generators/testing/behaviour.rb @@ -0,0 +1,106 @@ +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/concern' +require 'rails/generators' + +module Rails + module Generators + module Testing + module Behaviour + extend ActiveSupport::Concern + + included do + class_attribute :destination_root, :current_path, :generator_class, :default_arguments + + # Generators frequently change the current path using +FileUtils.cd+. + # So we need to store the path at file load and revert back to it after each test. + self.current_path = File.expand_path(Dir.pwd) + self.default_arguments = [] + end + + module ClassMethods + # Sets which generator should be tested: + # + # tests AppGenerator + def tests(klass) + self.generator_class = klass + end + + # Sets default arguments on generator invocation. This can be overwritten when + # invoking it. + # + # arguments %w(app_name --skip-active-record) + def arguments(array) + self.default_arguments = array + end + + # Sets the destination of generator files: + # + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + def destination(path) + self.destination_root = path + end + end + + # Runs the generator configured for this class. The first argument is an array like + # command line arguments: + # + # class AppGeneratorTest < Rails::Generators::TestCase + # tests AppGenerator + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + # teardown :cleanup_destination_root + # + # test "database.yml is not created when skipping Active Record" do + # run_generator %w(myapp --skip-active-record) + # assert_no_file "config/database.yml" + # end + # end + # + # You can provide a configuration hash as second argument. This method returns the output + # printed by the generator. + def run_generator(args=self.default_arguments, config={}) + capture(:stdout) do + args += ['--skip-bundle'] unless args.include? '--dev' + self.generator_class.start(args, config.reverse_merge(destination_root: destination_root)) + end + end + + # Instantiate the generator. + def generator(args=self.default_arguments, options={}, config={}) + @generator ||= self.generator_class.new(args, options, config.reverse_merge(destination_root: destination_root)) + end + + # Create a Rails::Generators::GeneratedAttribute by supplying the + # attribute type and, optionally, the attribute name: + # + # create_generated_attribute(:string, 'name') + def create_generated_attribute(attribute_type, name = 'test', index = nil) + Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':')) + end + + protected + + def destination_root_is_set? # :nodoc: + raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root + end + + def ensure_current_path # :nodoc: + cd current_path + end + + def prepare_destination # :nodoc: + rm_rf(destination_root) + mkdir_p(destination_root) + end + + def migration_file_name(relative) # :nodoc: + absolute = File.expand_path(relative, destination_root) + dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') + Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first + end + end + end + end +end diff --git a/railties/lib/rails/generators/testing/setup_and_teardown.rb b/railties/lib/rails/generators/testing/setup_and_teardown.rb new file mode 100644 index 0000000000..73102a283f --- /dev/null +++ b/railties/lib/rails/generators/testing/setup_and_teardown.rb @@ -0,0 +1,18 @@ +module Rails + module Generators + module Testing + module SetupAndTeardown + def setup # :nodoc: + destination_root_is_set? + ensure_current_path + super + end + + def teardown # :nodoc: + ensure_current_path + super + end + end + end + end +end |