How to Run a Ruby Script Within Bundler Context

How to run a ruby script within bundler context?

Pass the script name to the ruby command:

bundle exec ruby script_name

If you also want the Rails environment:

bundle exec rails runner script_name

How to test if a Ruby script is running via Bundler

You could check defined?(Bundler), but that will also be present if you require 'bundler' without having run bundle exec.

When you run inside bundle exec, there are a few ENV variables present that aren't otherwise. Notably, BUNDLE_GEMFILE and BUNDLE_BIN_PATH.

There are some more details in the Environment Modifications section of the bundle exec docs.

Run `bundle` system command in subfolder

Just figured it out:

Dir.chdir('sub_folder') do
Bundler.with_clean_env do
system('bundle')
end
end

Shelling out - Any Ruby code that opens a subshell (like system,
backticks, or %x{}) will automatically use the current Bundler
environment. If you need to shell out to a Ruby command that is not
part of your current bundle, use the with_clean_env method with a
block. Any subshells created inside the block will be given the
environment present before Bundler was activated. For example,
Homebrew commands run Ruby, but don't work inside a bundle:

http://bundler.io/man/bundle-exec.1.html#ENVIRONMENT-MODIFICATIONS

Pass ruby script file to rails console

In the meantime, this solution has been supported.

rails r PATH_TO_RUBY_FILE

Much simpler now.

Are bundle exec and require 'bundler/setup' equivalent?

In your specific example they can be considered the same, however in reality they are not the same.

bundle exec makes some changes to the environment that bundler/setup does not make. If your foo.rb never runs a subshell, or never tries to run other ruby executables in subshells, then both versions are equivalent (they will both load bundled gems correctly and work exactly the same).

The whole idea with bundle exec is to enable you to run executables that were not originally designed with bundler in mind. Like rspec, rails, rackup. If your own app (foo.rb) does not try to run such executables that might be dependent on your bundles, then it makes no difference either way. Since all you want to make sure with bundler is that you load the correct gems, and for that bundler/setup works exactly as expected in your case.

From the bundler docs when talking about running ruby system executables:

In some cases, running executables without bundle exec may work, if the executable happens to be installed in your system and does not pull in any gems that conflict with your bundle.

However, this is unreliable and is the source of considerable pain. Even if it looks like it works, it may not work in the future or on another machine.

Then from the manpage of bundle exec you can get some additional clues as to what bundle exec actually does:

ENVIRONMENT MODIFICATIONS

  • make sure that it's still possible to shell out to bundle from inside a command invoked by bundle exec (using $BUNDLE_BIN_PATH)
  • put the directory containing executables (like rails, rspec, rackup) for your bundle on $PATH
  • make sure that if bundler is invoked in the subshell, it uses the same Gemfile (by setting BUNDLE_GEMFILE)
  • add -rbundler/setup to $RUBYOPT, which makes sure that Ruby programs invoked in the subshell can see the gems in the bundle

So if you build your app with bundler support in mind, then you never need to bundle exec your app.

But if you need to use other tools that load your app code that might load gems before they load your app code (which then might pull in a wrong non-bundled gem), then you need to use bundle exec.

Is it possible to use 'bundle exec' functionality from code?

If you want to run some ruby with bundled gems you can just require "bundler/setup":

require 'bundler/setup'
require 'rspec' # loads the version specified in Gemfile

How do I tell from within a ruby script whether it has been run from the command line or from a non-interactive process?

$stdin.tty? will return true if connected to a terminal otherwise false.

There is a fair bit of additional information on question Best practices with STDIN in Ruby?

Using a gem in a pure ruby script (not Rails)

Use bundler. Create a Gemfile along side your ruby script.

In the Gemfile, add:

gem "my-gem", git: "https://github.com/gem123.git", branch: "some-branch"

Make sure bundler is installed:

gem install bundler

And install the required gems:

bundle install

Now just initialize bundler at the top of your script:

require 'rubygems'
require 'bundler/setup'

# require your gems as usual
require 'my-gem'


Related Topics



Leave a reply



Submit