diff options
Diffstat (limited to 'railties/lib/rails')
64 files changed, 496 insertions, 226 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 8075068b3f..77efe3248d 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -156,26 +156,20 @@ module Rails self end - # Implements call according to the Rack API. It simply - # dispatches the request to the underlying middleware stack. - def call(env) - req = ActionDispatch::Request.new env - env["ORIGINAL_FULLPATH"] = req.fullpath - env["ORIGINAL_SCRIPT_NAME"] = req.script_name - super(env) - end - # Reload application routes regardless if they changed or not. def reload_routes! routes_reloader.reload! end - # Return the application's KeyGenerator + # Returns the application's KeyGenerator def key_generator # number of iterations selected based on consultation with the google security # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220 @caching_key_generator ||= if secrets.secret_key_base + unless secrets.secret_key_base.kind_of?(String) + raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String, change this value in `config/secrets.yml`" + end key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000) ActiveSupport::CachingKeyGenerator.new(key_generator) else @@ -224,12 +218,12 @@ module Rails # Rails.application.configure do # config.middleware.use ExceptionNotifier, config_for(:exception_notification) # end - def config_for(name) + def config_for(name, env: Rails.env) yaml = Pathname.new("#{paths["config"].existent.first}/#{name}.yml") if yaml.exist? require "erb" - (YAML.load(ERB.new(yaml.read).result) || {})[Rails.env] || {} + (YAML.load(ERB.new(yaml.read).result) || {})[env] || {} else raise "Could not load configuration. No such file - #{yaml}" end @@ -514,5 +508,18 @@ module Rails end end end + + private + + def build_request(env) + req = super + env["ORIGINAL_FULLPATH"] = req.fullpath + env["ORIGINAL_SCRIPT_NAME"] = req.script_name + req + end + + def build_middleware + config.app_middleware + super + end end end diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index 0f4d932749..9baf8aa742 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -63,7 +63,7 @@ INFO Rails.cache = ActiveSupport::Cache.lookup_store(config.cache_store) if Rails.cache.respond_to?(:middleware) - config.middleware.insert_before("Rack::Runtime", Rails.cache.middleware) + config.middleware.insert_before(::Rack::Runtime, Rails.cache.middleware) end end end diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 4fc7a1db62..80733c2d90 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -3,6 +3,9 @@ require 'active_support/file_update_checker' require 'rails/engine/configuration' require 'rails/source_annotation_extractor' +require 'active_support/deprecation' +require 'active_support/core_ext/string/strip' # for strip_heredoc + module Rails class Application class Configuration < ::Rails::Engine::Configuration @@ -11,12 +14,12 @@ module Rails :eager_load, :exceptions_app, :file_watcher, :filter_parameters, :force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags, :railties_order, :relative_url_root, :secret_key_base, :secret_token, - :serve_static_files, :ssl_options, :static_cache_control, :static_index, + :ssl_options, :public_file_server, :session_options, :time_zone, :reload_classes_only_on_change, :beginning_of_week, :filter_redirect, :x attr_writer :log_level - attr_reader :encoding, :api_only + attr_reader :encoding, :api_only, :static_cache_control def initialize(*) super @@ -26,9 +29,9 @@ module Rails @filter_parameters = [] @filter_redirect = [] @helpers_paths = [] - @serve_static_files = true - @static_cache_control = nil - @static_index = "index" + @public_file_server = ActiveSupport::OrderedOptions.new + @public_file_server.enabled = true + @public_file_server.index_name = "index" @force_ssl = false @ssl_options = {} @session_store = :cookie_store @@ -36,13 +39,12 @@ module Rails @time_zone = "UTC" @beginning_of_week = :monday @log_level = nil - @middleware = app_middleware @generators = app_generators @cache_store = [ :file_store, "#{root}/tmp/cache/" ] @railties_order = [:all] @relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"] @reload_classes_only_on_change = true - @file_watcher = ActiveSupport::FileUpdateChecker + @file_watcher = file_update_checker @exceptions_app = nil @autoflush_log = true @log_formatter = ActiveSupport::Logger::SimpleFormatter.new @@ -53,6 +55,35 @@ module Rails @x = Custom.new end + def static_cache_control=(value) + ActiveSupport::Deprecation.warn <<-eow.strip_heredoc + `static_cache_control` is deprecated and will be removed in Rails 5.1. + Please use + `config.public_file_server.headers = { 'Cache-Control' => '#{value}' }` + instead. + eow + + @static_cache_control = value + end + + def serve_static_files + ActiveSupport::Deprecation.warn <<-eow.strip_heredoc + `serve_static_files` is deprecated and will be removed in Rails 5.1. + Please use `public_file_server.enabled` instead. + eow + + @public_file_server.enabled + end + + def serve_static_files=(value) + ActiveSupport::Deprecation.warn <<-eow.strip_heredoc + `serve_static_files` is deprecated and will be removed in Rails 5.1. + Please use `public_file_server.enabled = #{value}` instead. + eow + + @public_file_server.enabled = value + end + def encoding=(value) @encoding = value silence_warnings do @@ -150,6 +181,14 @@ module Rails end private + def file_update_checker + if defined?(Listen) && Listen::Adapter.select() != Listen::Adapter::Polling + ActiveSupport::FileEventedUpdateChecker + else + ActiveSupport::FileUpdateChecker + end + end + class Custom #:nodoc: def initialize @configurations = Hash.new diff --git a/railties/lib/rails/application/default_middleware_stack.rb b/railties/lib/rails/application/default_middleware_stack.rb index 88eade5c5a..5cb5bfb8b7 100644 --- a/railties/lib/rails/application/default_middleware_stack.rb +++ b/railties/lib/rails/application/default_middleware_stack.rb @@ -17,8 +17,11 @@ module Rails middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header - if config.serve_static_files - middleware.use ::ActionDispatch::Static, paths["public"].first, config.static_cache_control, index: config.static_index + if config.public_file_server.enabled + headers = config.public_file_server.headers || {} + headers['Cache-Control'.freeze] = config.static_cache_control if config.static_cache_control + + middleware.use ::ActionDispatch::Static, paths["public"].first, index: config.public_file_server.index_name, headers: headers end if rack_cache = load_rack_cache @@ -72,7 +75,6 @@ module Rails middleware.use ::ActionDispatch::Flash end - middleware.use ::ActionDispatch::ParamsParser middleware.use ::Rack::Head middleware.use ::Rack::ConditionalGet middleware.use ::Rack::ETag, "no-cache" diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index f8f92792a7..404e3c3e23 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -86,7 +86,7 @@ module Rails # added in the hook are taken into account. initializer :set_clear_dependencies_hook, group: :all do callback = lambda do - ActiveSupport::Dependencies.interlock.attempt_loading do + ActiveSupport::Dependencies.interlock.attempt_unloading do ActiveSupport::DescendantsTracker.clear ActiveSupport::Dependencies.clear end diff --git a/railties/lib/rails/application_controller.rb b/railties/lib/rails/application_controller.rb index 9a29ec21cf..618a09a5b3 100644 --- a/railties/lib/rails/application_controller.rb +++ b/railties/lib/rails/application_controller.rb @@ -6,7 +6,7 @@ class Rails::ApplicationController < ActionController::Base # :nodoc: def require_local! unless local_request? - render text: '<p>For security purposes, this information is only available to local requests.</p>', status: :forbidden + render html: '<p>For security purposes, this information is only available to local requests.</p>'.html_safe, status: :forbidden end end diff --git a/railties/lib/rails/code_statistics.rb b/railties/lib/rails/code_statistics.rb index fd352dc9b7..8e9097e1ef 100644 --- a/railties/lib/rails/code_statistics.rb +++ b/railties/lib/rails/code_statistics.rb @@ -33,7 +33,7 @@ class CodeStatistics #:nodoc: Hash[@pairs.map{|pair| [pair.first, calculate_directory_statistics(pair.last)]}] end - def calculate_directory_statistics(directory, pattern = /.*\.(rb|js|coffee)$/) + def calculate_directory_statistics(directory, pattern = /.*\.(rb|js|coffee|rake)$/) stats = CodeStatisticsCalculator.new Dir.foreach(directory) do |file_name| diff --git a/railties/lib/rails/code_statistics_calculator.rb b/railties/lib/rails/code_statistics_calculator.rb index a142236dbe..fad13e8517 100644 --- a/railties/lib/rails/code_statistics_calculator.rb +++ b/railties/lib/rails/code_statistics_calculator.rb @@ -25,6 +25,7 @@ class CodeStatisticsCalculator #:nodoc: } PATTERNS[:minitest] = PATTERNS[:rb].merge method: /^\s*(def|test)\s+['"_a-z]/ + PATTERNS[:rake] = PATTERNS[:rb] def initialize(lines = 0, code_lines = 0, classes = 0, methods = 0) @lines = lines diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index d1e445ac70..d3ea441f8e 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -34,6 +34,9 @@ module Rails opts.on("-P", "--pid=pid", String, "Specifies the PID file.", "Default: tmp/pids/server.pid") { |v| options[:pid] = v } + opts.on("-C", "--[no-]dev-caching", + "Specifies whether to perform caching in development.", + "true or false") { |v| options[:caching] = v } opts.separator "" @@ -67,6 +70,7 @@ module Rails print_boot_information trap(:INT) { exit } create_tmp_directories + setup_dev_caching log_to_stdout if options[:log_stdout] super @@ -82,16 +86,27 @@ module Rails def default_options super.merge({ - Port: 3000, + Port: ENV.fetch('PORT', 3000).to_i, DoNotReverseLookup: true, environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup, daemonize: false, + caching: false, pid: File.expand_path("tmp/pids/server.pid") }) end private + def setup_dev_caching + return unless options[:environment] == "development" + + if options[:caching] == false + delete_cache_file + elsif options[:caching] + create_cache_file + end + end + def print_boot_information url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}" puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}" @@ -101,6 +116,14 @@ module Rails puts "=> Ctrl-C to shutdown server" unless options[:daemonize] end + def create_cache_file + FileUtils.touch("tmp/caching-dev.txt") + end + + def delete_cache_file + FileUtils.rm("tmp/caching-dev.txt") if File.exist?("tmp/caching-dev.txt") + end + def create_tmp_directories %w(cache pids sockets).each do |dir_to_make| FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make)) diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index d99d27a756..30eafd59f2 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -33,9 +33,9 @@ module Rails # config.middleware.delete ActionDispatch::Flash # class MiddlewareStackProxy - def initialize - @operations = [] - @delete_operations = [] + def initialize(operations = [], delete_operations = []) + @operations = operations + @delete_operations = delete_operations end def insert_before(*args, &block) @@ -71,6 +71,19 @@ module Rails other end + + def +(other) # :nodoc: + MiddlewareStackProxy.new(@operations + other.operations, @delete_operations + other.delete_operations) + end + + protected + def operations + @operations + end + + def delete_operations + @delete_operations + end end class Generators #:nodoc: diff --git a/railties/lib/rails/console/helpers.rb b/railties/lib/rails/console/helpers.rb index b775f1ff8d..a33f71dc5b 100644 --- a/railties/lib/rails/console/helpers.rb +++ b/railties/lib/rails/console/helpers.rb @@ -4,7 +4,7 @@ module Rails # # This method assumes an +ApplicationController+ exists, and it extends +ActionController::Base+ def helper - @helper ||= ApplicationController.helpers + ApplicationController.helpers end # Gets a new instance of a controller object. diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 64c15f8f89..5757d235d2 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -2,6 +2,7 @@ require 'rails/railtie' require 'rails/engine/railties' require 'active_support/core_ext/module/delegation' require 'pathname' +require 'thread' module Rails # <tt>Rails::Engine</tt> allows you to wrap a specific Rails application or subset of @@ -429,6 +430,7 @@ module Rails @env_config = nil @helpers = nil @routes = nil + @app_build_lock = Mutex.new super end @@ -499,10 +501,13 @@ module Rails # Returns the underlying rack application for this engine. def app - @app ||= begin - config.middleware = config.middleware.merge_into(default_middleware_stack) - config.middleware.build(endpoint) - end + @app || @app_build_lock.synchronize { + @app ||= begin + stack = default_middleware_stack + config.middleware = build_middleware.merge_into(stack) + config.middleware.build(endpoint) + end + } end # Returns the endpoint for this engine. If none is registered, @@ -513,18 +518,13 @@ module Rails # Define the Rack API for this engine. def call(env) - env.merge!(env_config) - if env['SCRIPT_NAME'] - env[routes.env_key] = env['SCRIPT_NAME'].dup - end - app.call(env) + req = build_request env + app.call req.env end # Defines additional Rack env configuration that is added on each call. def env_config - @env_config ||= { - 'action_dispatch.routes' => routes - } + @env_config ||= {} end # Defines the routes for this engine. If a block is given to @@ -584,7 +584,7 @@ module Rails # I18n load paths are a special case since the ones added # later have higher priority. initializer :add_locales do - config.i18n.railties_load_path.concat(paths["config/locales"].existent) + config.i18n.railties_load_path << paths["config/locales"] end initializer :add_view_paths do @@ -686,5 +686,19 @@ module Rails def _all_load_paths #:nodoc: @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq end + + private + + def build_request(env) + env.merge!(env_config) + req = ActionDispatch::Request.new env + req.routes = routes + req.engine_script_name = req.script_name + req + end + + def build_middleware + config.middleware + end end end diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 62a4139d07..8cadbc3ddd 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -4,17 +4,14 @@ module Rails class Engine class Configuration < ::Rails::Railtie::Configuration attr_reader :root - attr_writer :middleware, :eager_load_paths, :autoload_once_paths, :autoload_paths + attr_accessor :middleware + attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths def initialize(root=nil) super() @root = root @generators = app_generators.dup - end - - # Returns the middleware stack for the engine. - def middleware - @middleware ||= Rails::Configuration::MiddlewareStackProxy.new + @middleware = Rails::Configuration::MiddlewareStackProxy.new end # Holds generators configuration: @@ -29,7 +26,7 @@ module Rails # # config.generators.colorize_logging = false # - def generators #:nodoc: + def generators @generators ||= Rails::Configuration::Generators.new yield(@generators) if block_given? @generators diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index b430cf1909..2645102619 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -178,7 +178,7 @@ module Rails options = sorted_groups.flat_map(&:last) suggestions = options.sort_by {|suggested| levenshtein_distance(namespace.to_s, suggested) }.first(3) msg = "Could not find generator '#{namespace}'. " - msg << "Maybe you meant #{ suggestions.map {|s| "'#{s}'"}.to_sentence(last_word_connector: " or ") }\n" + msg << "Maybe you meant #{ suggestions.map {|s| "'#{s}'"}.to_sentence(last_word_connector: " or ", locale: :en) }\n" msg << "Run `rails generate --help` for more options." puts msg end diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 560a553789..5bbd2f1aed 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -92,11 +92,11 @@ module Rails # file in <tt>config/environments</tt>. # # environment do - # "config.autoload_paths += %W(#{config.root}/extras)" + # "config.action_controller.asset_host = 'cdn.provider.com'" # end # # environment(nil, env: "development") do - # "config.autoload_paths += %W(#{config.root}/extras)" + # "config.action_controller.asset_host = 'localhost:3000'" # end def environment(data=nil, options={}) sentinel = /class [a-z_:]+ < Rails::Application/i @@ -235,7 +235,7 @@ module Rails sentinel = /\.routes\.draw do\s*\n/m in_root do - inject_into_file 'config/routes.rb', " #{routing_code}\n", { after: sentinel, verbose: false, force: true } + inject_into_file 'config/routes.rb', " #{routing_code}\n", { after: sentinel, verbose: false, force: false } end end diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 249fe96772..56c9d3e354 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -162,7 +162,8 @@ module Rails def database_gemfile_entry return [] if options[:skip_active_record] - GemfileEntry.version gem_for_database, nil, + gem_name, gem_version = gem_for_database + GemfileEntry.version gem_name, gem_version, "Use #{options[:database]} as the database for Active Record" end @@ -202,21 +203,34 @@ module Rails def self.path(name, path, comment = nil) new(name, nil, comment, path: path) end + + def version + version = super + + if version.is_a?(Array) + version.join("', '") + else + version + end + end end def rails_gemfile_entry - if options.dev? - [ - GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH), + dev_edge_common = [ GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails'), - GemfileEntry.github('arel', 'rails/arel') + GemfileEntry.github('sprockets', 'rails/sprockets'), + GemfileEntry.github('sass-rails', 'rails/sass-rails'), + GemfileEntry.github('arel', 'rails/arel'), + GemfileEntry.github('rack', 'rack/rack') ] + if options.dev? + [ + GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH) + ] + dev_edge_common elsif options.edge? [ - GemfileEntry.github('rails', 'rails/rails'), - GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails'), - GemfileEntry.github('arel', 'rails/arel') - ] + GemfileEntry.github('rails', 'rails/rails') + ] + dev_edge_common else [GemfileEntry.version('rails', Rails::VERSION::STRING, @@ -227,16 +241,16 @@ module Rails def gem_for_database # %w( mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql ) case options[:database] - when "oracle" then "ruby-oci8" - when "postgresql" then "pg" - when "frontbase" then "ruby-frontbase" - when "mysql" then "mysql2" - when "sqlserver" then "activerecord-sqlserver-adapter" - when "jdbcmysql" then "activerecord-jdbcmysql-adapter" - when "jdbcsqlite3" then "activerecord-jdbcsqlite3-adapter" - when "jdbcpostgresql" then "activerecord-jdbcpostgresql-adapter" - when "jdbc" then "activerecord-jdbc-adapter" - else options[:database] + when "oracle" then ["ruby-oci8", nil] + when "postgresql" then ["pg", ["~> 0.18"]] + when "frontbase" then ["ruby-frontbase", nil] + when "mysql" then ["mysql2", [">= 0.3.18", "< 0.5"]] + when "sqlserver" then ["activerecord-sqlserver-adapter", nil] + when "jdbcmysql" then ["activerecord-jdbcmysql-adapter", nil] + when "jdbcsqlite3" then ["activerecord-jdbcsqlite3-adapter", nil] + when "jdbcpostgresql" then ["activerecord-jdbcpostgresql-adapter", nil] + when "jdbc" then ["activerecord-jdbc-adapter", nil] + else [options[:database], nil] end end @@ -255,8 +269,6 @@ module Rails return [] if options[:skip_sprockets] gems = [] - gems << GemfileEntry.version('sass-rails', '~> 5.0', - 'Use SCSS for stylesheets') gems << GemfileEntry.version('uglifier', '>= 1.3.0', diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index 6fa413f8b0..c72ec400a0 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -302,13 +302,13 @@ module Rails default_for_option(Rails::Generators.options, name, options, options[:default]) end - # Return default aliases for the option name given doing a lookup in + # Returns default aliases for the option name given doing a lookup in # Rails::Generators.aliases. def self.default_aliases_for_option(name, options) default_for_option(Rails::Generators.aliases, name, options, options[:aliases]) end - # Return default for the option name given doing a lookup in config. + # Returns default for the option name given doing a lookup in config. def self.default_for_option(config, name, options, default) if generator_name and c = config[generator_name.to_sym] and c.key?(name) c[name] diff --git a/railties/lib/rails/generators/migration.rb b/railties/lib/rails/generators/migration.rb index 51e6d68bf0..87f2e1d42b 100644 --- a/railties/lib/rails/generators/migration.rb +++ b/railties/lib/rails/generators/migration.rb @@ -10,22 +10,22 @@ module Rails extend ActiveSupport::Concern attr_reader :migration_number, :migration_file_name, :migration_class_name - module ClassMethods - def migration_lookup_at(dirname) #:nodoc: + module ClassMethods #:nodoc: + def migration_lookup_at(dirname) Dir.glob("#{dirname}/[0-9]*_*.rb") end - def migration_exists?(dirname, file_name) #:nodoc: + def migration_exists?(dirname, file_name) migration_lookup_at(dirname).grep(/\d+_#{file_name}.rb$/).first end - def current_migration_number(dirname) #:nodoc: + def current_migration_number(dirname) migration_lookup_at(dirname).collect do |file| File.basename(file).split("_").first.to_i end.max.to_i end - def next_migration_number(dirname) #:nodoc: + def next_migration_number(dirname) raise NotImplementedError end end diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 6a1c2faaab..4f3f59cc22 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -48,10 +48,12 @@ group :development do # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' <% end -%> + + # Loading the listen gem enables an evented file system monitor. Check + # https://github.com/guard/listen#listen-adapters if on Windows or *BSD. + # gem 'listen', '~> 3.0.4' end <% end -%> -<% if RUBY_PLATFORM.match(/bccwin|cygwin|emx|mingw|mswin|wince|java/) -%> # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] -<% end -%> diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt new file mode 100644 index 0000000000..f80631bac6 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt @@ -0,0 +1,8 @@ + +<% unless options.api? -%> +//= link_tree ../images +<% end -%> +<% unless options.skip_javascript -%> +//= link_directory ../javascripts .js +<% end -%> +//= link_directory ../stylesheets .css 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 cb86978d4c..c88426ec06 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 @@ -5,7 +5,7 @@ // or any plugin's vendor/assets/javascripts directory 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. +// compiled file. JavaScript code in this file should be added after the last require_* statement. // // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // about supported directives. 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 0cdd2788d0..0ebd7fe829 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 @@ -7,7 +7,8 @@ * * 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 other CSS/SCSS - * files in this directory. It is generally better to create a new file per style scope. + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. * *= 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 75ea52828e..8bb4440f55 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 @@ -1,23 +1,24 @@ <!DOCTYPE html> <html> -<head> - <title><%= camelized %></title> - <%- if options[:skip_javascript] -%> - <%%= stylesheet_link_tag 'application', media: 'all' %> - <%- else -%> - <%- if gemfile_entries.any? { |m| m.name == 'turbolinks' } -%> - <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> - <%%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> + <head> + <title><%= camelized %></title> + <%- if options[:skip_javascript] -%> + <%%= stylesheet_link_tag 'application', media: 'all' %> <%- else -%> - <%%= stylesheet_link_tag 'application', media: 'all' %> - <%%= javascript_include_tag 'application' %> + <%- if gemfile_entries.any? { |m| m.name == 'turbolinks' } -%> + <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> + <%%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> + <%- else -%> + <%%= stylesheet_link_tag 'application', media: 'all' %> + <%%= javascript_include_tag 'application' %> + <%- end -%> <%- end -%> - <%- end -%> - <%%= csrf_meta_tags %> -</head> -<body> + <%%= csrf_meta_tags %> + </head> -<%%= yield %> + <body> -</body> + <%%= yield %> + + </body> </html> diff --git a/railties/lib/rails/generators/rails/app/templates/bin/setup b/railties/lib/rails/generators/rails/app/templates/bin/setup index a57b16444c..0c8b179827 100644 --- a/railties/lib/rails/generators/rails/app/templates/bin/setup +++ b/railties/lib/rails/generators/rails/app/templates/bin/setup @@ -15,7 +15,7 @@ chdir APP_ROOT do puts '== Installing dependencies ==' system! 'gem install bundler --conservative' - system!('bundle check') or system!('bundle install') + system('bundle check') or system!('bundle install') # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') diff --git a/railties/lib/rails/generators/rails/app/templates/bin/update b/railties/lib/rails/generators/rails/app/templates/bin/update new file mode 100644 index 0000000000..9830e6b29a --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/bin/update @@ -0,0 +1,28 @@ +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system 'bundle check' or system! 'bundle install' + + puts "\n== Updating database ==" + system! 'bin/rake db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rake log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rake restart' +end 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 6b7d7abd0b..ddd0fcade1 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -26,7 +26,7 @@ module <%= app_const_base %> # -- all .rb files in that directory are automatically loaded. # 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. + # Run "rake time:zones:all" for a time zone names list. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml index f5b62e8fb3..5ca549a8c8 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml @@ -7,7 +7,7 @@ # gem 'activerecord-jdbcmysql-adapter' # # And be sure to use new-style password hashing: -# http://dev.mysql.com/doc/refman/5.6/en/old-client.html +# http://dev.mysql.com/doc/refman/5.7/en/old-client.html # default: &default adapter: mysql diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml index b0767bd93a..119c2fe2c3 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml @@ -7,7 +7,7 @@ # gem 'mysql2' # # And be sure to use new-style password hashing: -# http://dev.mysql.com/doc/refman/5.6/en/old-client.html +# http://dev.mysql.com/doc/refman/5.7/en/old-client.html # default: &default adapter: mysql2 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 ecb5d4170f..4dd20a9d2e 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 @@ -9,9 +9,21 @@ Rails.application.configure do # Do not eager load code on boot. config.eager_load = false - # Show full error reports and disable caching. + # Show full error reports. config.consider_all_requests_local = true - config.action_controller.perform_caching = false + + # Enable/disable caching. By default caching is disabled. + if Rails.root.join('tmp/caching-dev.txt').exist? + config.action_controller.perform_caching = true + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => 'public, max-age=172800' + } + else + config.action_controller.perform_caching = false + config.cache_store = :null_store + end + <%- unless options.skip_action_mailer? -%> # Don't care if the mailer can't send. 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 8c09396fc1..a5302550fa 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 @@ -16,7 +16,7 @@ Rails.application.configure do # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. - config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? <%- unless options.skip_sprockets? -%> # Compress JavaScripts and CSS. @@ -51,7 +51,8 @@ Rails.application.configure do # config.log_tags = [ :subdomain, :request_id ] # Use a different logger for distributed setups. - # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') # Use a different cache store in production. # config.cache_store = :mem_cache_store 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 0306deb18c..8133917591 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 @@ -12,9 +12,11 @@ Rails.application.configure do # preloads Rails for running tests, you may have to set it to true. config.eager_load = false - # Configure static file server for tests with Cache-Control for performance. - config.serve_static_files = true - config.static_cache_control = 'public, max-age=3600' + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => 'public, max-age=3600' + } # Show full error reports and disable caching. config.consider_all_requests_local = true diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb index 45c44d24f8..3b1c1b5ed1 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb @@ -1,9 +1,11 @@ -# Avoid CORS issues when API is called from the frontend app -# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests +# Be sure to restart your server when you modify this file. + +# Avoid CORS issues when API is called from the frontend app. +# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests. # Read more: https://github.com/cyu/rack-cors -# Rails.application.config.middleware.insert_before 0, "Rack::Cors" do +# Rails.application.config.middleware.insert_before 0, Rack::Cors do # allow do # origins 'example.com' # 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 3f66539d54..787824f888 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb @@ -1,56 +1,3 @@ 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" - # root 'welcome#index' - - # Example of regular route: - # get 'products/:id' => 'catalog#view' - - # Example of named route that can be invoked with purchase_url(id: product.id) - # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase - - # Example resource route (maps HTTP verbs to controller actions automatically): - # resources :products - - # Example resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end - - # Example resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Example resource route with more complex sub-resources: - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', on: :collection - # 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 - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index 66111004aa..eeeef430bb 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -17,15 +17,22 @@ module Rails def app if mountable? - directory 'app' - empty_directory_with_keep_file "app/assets/images/#{namespaced_name}" + if api? + directory 'app', exclude_pattern: %r{app/(views|helpers)} + else + directory 'app' + empty_directory_with_keep_file "app/assets/images/#{namespaced_name}" + end elsif full? empty_directory_with_keep_file 'app/models' empty_directory_with_keep_file 'app/controllers' - empty_directory_with_keep_file 'app/views' - empty_directory_with_keep_file 'app/helpers' empty_directory_with_keep_file 'app/mailers' - empty_directory_with_keep_file "app/assets/images/#{namespaced_name}" + + unless api? + empty_directory_with_keep_file "app/assets/images/#{namespaced_name}" + empty_directory_with_keep_file 'app/helpers' + empty_directory_with_keep_file 'app/views' + end end end @@ -82,6 +89,7 @@ task default: :test opts = (options || {}).slice(*PASSTHROUGH_OPTIONS) opts[:force] = force opts[:skip_bundle] = true + opts[:api] = options.api? invoke Rails::Generators::AppGenerator, [ File.expand_path(dummy_path, destination_root) ], opts @@ -96,8 +104,9 @@ task default: :test 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 + 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 + template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true end def test_dummy_clean @@ -108,12 +117,16 @@ task default: :test remove_file "Gemfile" remove_file "lib/tasks" remove_file "public/robots.txt" - remove_file "README" + remove_file "README.md" remove_file "test" remove_file "vendor" end end + def assets_manifest + template "rails/engine_manifest.js", "app/assets/config/#{underscored_name}_manifest.js" + end + def stylesheets if mountable? copy_file "rails/stylesheets.css", @@ -176,6 +189,9 @@ task default: :test desc: "If creating plugin in application's directory " + "skip adding entry to Gemfile" + class_option :api, type: :boolean, default: false, + desc: "Generate a smaller stack for API application plugins" + def initialize(*args) @dummy_path = nil super @@ -209,16 +225,16 @@ task default: :test build(:lib) end - def create_public_stylesheets_files - build(:stylesheets) + def create_assets_manifest_file + build(:assets_manifest) if !api? && engine? end - def create_javascript_files - build(:javascripts) + def create_public_stylesheets_files + build(:stylesheets) unless api? end - def create_images_directory - build(:images) + def create_javascript_files + build(:javascripts) unless api? end def create_bin_files @@ -305,6 +321,10 @@ task default: :test options[:skip_test].blank? || options[:dummy_path] != 'test/dummy' end + def api? + options[:api] + end + def self.banner "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]" end diff --git a/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec index f8ece4fe73..ff242adbab 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec +++ b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec @@ -22,6 +22,6 @@ Gem::Specification.new do |s| <%= '# ' if options.dev? || options.edge? -%>s.add_dependency "rails", "~> <%= Rails::VERSION::STRING %>" <% unless options[:skip_active_record] -%> - s.add_development_dependency "<%= gem_for_database %>" + s.add_development_dependency "<%= gem_for_database[0] %>" <% end -%> end diff --git a/railties/lib/rails/generators/rails/plugin/templates/Gemfile b/railties/lib/rails/generators/rails/plugin/templates/Gemfile index 2c91c6a0ea..f085a2577a 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/Gemfile +++ b/railties/lib/rails/generators/rails/plugin/templates/Gemfile @@ -11,7 +11,7 @@ gemspec <% if options[:skip_gemspec] -%> group :development do - gem '<%= gem_for_database %>' + gem '<%= gem_for_database[0] %>' end <% else -%> # Declare any dependencies that are still in development here instead of in diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt index 7157e48c42..7fe4e5034d 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt @@ -1,5 +1,5 @@ <%= wrap_in_modules <<-rb.strip_heredoc - class ApplicationController < ActionController::Base + class ApplicationController < ActionController::#{api? ? "API" : "Base"} end rb %> diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt new file mode 100644 index 0000000000..bad1ff2d16 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt @@ -0,0 +1,5 @@ +<%= wrap_in_modules <<-rb.strip_heredoc + class ApplicationJob < ActiveJob::Base + end +rb +%> diff --git a/railties/lib/rails/generators/rails/plugin/templates/gitignore b/railties/lib/rails/generators/rails/plugin/templates/gitignore index d524fcbc4e..54c78d7927 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/gitignore +++ b/railties/lib/rails/generators/rails/plugin/templates/gitignore @@ -6,5 +6,4 @@ pkg/ <%= dummy_path %>/db/*.sqlite3-journal <%= dummy_path %>/log/*.log <%= dummy_path %>/tmp/ -<%= dummy_path %>/.sass-cache <% end -%> diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb index 17afd52177..8938770fc4 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb @@ -1,6 +1,7 @@ <%= wrap_in_modules <<-rb.strip_heredoc class Engine < ::Rails::Engine #{mountable? ? ' isolate_namespace ' + camelized_modules : ' '} + #{api? ? " config.generators.api_only = true" : ' '} end rb %> diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb index d257295988..b08f4ef9ae 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb @@ -1 +1 @@ -<%= wrap_in_modules 'VERSION = "0.0.1"' %> +<%= wrap_in_modules "VERSION = '0.1.0'" %> diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js b/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js new file mode 100644 index 0000000000..8d21b2b6fb --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js @@ -0,0 +1,11 @@ + +<% unless api? -%> +//= link_tree ../images +<% end -%> +<% unless options.skip_javascript -%> +//= link_directory ../javascripts .js +<% end -%> +//= link_directory ../stylesheets .css +<% if mountable? && !api? -%> +//= link <%= underscored_name %>_manifest.js +<% end -%> diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js b/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js new file mode 100644 index 0000000000..2f23844f5e --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js @@ -0,0 +1,6 @@ +<% if mountable? -%> +<% if !options.skip_javascript -%> +//= link_directory ../javascripts/<%= namespaced_name %> .js +<% end -%> +//= link_directory ../stylesheets/<%= namespaced_name %> .css +<% end -%> diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js index 8913b40f69..e54c6461cc 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js @@ -5,7 +5,7 @@ // or any plugin's vendor/assets/javascripts directory 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. +// compiled file. JavaScript code in this file should be added after the last require_* statement. // // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // about supported directives. diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css index 0cdd2788d0..0ebd7fe829 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css @@ -7,7 +7,8 @@ * * 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 other CSS/SCSS - * files in this directory. It is generally better to create a new file per style scope. + * files in this directory. Styles in this file should be added after the last require_* statement. + * 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/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb index 95adcc06ff..f315144723 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb @@ -14,12 +14,10 @@ require "rails/test_help" # to be shown. Minitest.backtrace_filter = Minitest::BacktraceFilter.new -# Load support files -Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } - # Load fixtures from the engine if ActiveSupport::TestCase.respond_to?(:fixture_path=) ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__) + ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files" ActiveSupport::TestCase.fixtures :all end diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb index bc3c9b3f6b..17a86f376b 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb @@ -1,5 +1,5 @@ <% if namespaced? -%> -require_dependency "<%= namespaced_file_path %>/application_controller" +require_dependency "<%= namespaced_path %>/application_controller" <% end -%> <% module_namespacing do -%> 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 2c3b04043f..f73e9a96ba 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb @@ -1,5 +1,5 @@ <% if namespaced? -%> -require_dependency "<%= namespaced_file_path %>/application_controller" +require_dependency "<%= namespaced_path %>/application_controller" <% end -%> <% module_namespacing do -%> diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb index 896b38bc8f..f302cd6c3d 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb @@ -3,7 +3,10 @@ require 'test_helper' <% module_namespacing do -%> class <%= controller_class_name %>ControllerTest < ActionController::TestCase setup do - @<%= singular_table_name %> = <%= table_name %>(:one) + @<%= singular_table_name %> = <%= fixture_name %>(:one) +<% if mountable_engine? -%> + @routes = Engine.routes +<% end -%> end test "should get index" do diff --git a/railties/lib/rails/generators/testing/assertions.rb b/railties/lib/rails/generators/testing/assertions.rb index 17af6eddfa..76758df86d 100644 --- a/railties/lib/rails/generators/testing/assertions.rb +++ b/railties/lib/rails/generators/testing/assertions.rb @@ -1,5 +1,3 @@ -require 'shellwords' - module Rails module Generators module Testing diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb index c9700e1cd7..94b5e52224 100644 --- a/railties/lib/rails/generators/testing/behaviour.rb +++ b/railties/lib/rails/generators/testing/behaviour.rb @@ -92,7 +92,8 @@ module Rails cd current_path end - def prepare_destination # :nodoc: + # Clears all files and directories in destination. + def prepare_destination rm_rf(destination_root) mkdir_p(destination_root) end diff --git a/railties/lib/rails/mailers_controller.rb b/railties/lib/rails/mailers_controller.rb index 41422a656c..6143cf2dd9 100644 --- a/railties/lib/rails/mailers_controller.rb +++ b/railties/lib/rails/mailers_controller.rb @@ -3,7 +3,7 @@ require 'rails/application_controller' class Rails::MailersController < Rails::ApplicationController # :nodoc: prepend_view_path ActionDispatch::DebugExceptions::RESCUES_TEMPLATE_PATH - before_action :require_local! + before_action :require_local!, unless: :show_previews? before_action :find_preview, only: :preview def index @@ -26,12 +26,12 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc: if part = find_part(part_type) response.content_type = part_type - render text: part.respond_to?(:decoded) ? part.decoded : part + render plain: part.respond_to?(:decoded) ? part.decoded : part else raise AbstractController::ActionNotFound, "Email part '#{part_type}' not found in #{@preview.name}##{@email_action}" end else - @part = find_preferred_part(request.format, Mime::HTML, Mime::TEXT) + @part = find_preferred_part(request.format, Mime[:html], Mime[:text]) render action: 'email', layout: false, formats: %w[html] end else @@ -41,6 +41,10 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc: end protected + def show_previews? + ActionMailer::Base.show_previews + end + def find_preview candidates = [] params[:path].to_s.scan(%r{/|$}){ candidates << $` } diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb index ebcaaaba46..e47616a87f 100644 --- a/railties/lib/rails/paths.rb +++ b/railties/lib/rails/paths.rb @@ -123,6 +123,10 @@ module Rails options[:load_path] ? load_path! : skip_load_path! end + def absolute_current # :nodoc: + File.expand_path(@current, @root.path) + end + def children keys = @root.keys.find_all { |k| k.start_with?(@current) && k != @current @@ -175,6 +179,10 @@ module Rails @paths end + def extensions # :nodoc: + $1.split(',') if @glob =~ /\{([\S]+)\}/ + end + # Expands all paths against the root and return all unique values. def expanded raise "You need to set a path root" unless @root.path diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index 9b058a1848..8dd87b6cc5 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -3,7 +3,7 @@ # rake notes # rake notes:optimize # -# and friends. See <tt>rake -T notes</tt> and <tt>railties/lib/tasks/annotations.rake</tt>. +# and friends. See <tt>rake -T notes</tt> and <tt>railties/lib/rails/tasks/annotations.rake</tt>. # # Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that # represent the line where the annotation lives, its tag, and its text. Note diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb index 2c3d278eca..d3e33584d7 100644 --- a/railties/lib/rails/tasks.rb +++ b/railties/lib/rails/tasks.rb @@ -3,6 +3,7 @@ require 'rake' # Load Rails Rakefile extensions %w( annotations + dev framework initializers log @@ -10,8 +11,9 @@ require 'rake' misc restart routes - statistics tmp -).each do |task| +).tap { |arr| + arr << 'statistics' if Rake.application.current_scope.empty? +}.each do |task| load "rails/tasks/#{task}.rake" end diff --git a/railties/lib/rails/tasks/dev.rake b/railties/lib/rails/tasks/dev.rake new file mode 100644 index 0000000000..e949172d3f --- /dev/null +++ b/railties/lib/rails/tasks/dev.rake @@ -0,0 +1,15 @@ +namespace :dev do + task :cache do + desc 'Toggle development mode caching on/off' + + if File.exist? 'tmp/caching-dev.txt' + File.delete 'tmp/caching-dev.txt' + puts 'Development mode is no longer being cached.' + else + FileUtils.touch 'tmp/caching-dev.txt' + puts 'Development mode is now being cached.' + end + + FileUtils.touch 'tmp/restart.txt' + end +end diff --git a/railties/lib/rails/tasks/engine.rake b/railties/lib/rails/tasks/engine.rake index 16ad1bfc84..c51524f8f6 100644 --- a/railties/lib/rails/tasks/engine.rake +++ b/railties/lib/rails/tasks/engine.rake @@ -40,7 +40,7 @@ namespace :db do desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)." app_task "rollback" - desc "Create a db/schema.rb file that can be portably used against any DB supported by AR" + desc "Create a db/schema.rb file that can be portably used against any DB supported by Active Record" app_task "schema:dump" desc "Load a schema.rb file into the database" diff --git a/railties/lib/rails/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake index 735c36eb3a..a919d36939 100644 --- a/railties/lib/rails/tasks/statistics.rake +++ b/railties/lib/rails/tasks/statistics.rake @@ -9,6 +9,7 @@ STATS_DIRECTORIES = [ %w(Mailers app/mailers), %w(Javascripts app/assets/javascripts), %w(Libraries lib/), + %w(Tasks lib/tasks), %w(APIs app/apis), %w(Controller\ tests test/controllers), %w(Helper\ tests test/helpers), diff --git a/railties/lib/rails/templates/rails/mailers/email.html.erb b/railties/lib/rails/templates/rails/mailers/email.html.erb index bb6e49966d..fed96fbc85 100644 --- a/railties/lib/rails/templates/rails/mailers/email.html.erb +++ b/railties/lib/rails/templates/rails/mailers/email.html.erb @@ -94,9 +94,9 @@ <% if @email.multipart? %> <dd> - <select onchange="document.getElementsByName('messageBody')[0].src=this.options[this.selectedIndex].value;"> - <option <%= request.format == Mime::HTML ? 'selected' : '' %> value="?part=text%2Fhtml">View as HTML email</option> - <option <%= request.format == Mime::TEXT ? 'selected' : '' %> value="?part=text%2Fplain">View as plain-text email</option> + <select onchange="formatChanged(this);"> + <option <%= request.format == Mime[:html] ? 'selected' : '' %> value="?part=text%2Fhtml">View as HTML email</option> + <option <%= request.format == Mime[:text] ? 'selected' : '' %> value="?part=text%2Fplain">View as plain-text email</option> </select> </dd> <% end %> @@ -112,5 +112,19 @@ </p> <% end %> +<script> + function formatChanged(form) { + var part_name = form.options[form.selectedIndex].value + var iframe =document.getElementsByName('messageBody')[0]; + iframe.contentWindow.location.replace(part_name); + + if (history.replaceState) { + var url = location.pathname.replace(/\.(txt|html)$/, ''); + var format = /html/.test(part_name) ? '.html' : '.txt'; + window.history.replaceState({}, '', url + format); + } + } +</script> + </body> </html> diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb index 828039dc43..5cc1b5b219 100644 --- a/railties/lib/rails/test_help.rb +++ b/railties/lib/rails/test_help.rb @@ -28,14 +28,14 @@ if defined?(ActiveRecord::Base) end class ActionController::TestCase - def before_setup + def before_setup # :nodoc: @routes = Rails.application.routes super end end class ActionDispatch::IntegrationTest - def before_setup + def before_setup # :nodoc: @routes = Rails.application.routes super end diff --git a/railties/lib/rails/test_unit/minitest_plugin.rb b/railties/lib/rails/test_unit/minitest_plugin.rb index ab71298509..d1ba35a5ec 100644 --- a/railties/lib/rails/test_unit/minitest_plugin.rb +++ b/railties/lib/rails/test_unit/minitest_plugin.rb @@ -3,6 +3,16 @@ require "rails/test_unit/reporter" require "rails/test_unit/test_requirer" module Minitest + mattr_accessor(:hide_aggregated_results) { false } + + module AggregatedResultSuppresion + def aggregated_results + super unless Minitest.hide_aggregated_results + end + end + + SummaryReporter.prepend AggregatedResultSuppresion + def self.plugin_rails_options(opts, options) opts.separator "" opts.separator "Usage: bin/rails test [options] [files or directories]" @@ -14,9 +24,11 @@ module Minitest opts.separator "" opts.separator " bin/rails test test/controllers test/integration/login_test.rb" opts.separator "" + opts.separator "By default test failures and errors are reported inline during a run." + opts.separator "" opts.separator "Rails options:" - opts.on("-e", "--environment [ENV]", + opts.on("-e", "--environment ENV", "Run tests in the ENV environment") do |env| options[:environment] = env.strip end @@ -26,21 +38,45 @@ module Minitest options[:full_backtrace] = true end + opts.on("-d", "--defer-output", + "Output test failures and errors after the test run") do + options[:output_inline] = false + end + + opts.on("-f", "--fail-fast", + "Abort test run on first failure") do + options[:fail_fast] = true + end + + options[:output_inline] = true options[:patterns] = opts.order! end + # Running several Rake tasks in a single command would trip up the runner, + # as the patterns would also contain the other Rake tasks. + def self.rake_run(patterns) # :nodoc: + @rake_patterns = patterns + run + end + def self.plugin_rails_init(options) self.run_with_rails_extension = true ENV["RAILS_ENV"] = options[:environment] || "test" - ::Rails::TestRequirer.require_files options[:patterns] unless run_with_autorun + unless run_with_autorun + patterns = defined?(@rake_patterns) ? @rake_patterns : options[:patterns] + ::Rails::TestRequirer.require_files(patterns) + end unless options[:full_backtrace] || ENV["BACKTRACE"] # Plugin can run without Rails loaded, check before filtering. Minitest.backtrace_filter = ::Rails.backtrace_cleaner if ::Rails.respond_to?(:backtrace_cleaner) end + # Disable the extra failure output after a run, unless output is deferred. + self.hide_aggregated_results = options[:output_inline] + self.reporter << ::Rails::TestUnitReporter.new(options[:io], options) end @@ -48,4 +84,5 @@ module Minitest mattr_accessor(:run_with_rails_extension) { false } end +Minitest.load_plugins Minitest.extensions << 'rails' diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb index 09b8675cf8..de4b002e55 100644 --- a/railties/lib/rails/test_unit/reporter.rb +++ b/railties/lib/rails/test_unit/reporter.rb @@ -6,8 +6,25 @@ module Rails class_attribute :executable self.executable = "bin/rails test" + def record(result) + super + + if output_inline? && result.failure && (!result.skipped? || options[:verbose]) + io.puts + io.puts + io.puts result.failures.map(&:message) + io.puts + io.puts format_rerun_snippet(result) + io.puts + end + + if fail_fast? && result.failure && !result.error? && !result.skipped? + raise Interrupt + end + end + def report - return if filtered_results.empty? + return if output_inline? || filtered_results.empty? io.puts io.puts "Failed tests:" io.puts @@ -15,10 +32,7 @@ module Rails end def aggregated_results # :nodoc: - filtered_results.map do |result| - location, line = result.method(result.name).source_location - "#{self.executable} #{relative_path_for(location)}:#{line}" - end.join "\n" + filtered_results.map { |result| format_rerun_snippet(result) }.join "\n" end def filtered_results @@ -32,5 +46,25 @@ module Rails def relative_path_for(file) file.sub(/^#{Rails.root}\/?/, '') end + + private + def output_inline? + options[:output_inline] + end + + def fail_fast? + options[:fail_fast] + end + + def format_rerun_snippet(result) + # Try to extract path to assertion from backtrace. + if result.location =~ /\[(.*)\]\z/ + assertion_path = $1 + else + assertion_path = result.method(result.name).source_location.join(':') + end + + "#{self.executable} #{relative_path_for(assertion_path)}" + end end end diff --git a/railties/lib/rails/test_unit/test_requirer.rb b/railties/lib/rails/test_unit/test_requirer.rb index 84c2256729..83d2c55ffd 100644 --- a/railties/lib/rails/test_unit/test_requirer.rb +++ b/railties/lib/rails/test_unit/test_requirer.rb @@ -18,7 +18,7 @@ module Rails arg = arg.gsub(/:(\d+)?$/, '') if Dir.exist?(arg) "#{arg}/**/*_test.rb" - elsif File.file?(arg) + else arg end end diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake index dda492f974..6676c6a079 100644 --- a/railties/lib/rails/test_unit/testing.rake +++ b/railties/lib/rails/test_unit/testing.rake @@ -7,7 +7,7 @@ task default: :test desc "Runs all tests in test folder" task :test do $: << "test" - Minitest.run(['test']) + Minitest.rake_run(["test"]) end namespace :test do @@ -24,22 +24,22 @@ namespace :test do ["models", "helpers", "controllers", "mailers", "integration", "jobs"].each do |name| task name => "test:prepare" do $: << "test" - Minitest.run(["test/#{name}"]) + Minitest.rake_run(["test/#{name}"]) end end task :generators => "test:prepare" do $: << "test" - Minitest.run(["test/lib/generators"]) + Minitest.rake_run(["test/lib/generators"]) end task :units => "test:prepare" do $: << "test" - Minitest.run(["test/models", "test/helpers", "test/unit"]) + Minitest.rake_run(["test/models", "test/helpers", "test/unit"]) end task :functionals => "test:prepare" do $: << "test" - Minitest.run(["test/controllers", "test/mailers", "test/functional"]) + Minitest.rake_run(["test/controllers", "test/mailers", "test/functional"]) end end |