From 009873aec89a4b843b41accf616b42b7a9917ba8 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 6 Jan 2013 16:13:47 -0700 Subject: [PATCH] Introduce ./bin for your app's executables: bin/bundle, bin/rails, bin/rake. Executable scripts are versioned code like the rest of your app. To generate a stub for a bundled gem: 'bundle binstubs unicorn' and 'git add bin/unicorn' --- guides/source/4_0_release_notes.md | 2 + guides/source/action_controller_overview.md | 2 +- guides/source/action_mailer_basics.md | 2 +- guides/source/engines.md | 4 +- guides/source/initialization.md | 120 +----------------- railties/CHANGELOG.md | 14 ++ railties/lib/rails/app_rails_loader.rb | 29 +++++ railties/lib/rails/cli.rb | 7 +- railties/lib/rails/commands.rb | 2 +- railties/lib/rails/commands/runner.rb | 2 +- railties/lib/rails/generators/actions.rb | 2 +- .../generators/rails/app/app_generator.rb | 22 ++-- .../generators/rails/app/templates/README | 11 +- .../generators/rails/app/templates/bin/bundle | 3 + .../generators/rails/app/templates/bin/rails | 3 + .../generators/rails/app/templates/bin/rake | 3 + .../rails/app/templates/script/rails | 5 - .../rails/plugin_new/plugin_new_generator.rb | 14 +- .../templates/{script => bin}/rails.tt | 0 railties/lib/rails/script_rails_loader.rb | 29 ----- .../lib/rails/source_annotation_extractor.rb | 10 +- railties/lib/rails/tasks/framework.rake | 10 +- railties/test/app_rails_loader_test.rb | 41 ++++++ railties/test/application/generators_test.rb | 2 +- railties/test/application/rake/notes_test.rb | 8 +- railties/test/generators/actions_test.rb | 2 +- .../test/generators/app_generator_test.rb | 4 +- .../generators/plugin_new_generator_test.rb | 12 +- .../test/generators/shared_generator_tests.rb | 4 +- railties/test/isolation/abstract_unit.rb | 2 +- railties/test/script_rails_loader_test.rb | 22 ---- 31 files changed, 163 insertions(+), 230 deletions(-) create mode 100644 railties/lib/rails/app_rails_loader.rb create mode 100644 railties/lib/rails/generators/rails/app/templates/bin/bundle create mode 100644 railties/lib/rails/generators/rails/app/templates/bin/rails create mode 100644 railties/lib/rails/generators/rails/app/templates/bin/rake delete mode 100644 railties/lib/rails/generators/rails/app/templates/script/rails rename railties/lib/rails/generators/rails/plugin_new/templates/{script => bin}/rails.tt (100%) delete mode 100644 railties/lib/rails/script_rails_loader.rb create mode 100644 railties/test/app_rails_loader_test.rb delete mode 100644 railties/test/script_rails_loader_test.rb diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md index 80af0c1225..002e1da5af 100644 --- a/guides/source/4_0_release_notes.md +++ b/guides/source/4_0_release_notes.md @@ -85,6 +85,8 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/master/railt * New test locations `test/models`, `test/helpers`, `test/controllers`, and `test/mailers`. Corresponding rake tasks added as well. ([Pull Request](https://github.com/rails/rails/pull/7878)) +* Your app's executables now live in the `bin/` dir. Run `rake update:bin` to get `bin/bundle`, `bin/rails`, and `bin/rake`. + * Threadsafe on by default ### Deprecations diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md index f06aeccffc..e0408cadda 100644 --- a/guides/source/action_controller_overview.md +++ b/guides/source/action_controller_overview.md @@ -194,7 +194,7 @@ If you need a different session storage mechanism, you can change it in the `con ```ruby # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information -# (create the session table with "script/rails g active_record:session_migration") +# (create the session table with "rails g active_record:session_migration") # YourApp::Application.config.session_store :active_record_store ``` diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md index 795afd0150..7c6ef52f4a 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -419,7 +419,7 @@ Receiving and parsing emails with Action Mailer can be a rather complex endeavor * Implement a `receive` method in your mailer. -* Configure your email server to forward emails from the address(es) you would like your app to receive to `/path/to/app/script/rails runner 'UserMailer.receive(STDIN.read)'`. +* Configure your email server to forward emails from the address(es) you would like your app to receive to `/path/to/app/bin/rails runner 'UserMailer.receive(STDIN.read)'`. Once a method called `receive` is defined in any mailer, Action Mailer will parse the raw incoming email into an email object, decode it, instantiate a new mailer, and pass the email object to the mailer `receive` instance method. Here's an example: diff --git a/guides/source/engines.md b/guides/source/engines.md index 116a7e67cd..8c0cbed3f2 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -149,9 +149,9 @@ Lastly, the `app/views` directory contains a `layouts` folder which contains a f If you don't want to force a layout on to users of the engine, then you can delete this file and reference a different layout in the controllers of your engine. -#### `script` directory +#### `bin` directory -This directory contains one file, `script/rails`, which enables you to use the `rails` sub-commands and generators just like you would within an application. This means that you will very easily be able to generate new controllers and models for this engine by running commands like this: +This directory contains one file, `bin/rails`, which enables you to use the `rails` sub-commands and generators just like you would within an application. This means that you will very easily be able to generate new controllers and models for this engine by running commands like this: ```bash rails g model diff --git a/guides/source/initialization.md b/guides/source/initialization.md index 457e28383d..8ba5fa4601 100644 --- a/guides/source/initialization.md +++ b/guides/source/initialization.md @@ -26,126 +26,16 @@ quickly. Launch! ------- -A Rails application is usually started with the command `rails server`. +Now we finally boot and initialize the app. It all starts with your app's +`bin/rails` executable. A Rails application is usually started by running +`rails console` or `rails server`. ### `bin/rails` -The actual `rails` command is kept in _bin/rails_: - -```ruby -#!/usr/bin/env ruby - -if File.exists?(File.join(File.expand_path('../../..', __FILE__), '.git')) - railties_path = File.expand_path('../../lib', __FILE__) - $:.unshift(railties_path) -end -require "rails/cli" -``` - -This file will first attempt to push the `railties/lib` directory if -present, and then requires `rails/cli`. - -### `railties/lib/rails/cli.rb` - -This file looks like this: - -```ruby -require 'rbconfig' -require 'rails/script_rails_loader' - -# If we are inside a Rails application this method performs an exec and thus -# the rest of this script is not run. -Rails::ScriptRailsLoader.exec_script_rails! - -require 'rails/ruby_version_check' -Signal.trap("INT") { puts; exit(1) } - -if ARGV.first == 'plugin' - ARGV.shift - require 'rails/commands/plugin_new' -else - require 'rails/commands/application' -end -``` - -The `rbconfig` file from the Ruby standard library provides us with the `RbConfig` class which contains detailed information about the Ruby environment, including how Ruby was compiled. We can see this in use in `railties/lib/rails/script_rails_loader`. - -```ruby -require 'pathname' - -module Rails - module ScriptRailsLoader - RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"] - SCRIPT_RAILS = File.join('script', 'rails') - ... - - end -end -``` - -The `rails/script_rails_loader` file uses `RbConfig::Config` to obtain the `bin_dir` and `ruby_install_name` values for the configuration which together form the path to the Ruby interpreter. The `RbConfig::CONFIG["EXEEXT"]` will suffix this path with ".exe" if the script is running on Windows. This constant is used later on in `exec_script_rails!`. As for the `SCRIPT_RAILS` constant, we'll see that when we get to the `in_rails_application?` method. - -Back in `rails/cli`, the next line is this: - -```ruby -Rails::ScriptRailsLoader.exec_script_rails! -``` - -This method is defined in `rails/script_rails_loader`: - -```ruby -def self.exec_script_rails! - cwd = Dir.pwd - return unless in_rails_application? || in_rails_application_subdirectory? - exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? - Dir.chdir("..") do - # Recurse in a chdir block: if the search fails we want to be sure - # the application is generated in the original working directory. - exec_script_rails! unless cwd == Dir.pwd - end -rescue SystemCallError - # could not chdir, no problem just return -end -``` - -This method will first check if the current working directory (`cwd`) is a Rails application or a subdirectory of one. This is determined by the `in_rails_application?` method: - -```ruby -def self.in_rails_application? - File.exists?(SCRIPT_RAILS) -end -``` - -The `SCRIPT_RAILS` constant defined earlier is used here, with `File.exists?` checking for its presence in the current directory. If this method returns `false` then `in_rails_application_subdirectory?` will be used: - -```ruby -def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd)) - File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent) -end -``` - -This climbs the directory tree until it reaches a path which contains a `script/rails` file. If a directory containing this file is reached then this line will run: - -```ruby -exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? -``` - -This is effectively the same as running `ruby script/rails [arguments]`, where `[arguments]` at this point in time is simply "server". - -Rails Initialization --------------------- - -Only now we finally start the real initialization process, beginning -with `script/rails`. - -TIP: If you execute `script/rails` directly from your Rails app you will -skip executing all the code that we've just described. - -### `script/rails` - This file is as follows: ```ruby +#!/usr/bin/env ruby APP_PATH = File.expand_path('../../config/application', __FILE__) require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' @@ -227,7 +117,7 @@ If we used `s` rather than `server`, Rails will use the `aliases` defined in the ```ruby when 'server' # Change to the application's path if there is no config.ru file in current dir. - # This allows us to run script/rails server from other directories, but still get + # This allows us to run `rails server` from other directories, but still get # the main config.ru and properly set the tmp directory. Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index e8a91af7af..5f6a23c53e 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,5 +1,19 @@ ## Rails 4.0.0 (unreleased) ## +* App executables now live in the `bin/` directory: `bin/bundle`, + `bin/rails`, `bin/rake`. Run `rake rails:update:bin` to add these + executables to your own app. `script/rails` is gone from new apps. + + Running executables within your app ensures they use your app's Ruby + version and its bundled gems, and it ensures your production deployment + tools only need to execute a single script. No more having to carefully + `cd` to the app dir and run `bundle exec ...`. + + Rather than treating `bin/` as a junk drawer for generated "binstubs", + bundler 1.3 adds support for generating stubs for just the executables + you actually use: `bundle binstubs unicorn` generates `bin/unicorn`. + Add that executable to git and version it just like any other app code. + * `config.assets.enabled` is now true by default. If you're upgrading from a Rails 3.x app that does not use the asset pipeline, you'll be required to add `config.assets.enabled = false` to your application.rb. If you don't want the asset pipeline on a new app use `--skip-sprockets` diff --git a/railties/lib/rails/app_rails_loader.rb b/railties/lib/rails/app_rails_loader.rb new file mode 100644 index 0000000000..8937e10db3 --- /dev/null +++ b/railties/lib/rails/app_rails_loader.rb @@ -0,0 +1,29 @@ +require 'pathname' + +module Rails + module AppRailsLoader + RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"] + EXECUTABLE = 'bin/rails' + + def self.exec_app_rails + cwd = Dir.pwd + return unless in_rails_application_or_engine? || in_rails_application_or_engine_subdirectory? + exec RUBY, EXECUTABLE, *ARGV if in_rails_application_or_engine? + Dir.chdir("..") do + # Recurse in a chdir block: if the search fails we want to be sure + # the application is generated in the original working directory. + exec_app_rails unless cwd == Dir.pwd + end + rescue SystemCallError + # could not chdir, no problem just return + end + + def self.in_rails_application_or_engine? + File.exists?(EXECUTABLE) && File.read(EXECUTABLE) =~ /(APP|ENGINE)_PATH/ + end + + def self.in_rails_application_or_engine_subdirectory?(path = Pathname.new(Dir.pwd)) + File.exists?(File.join(path, EXECUTABLE)) || !path.root? && in_rails_application_or_engine_subdirectory?(path.parent) + end + end +end diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb index 443d6f47ad..b717b026de 100644 --- a/railties/lib/rails/cli.rb +++ b/railties/lib/rails/cli.rb @@ -1,9 +1,12 @@ require 'rbconfig' -require 'rails/script_rails_loader' +require 'rails/app_rails_loader' # If we are inside a Rails application this method performs an exec and thus # the rest of this script is not run. -Rails::ScriptRailsLoader.exec_script_rails! +# +# TODO: when we hit this, advise adding ./bin to $PATH instead. Then the +# app's `rails` executable is run immediately. +Rails::AppRailsLoader.exec_app_rails require 'rails/ruby_version_check' Signal.trap("INT") { puts; exit(1) } diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb index 5ccec8082c..9cb11f66c6 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -72,7 +72,7 @@ when 'console' when 'server' # Change to the application's path if there is no config.ru file in current dir. - # This allows us to run script/rails server from other directories, but still get + # This allows us to run `rails server` from other directories, but still get # the main config.ru and properly set the tmp directory. Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb index 6adbdc6e0b..c4622d6a2d 100644 --- a/railties/lib/rails/commands/runner.rb +++ b/railties/lib/rails/commands/runner.rb @@ -24,7 +24,7 @@ ARGV.clone.options do |opts| if RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ opts.separator "" - opts.separator "You can also use runner as a shebang line for your scripts like this:" + opts.separator "You can also use runner as a shebang line for your executables:" opts.separator "-------------------------------------------------------------" opts.separator "#!/usr/bin/env #{File.expand_path($0)} runner" opts.separator "" diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index b96ee9295e..71cb0b903b 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -186,7 +186,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 diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 372790df59..7d9044a2b4 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -63,6 +63,13 @@ module Rails keep_file 'app/models/concerns' end + def bin + directory "bin" do |content| + "#{shebang}\n" + content + end + chmod "bin", 0755, verbose: false + end + def config empty_directory "config" @@ -103,13 +110,6 @@ module Rails directory "public", "public", recursive: false end - def script - directory "script" do |content| - "#{shebang}\n" + content - end - chmod "script", 0755, verbose: false - end - def test empty_directory_with_keep_file 'test/fixtures' empty_directory_with_keep_file 'test/controllers' @@ -178,6 +178,10 @@ module Rails build(:app) end + def create_bin_files + build(:bin) + end + def create_config_files build(:config) end @@ -211,10 +215,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 diff --git a/railties/lib/rails/generators/rails/app/templates/README b/railties/lib/rails/generators/rails/app/templates/README index 2bd7c27f2a..e566c01c46 100644 --- a/railties/lib/rails/generators/rails/app/templates/README +++ b/railties/lib/rails/generators/rails/app/templates/README @@ -166,6 +166,7 @@ The default directory structure of a generated Ruby on Rails application: | | `-- concerns | `-- views | `-- layouts + |-- bin |-- config | |-- environments | |-- initializers @@ -177,7 +178,6 @@ The default directory structure of a generated Ruby on Rails application: | `-- tasks |-- log |-- public - |-- script |-- test | |-- controllers | |-- fixtures @@ -226,6 +226,12 @@ app/helpers generated for you automatically when using generators for controllers. Helpers can be used to wrap functionality for your views into methods. +bin + Your app's executables -- bundler, rake, rails, and more -- automatically + run using your app's Ruby version and its bundled gems. When you bundle + a new gem and need to run one of its executables, use `bundle binstubs ` + to add it. For example, `bundle binstubs unicorn` adds ./bin/unicorn. + config Configuration files for the Rails environment, the routing map, the database, and other dependencies. @@ -248,9 +254,6 @@ public 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 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..e0df7f4440 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/bin/bundle @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +require 'rubygems' +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/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/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb index cd756a729d..af00748037 100644 --- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb @@ -130,13 +130,13 @@ task default: :test end end - def script(force = false) + 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 @@ -214,8 +214,8 @@ task default: :test build(:images) end - def create_script_files - build(:script) + def create_bin_files + build(:bin) end def create_test_files @@ -264,8 +264,8 @@ task default: :test store_application_definition! build(:test_dummy_config) 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 diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt b/railties/lib/rails/generators/rails/plugin_new/templates/bin/rails.tt similarity index 100% rename from railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt rename to railties/lib/rails/generators/rails/plugin_new/templates/bin/rails.tt diff --git a/railties/lib/rails/script_rails_loader.rb b/railties/lib/rails/script_rails_loader.rb deleted file mode 100644 index 7054089614..0000000000 --- a/railties/lib/rails/script_rails_loader.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'pathname' - -module Rails - module ScriptRailsLoader - RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"] - SCRIPT_RAILS = File.join('script', 'rails') - - def self.exec_script_rails! - cwd = Dir.pwd - return unless in_rails_application? || in_rails_application_subdirectory? - exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application? - Dir.chdir("..") do - # Recurse in a chdir block: if the search fails we want to be sure - # the application is generated in the original working directory. - exec_script_rails! unless cwd == Dir.pwd - end - rescue SystemCallError - # could not chdir, no problem just return - end - - def self.in_rails_application? - File.exists?(SCRIPT_RAILS) - end - - def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd)) - File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent) - end - end -end \ No newline at end of file diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index ac806e8006..971fbf627b 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -15,7 +15,7 @@ class SourceAnnotationExtractor class Annotation < Struct.new(:line, :tag, :text) def self.directories - @@directories ||= %w(app config db lib script test) + (ENV['SOURCE_ANNOTATION_DIRECTORIES'] || '').split(',') + @@directories ||= %w(app config db lib test) + (ENV['SOURCE_ANNOTATION_DIRECTORIES'] || '').split(',') end # Returns a representation of the annotation that looks like this: @@ -31,11 +31,11 @@ class SourceAnnotationExtractor end end - # Prints all annotations with tag +tag+ under the root directories +app+, +config+, +lib+, - # +script+, and +test+ (recursively). Filenames with extension + # Prints all annotations with tag +tag+ under the root directories +app+, + # +config+, +lib+, and +test+ (recursively). Filenames with extension # +.builder+, +.rb+, +.erb+, +.haml+, +.slim+, +.css+, +.scss+, +.js+, - # +.coffee+, and +.rake+ are taken into account. The +options+ hash is passed to each - # annotation's +to_s+. + # +.coffee+, and +.rake+ are taken into account. The +options+ hash is + # passed to each annotation's +to_s+. # # This class method is the single entry point for the rake tasks. def self.enumerate(tag, options={}) diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake index 50499304cb..2116330b45 100644 --- a/railties/lib/rails/tasks/framework.rake +++ b/railties/lib/rails/tasks/framework.rake @@ -1,6 +1,6 @@ namespace :rails do - desc "Update configs and some other initially generated files (or use just update:configs, update:scripts, or update:application_controller)" - task update: [ "update:configs", "update:scripts", "update:application_controller" ] + desc "Update configs and some other initially generated files (or use just update:configs, update:bin, or update:application_controller)" + task update: [ "update:configs", "update:bin", "update:application_controller" ] desc "Applies the template supplied by LOCATION=(/path/to/template) or URL" task :template do @@ -58,9 +58,9 @@ namespace :rails do invoke_from_app_generator :create_config_files end - # desc "Adds new scripts to the application script/ directory" - task :scripts do - invoke_from_app_generator :create_script_files + # desc "Adds new executables to the application bin/ directory" + task :bin do + invoke_from_app_generator :create_bin_files end # desc "Rename application.rb to application_controller.rb" diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_rails_loader_test.rb new file mode 100644 index 0000000000..87e0ad7bd7 --- /dev/null +++ b/railties/test/app_rails_loader_test.rb @@ -0,0 +1,41 @@ +require 'abstract_unit' +require 'rails/app_rails_loader' + +class AppRailsLoaderTest < ActiveSupport::TestCase + test "is in a rails application if bin/rails exists and contains APP_PATH" do + File.stubs(:exists?).returns(true) + File.stubs(:read).with('bin/rails').returns('APP_PATH') + assert Rails::AppRailsLoader.in_rails_application_or_engine? + end + + test "is not in a rails application if bin/rails exists but doesn't contain APP_PATH" do + File.stubs(:exists?).returns(true) + File.stubs(:read).with('bin/rails').returns('railties bin/rails') + assert !Rails::AppRailsLoader.in_rails_application_or_engine? + end + + test "is in a rails application if parent directory has bin/rails containing APP_PATH" do + File.stubs(:exists?).with("/foo/bar/bin/rails").returns(false) + File.stubs(:exists?).with("/foo/bin/rails").returns(true) + File.stubs(:read).with('/foo/bin/rails').returns('APP_PATH') + assert Rails::AppRailsLoader.in_rails_application_or_engine_subdirectory?(Pathname.new("/foo/bar")) + end + + test "is not in a rails application if at the root directory and doesn't have bin/rails" do + Pathname.any_instance.stubs(:root?).returns true + assert !Rails::AppRailsLoader.in_rails_application_or_engine? + end + + test "is in a rails engine if parent directory has bin/rails containing ENGINE_PATH" do + File.stubs(:exists?).with("/foo/bar/bin/rails").returns(false) + File.stubs(:exists?).with("/foo/bin/rails").returns(true) + File.stubs(:read).with('/foo/bin/rails').returns('ENGINE_PATH') + assert Rails::AppRailsLoader.in_rails_application_or_engine_subdirectory?(Pathname.new("/foo/bar")) + end + + test "is in a rails engine if bin/rails exists containing ENGINE_PATH" do + File.stubs(:exists?).returns(true) + File.stubs(:read).with('bin/rails').returns('ENGINE_PATH') + assert Rails::AppRailsLoader.in_rails_application_or_engine? + end +end diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb index bc0af499c1..78ada58ec8 100644 --- a/railties/test/application/generators_test.rb +++ b/railties/test/application/generators_test.rb @@ -30,7 +30,7 @@ module ApplicationTests end test "allow running plugin new generator inside Rails app directory" do - FileUtils.cd(rails_root){ `ruby script/rails plugin new vendor/plugins/bukkits` } + FileUtils.cd(rails_root){ `ruby bin/rails plugin new vendor/plugins/bukkits` } assert File.exist?(File.join(rails_root, "vendor/plugins/bukkits/test/dummy/config/application.rb")) end diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 744bb93671..5893d58925 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -62,7 +62,6 @@ module ApplicationTests app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" app_file "db/some_seeds.rb", "# TODO: note in db directory" app_file "lib/some_file.rb", "# TODO: note in lib directory" - app_file "script/run_something.rb", "# TODO: note in script directory" app_file "test/some_test.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in test directory" app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" @@ -83,11 +82,10 @@ module ApplicationTests assert_match(/note in config directory/, output) assert_match(/note in db directory/, output) assert_match(/note in lib directory/, output) - assert_match(/note in script directory/, output) assert_match(/note in test directory/, output) assert_no_match(/note in some_other directory/, output) - assert_equal 6, lines.size + assert_equal 5, lines.size lines.each do |line_number| assert_equal 4, line_number.size @@ -100,7 +98,6 @@ module ApplicationTests app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" app_file "db/some_seeds.rb", "# TODO: note in db directory" app_file "lib/some_file.rb", "# TODO: note in lib directory" - app_file "script/run_something.rb", "# TODO: note in script directory" app_file "test/some_test.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in test directory" app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" @@ -121,12 +118,11 @@ module ApplicationTests assert_match(/note in config directory/, output) assert_match(/note in db directory/, output) assert_match(/note in lib directory/, output) - assert_match(/note in script directory/, output) assert_match(/note in test directory/, output) assert_match(/note in some_other directory/, output) - assert_equal 7, lines.size + assert_equal 6, lines.size lines.each do |line_number| assert_equal 4, line_number.size diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 54734ed260..c9e9f33d4e 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -151,7 +151,7 @@ class ActionsTest < Rails::Generators::TestCase end def test_generate_should_run_script_generate_with_argument_and_options - generator.expects(:run_ruby_script).once.with('script/rails generate model MyModel', verbose: false) + generator.expects(:run_ruby_script).once.with('bin/rails generate model MyModel', verbose: false) action :generate, 'model', 'MyModel' end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 945cb61bc1..1750149abc 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -17,6 +17,9 @@ DEFAULT_APP_FILES = %w( app/models app/models/concerns app/views/layouts + bin/bundle + bin/rails + bin/rake config/environments config/initializers config/locales @@ -26,7 +29,6 @@ DEFAULT_APP_FILES = %w( lib/tasks lib/assets log - script/rails test/fixtures test/controllers test/models diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index ab78800a4e..4bf5a2f08b 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -209,10 +209,10 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_file "app/views" assert_file "app/helpers" assert_file "app/mailers" + assert_file "bin/rails" assert_file "config/routes.rb", /Rails.application.routes.draw do/ assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < ::Rails::Engine\n end\nend/ assert_file "lib/bukkits.rb", /require "bukkits\/engine"/ - assert_file "script/rails" end def test_being_quiet_while_creating_dummy_application @@ -246,15 +246,15 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase def test_usage_of_engine_commands run_generator [destination_root, "--full"] - assert_file "script/rails", /ENGINE_PATH = File.expand_path\('..\/..\/lib\/bukkits\/engine', __FILE__\)/ - assert_file "script/rails", /ENGINE_ROOT = File.expand_path\('..\/..', __FILE__\)/ - assert_file "script/rails", /require 'rails\/all'/ - assert_file "script/rails", /require 'rails\/engine\/commands'/ + assert_file "bin/rails", /ENGINE_PATH = File.expand_path\('..\/..\/lib\/bukkits\/engine', __FILE__\)/ + assert_file "bin/rails", /ENGINE_ROOT = File.expand_path\('..\/..', __FILE__\)/ + assert_file "bin/rails", /require 'rails\/all'/ + assert_file "bin/rails", /require 'rails\/engine\/commands'/ end def test_shebang run_generator [destination_root, "--full"] - assert_file "script/rails", /#!\/usr\/bin\/env ruby/ + assert_file "bin/rails", /#!\/usr\/bin\/env ruby/ end def test_passing_dummy_path_as_a_parameter diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index e4924c8386..d203afed5c 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -68,12 +68,12 @@ module SharedGeneratorTests def test_shebang_is_added_to_rails_file run_generator [destination_root, "--ruby", "foo/bar/baz", "--full"] - assert_file "script/rails", /#!foo\/bar\/baz/ + assert_file "bin/rails", /#!foo\/bar\/baz/ end def test_shebang_when_is_the_same_as_default_use_env run_generator [destination_root, "--ruby", Thor::Util.ruby_command, "--full"] - assert_file "script/rails", /#!\/usr\/bin\/env/ + assert_file "bin/rails", /#!\/usr\/bin\/env/ end def test_template_raises_an_error_with_invalid_path diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 172a42a549..7ae1b5ccfd 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -206,7 +206,7 @@ module TestHelpers def script(script) Dir.chdir(app_path) do - `#{Gem.ruby} #{app_path}/script/rails #{script}` + `#{Gem.ruby} #{app_path}/bin/rails #{script}` end end diff --git a/railties/test/script_rails_loader_test.rb b/railties/test/script_rails_loader_test.rb deleted file mode 100644 index 3ccc147749..0000000000 --- a/railties/test/script_rails_loader_test.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'abstract_unit' -require 'rails/script_rails_loader' - -class ScriptRailsLoaderTest < ActiveSupport::TestCase - - test "is in a rails application if script/rails exists" do - File.stubs(:exists?).returns(true) - assert Rails::ScriptRailsLoader.in_rails_application? - end - - test "is in a rails application if parent directory has script/rails" do - File.stubs(:exists?).with("/foo/bar/script/rails").returns(false) - File.stubs(:exists?).with("/foo/script/rails").returns(true) - assert Rails::ScriptRailsLoader.in_rails_application_subdirectory?(Pathname.new("/foo/bar")) - end - - test "is not in a rails application if at the root directory and doesn't have script/rails" do - Pathname.any_instance.stubs(:root?).returns true - assert !Rails::ScriptRailsLoader.in_rails_application? - end - -end \ No newline at end of file