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'

This commit is contained in:
Jeremy Kemper 2013-01-06 16:13:47 -07:00
parent 19b52d3f81
commit 009873aec8
31 changed files with 163 additions and 230 deletions

View File

@ -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)) * 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 * Threadsafe on by default
### Deprecations ### Deprecations

View File

@ -194,7 +194,7 @@ If you need a different session storage mechanism, you can change it in the `con
```ruby ```ruby
# Use the database for sessions instead of the cookie-based default, # Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information # 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 # YourApp::Application.config.session_store :active_record_store
``` ```

View File

@ -419,7 +419,7 @@ Receiving and parsing emails with Action Mailer can be a rather complex endeavor
* Implement a `receive` method in your mailer. * 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: 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:

View File

@ -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. 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 ```bash
rails g model rails g model

View File

@ -26,126 +26,16 @@ quickly.
Launch! 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` ### `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: This file is as follows:
```ruby ```ruby
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__) APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__) require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands' require 'rails/commands'
@ -227,7 +117,7 @@ If we used `s` rather than `server`, Rails will use the `aliases` defined in the
```ruby ```ruby
when 'server' when 'server'
# Change to the application's path if there is no config.ru file in current dir. # 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. # 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")) Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))

View File

@ -1,5 +1,19 @@
## Rails 4.0.0 (unreleased) ## ## 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 * `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` 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` to your application.rb. If you don't want the asset pipeline on a new app use `--skip-sprockets`

View File

@ -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

View File

@ -1,9 +1,12 @@
require 'rbconfig' 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 # If we are inside a Rails application this method performs an exec and thus
# the rest of this script is not run. # 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' require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit(1) } Signal.trap("INT") { puts; exit(1) }

View File

@ -72,7 +72,7 @@ when 'console'
when 'server' when 'server'
# Change to the application's path if there is no config.ru file in current dir. # 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. # 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")) Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))

View File

@ -24,7 +24,7 @@ ARGV.clone.options do |opts|
if RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ if RbConfig::CONFIG['host_os'] !~ /mswin|mingw/
opts.separator "" 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 "-------------------------------------------------------------"
opts.separator "#!/usr/bin/env #{File.expand_path($0)} runner" opts.separator "#!/usr/bin/env #{File.expand_path($0)} runner"
opts.separator "" opts.separator ""

View File

@ -186,7 +186,7 @@ module Rails
log :generate, what log :generate, what
argument = args.map {|arg| arg.to_s }.flatten.join(" ") 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 end
# Runs the supplied rake task # Runs the supplied rake task

View File

@ -63,6 +63,13 @@ module Rails
keep_file 'app/models/concerns' keep_file 'app/models/concerns'
end end
def bin
directory "bin" do |content|
"#{shebang}\n" + content
end
chmod "bin", 0755, verbose: false
end
def config def config
empty_directory "config" empty_directory "config"
@ -103,13 +110,6 @@ module Rails
directory "public", "public", recursive: false directory "public", "public", recursive: false
end end
def script
directory "script" do |content|
"#{shebang}\n" + content
end
chmod "script", 0755, verbose: false
end
def test def test
empty_directory_with_keep_file 'test/fixtures' empty_directory_with_keep_file 'test/fixtures'
empty_directory_with_keep_file 'test/controllers' empty_directory_with_keep_file 'test/controllers'
@ -178,6 +178,10 @@ module Rails
build(:app) build(:app)
end end
def create_bin_files
build(:bin)
end
def create_config_files def create_config_files
build(:config) build(:config)
end end
@ -211,10 +215,6 @@ module Rails
build(:public_directory) build(:public_directory)
end end
def create_script_files
build(:script)
end
def create_test_files def create_test_files
build(:test) unless options[:skip_test_unit] build(:test) unless options[:skip_test_unit]
end end

View File

@ -166,6 +166,7 @@ The default directory structure of a generated Ruby on Rails application:
| | `-- concerns | | `-- concerns
| `-- views | `-- views
| `-- layouts | `-- layouts
|-- bin
|-- config |-- config
| |-- environments | |-- environments
| |-- initializers | |-- initializers
@ -177,7 +178,6 @@ The default directory structure of a generated Ruby on Rails application:
| `-- tasks | `-- tasks
|-- log |-- log
|-- public |-- public
|-- script
|-- test |-- test
| |-- controllers | |-- controllers
| |-- fixtures | |-- fixtures
@ -226,6 +226,12 @@ app/helpers
generated for you automatically when using generators for controllers. generated for you automatically when using generators for controllers.
Helpers can be used to wrap functionality for your views into methods. 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 <gem>`
to add it. For example, `bundle binstubs unicorn` adds ./bin/unicorn.
config config
Configuration files for the Rails environment, the routing map, the database, Configuration files for the Rails environment, the routing map, the database,
and other dependencies. and other dependencies.
@ -248,9 +254,6 @@ public
default HTML files. This should be set as the DOCUMENT_ROOT of your web default HTML files. This should be set as the DOCUMENT_ROOT of your web
server. server.
script
Helper scripts for automation and generation.
test test
Unit and functional tests along with fixtures. When using the rails generate 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 command, template test files will be generated for you and placed in this

View File

@ -0,0 +1,3 @@
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'rubygems'
load Gem.bin_path('bundler', 'bundle')

View File

@ -0,0 +1,3 @@
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'

View File

@ -0,0 +1,3 @@
require_relative '../config/boot'
require 'rake'
Rake.application.run

View File

@ -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'

View File

@ -130,13 +130,13 @@ task default: :test
end end
end end
def script(force = false) def bin(force = false)
return unless engine? return unless engine?
directory "script", force: force do |content| directory "bin", force: force do |content|
"#{shebang}\n" + content "#{shebang}\n" + content
end end
chmod "script", 0755, verbose: false chmod "bin", 0755, verbose: false
end end
def gemfile_entry def gemfile_entry
@ -214,8 +214,8 @@ task default: :test
build(:images) build(:images)
end end
def create_script_files def create_bin_files
build(:script) build(:bin)
end end
def create_test_files def create_test_files
@ -264,8 +264,8 @@ task default: :test
store_application_definition! store_application_definition!
build(:test_dummy_config) build(:test_dummy_config)
build(:test_dummy_clean) build(:test_dummy_clean)
# ensure that script/rails has proper dummy_path # ensure that bin/rails has proper dummy_path
build(:script, true) build(:bin, true)
end end
end end

View File

@ -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

View File

@ -15,7 +15,7 @@
class SourceAnnotationExtractor class SourceAnnotationExtractor
class Annotation < Struct.new(:line, :tag, :text) class Annotation < Struct.new(:line, :tag, :text)
def self.directories 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 end
# Returns a representation of the annotation that looks like this: # Returns a representation of the annotation that looks like this:
@ -31,11 +31,11 @@ class SourceAnnotationExtractor
end end
end end
# Prints all annotations with tag +tag+ under the root directories +app+, +config+, +lib+, # Prints all annotations with tag +tag+ under the root directories +app+,
# +script+, and +test+ (recursively). Filenames with extension # +config+, +lib+, and +test+ (recursively). Filenames with extension
# +.builder+, +.rb+, +.erb+, +.haml+, +.slim+, +.css+, +.scss+, +.js+, # +.builder+, +.rb+, +.erb+, +.haml+, +.slim+, +.css+, +.scss+, +.js+,
# +.coffee+, and +.rake+ are taken into account. The +options+ hash is passed to each # +.coffee+, and +.rake+ are taken into account. The +options+ hash is
# annotation's +to_s+. # passed to each annotation's +to_s+.
# #
# This class method is the single entry point for the rake tasks. # This class method is the single entry point for the rake tasks.
def self.enumerate(tag, options={}) def self.enumerate(tag, options={})

View File

@ -1,6 +1,6 @@
namespace :rails do namespace :rails do
desc "Update configs and some other initially generated files (or use just update:configs, update:scripts, or 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:scripts", "update:application_controller" ] task update: [ "update:configs", "update:bin", "update:application_controller" ]
desc "Applies the template supplied by LOCATION=(/path/to/template) or URL" desc "Applies the template supplied by LOCATION=(/path/to/template) or URL"
task :template do task :template do
@ -58,9 +58,9 @@ namespace :rails do
invoke_from_app_generator :create_config_files invoke_from_app_generator :create_config_files
end end
# desc "Adds new scripts to the application script/ directory" # desc "Adds new executables to the application bin/ directory"
task :scripts do task :bin do
invoke_from_app_generator :create_script_files invoke_from_app_generator :create_bin_files
end end
# desc "Rename application.rb to application_controller.rb" # desc "Rename application.rb to application_controller.rb"

View File

@ -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

View File

@ -30,7 +30,7 @@ module ApplicationTests
end end
test "allow running plugin new generator inside Rails app directory" do 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")) assert File.exist?(File.join(rails_root, "vendor/plugins/bukkits/test/dummy/config/application.rb"))
end end

View File

@ -62,7 +62,6 @@ module ApplicationTests
app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" 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 "db/some_seeds.rb", "# TODO: note in db directory"
app_file "lib/some_file.rb", "# TODO: note in lib 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 "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" 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 config directory/, output)
assert_match(/note in db directory/, output) assert_match(/note in db directory/, output)
assert_match(/note in lib 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 test directory/, output)
assert_no_match(/note in some_other 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| lines.each do |line_number|
assert_equal 4, line_number.size 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 "config/initializers/some_initializer.rb", "# TODO: note in config directory"
app_file "db/some_seeds.rb", "# TODO: note in db 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 "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 "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" 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 config directory/, output)
assert_match(/note in db directory/, output) assert_match(/note in db directory/, output)
assert_match(/note in lib 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 test directory/, output)
assert_match(/note in some_other 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| lines.each do |line_number|
assert_equal 4, line_number.size assert_equal 4, line_number.size

View File

@ -151,7 +151,7 @@ class ActionsTest < Rails::Generators::TestCase
end end
def test_generate_should_run_script_generate_with_argument_and_options 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' action :generate, 'model', 'MyModel'
end end

View File

@ -17,6 +17,9 @@ DEFAULT_APP_FILES = %w(
app/models app/models
app/models/concerns app/models/concerns
app/views/layouts app/views/layouts
bin/bundle
bin/rails
bin/rake
config/environments config/environments
config/initializers config/initializers
config/locales config/locales
@ -26,7 +29,6 @@ DEFAULT_APP_FILES = %w(
lib/tasks lib/tasks
lib/assets lib/assets
log log
script/rails
test/fixtures test/fixtures
test/controllers test/controllers
test/models test/models

View File

@ -209,10 +209,10 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
assert_file "app/views" assert_file "app/views"
assert_file "app/helpers" assert_file "app/helpers"
assert_file "app/mailers" assert_file "app/mailers"
assert_file "bin/rails"
assert_file "config/routes.rb", /Rails.application.routes.draw do/ 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/engine.rb", /module Bukkits\n class Engine < ::Rails::Engine\n end\nend/
assert_file "lib/bukkits.rb", /require "bukkits\/engine"/ assert_file "lib/bukkits.rb", /require "bukkits\/engine"/
assert_file "script/rails"
end end
def test_being_quiet_while_creating_dummy_application def test_being_quiet_while_creating_dummy_application
@ -246,15 +246,15 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_usage_of_engine_commands def test_usage_of_engine_commands
run_generator [destination_root, "--full"] run_generator [destination_root, "--full"]
assert_file "script/rails", /ENGINE_PATH = File.expand_path\('..\/..\/lib\/bukkits\/engine', __FILE__\)/ assert_file "bin/rails", /ENGINE_PATH = File.expand_path\('..\/..\/lib\/bukkits\/engine', __FILE__\)/
assert_file "script/rails", /ENGINE_ROOT = File.expand_path\('..\/..', __FILE__\)/ assert_file "bin/rails", /ENGINE_ROOT = File.expand_path\('..\/..', __FILE__\)/
assert_file "script/rails", /require 'rails\/all'/ assert_file "bin/rails", /require 'rails\/all'/
assert_file "script/rails", /require 'rails\/engine\/commands'/ assert_file "bin/rails", /require 'rails\/engine\/commands'/
end end
def test_shebang def test_shebang
run_generator [destination_root, "--full"] run_generator [destination_root, "--full"]
assert_file "script/rails", /#!\/usr\/bin\/env ruby/ assert_file "bin/rails", /#!\/usr\/bin\/env ruby/
end end
def test_passing_dummy_path_as_a_parameter def test_passing_dummy_path_as_a_parameter

View File

@ -68,12 +68,12 @@ module SharedGeneratorTests
def test_shebang_is_added_to_rails_file def test_shebang_is_added_to_rails_file
run_generator [destination_root, "--ruby", "foo/bar/baz", "--full"] run_generator [destination_root, "--ruby", "foo/bar/baz", "--full"]
assert_file "script/rails", /#!foo\/bar\/baz/ assert_file "bin/rails", /#!foo\/bar\/baz/
end end
def test_shebang_when_is_the_same_as_default_use_env def test_shebang_when_is_the_same_as_default_use_env
run_generator [destination_root, "--ruby", Thor::Util.ruby_command, "--full"] 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 end
def test_template_raises_an_error_with_invalid_path def test_template_raises_an_error_with_invalid_path

View File

@ -206,7 +206,7 @@ module TestHelpers
def script(script) def script(script)
Dir.chdir(app_path) do Dir.chdir(app_path) do
`#{Gem.ruby} #{app_path}/script/rails #{script}` `#{Gem.ruby} #{app_path}/bin/rails #{script}`
end end
end end

View File

@ -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