aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorCody Cutrer <cody@cutrer.us>2016-08-31 09:28:44 -0600
committerCody Cutrer <cody@instructure.com>2017-07-17 13:46:44 -0600
commited44b145bd6d621cd19a4a3c94eff1311e9c3755 (patch)
tree652eb7df106e28b88f1e42863890ca085c5ed417 /railties
parentc24be369322b9e0211fcef30003375de195ef660 (diff)
downloadrails-ed44b145bd6d621cd19a4a3c94eff1311e9c3755.tar.gz
rails-ed44b145bd6d621cd19a4a3c94eff1311e9c3755.tar.bz2
rails-ed44b145bd6d621cd19a4a3c94eff1311e9c3755.zip
support `-` as an argument to `rails runner`
in Rails 4.0, you could use `/dev/stdin` on both Linux and Mac, but with the switch to Kernel.load in Rails 4.1, this broke on Linux (you get a LoadError). Instead, explicitly detect `-` as meaning stdin, then read from stdin explicitly, instead of performing file gymnastics. This should now work on any platform uniformly. Passing a script via stdin is useful when you're sshing to a server, and the script you want to run is stored locally. You could theoretically pass the entire script on the command line, but in reality you'll run into problems with the command being too long.
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md5
-rw-r--r--railties/lib/rails/commands/runner/USAGE3
-rw-r--r--railties/lib/rails/commands/runner/runner_command.rb6
-rw-r--r--railties/test/application/runner_test.rb8
4 files changed, 20 insertions, 2 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index f720b7caab..45e1f5f3ea 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Support `-` as a platform-agnostic way to run a script from stdin with
+ `rails runner`
+
+ *Cody Cutrer*
+
* Add `bootsnap` to default `Gemfile`.
*Burke Libbey*
diff --git a/railties/lib/rails/commands/runner/USAGE b/railties/lib/rails/commands/runner/USAGE
index b2a6e8493d..24b60037f0 100644
--- a/railties/lib/rails/commands/runner/USAGE
+++ b/railties/lib/rails/commands/runner/USAGE
@@ -8,6 +8,9 @@ Run the Ruby file located at `path/to/filename.rb` after loading the app:
<%= executable %> path/to/filename.rb
+Run the Ruby script read from stdin after loading the app:
+ <%= executable %> -
+
<% unless Gem.win_platform? %>
You can also use the runner command as a shebang line for your executables:
diff --git a/railties/lib/rails/commands/runner/runner_command.rb b/railties/lib/rails/commands/runner/runner_command.rb
index 6864a9726b..c931fc2152 100644
--- a/railties/lib/rails/commands/runner/runner_command.rb
+++ b/railties/lib/rails/commands/runner/runner_command.rb
@@ -13,7 +13,7 @@ module Rails
end
def self.banner(*)
- "#{super} [<'Some.ruby(code)'> | <filename.rb>]"
+ "#{super} [<'Some.ruby(code)'> | <filename.rb> | -]"
end
def perform(code_or_file = nil, *command_argv)
@@ -29,7 +29,9 @@ module Rails
ARGV.replace(command_argv)
- if File.exist?(code_or_file)
+ if code_or_file == "-"
+ eval($stdin.read, binding, "stdin")
+ elsif File.exist?(code_or_file)
$0 = code_or_file
Kernel.load code_or_file
else
diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb
index 0c45bc398a..81f717b2c3 100644
--- a/railties/test/application/runner_test.rb
+++ b/railties/test/application/runner_test.rb
@@ -84,6 +84,14 @@ module ApplicationTests
assert_match %w( a b ).to_s, Dir.chdir(app_path) { `bin/rails runner "bin/program_name.rb" a b` }
end
+ def test_should_run_stdin
+ app_file "bin/count_users.rb", <<-SCRIPT
+ puts User.count
+ SCRIPT
+
+ assert_match "42", Dir.chdir(app_path) { `cat bin/count_users.rb | bin/rails runner -` }
+ end
+
def test_with_hook
add_to_config <<-RUBY
runner do |app|