Require files from gem in Ruby script without bundle exec - ruby

I have a script that needs to require specific files out of gems defined in the project Gemfile.
#!/usr/bin/env ruby
require 'some_gem/helpers/some_helper'
... rest of script
When I run the script, I get an error about not being able to load some_helper.rb. If I run with bundle exec command... then everything works.
I understand that bundle exec exposes the Gems to the $LOAD_PATH which lets require work. Is there a way to move that capability into the script so users don't have to type bundle exec?
Do I just need to add require "bundler/setup" to the script before I require the gem files?

http://bundler.io/v1.12/#getting-started
:)
#!/usr/bin/env ruby
require 'rubygems' # because reasons.. most probably it is not needed unless you are using really old ruby where it is not loaded by default
# also at the moment rubygems and bundler are being merged :)
require 'bundler/setup' # for things installed with bundler
require 'some_gem/helpers/some_helper'
You can also check e.g. http://mislav.net/2013/01/understanding-binstubs/

Related

Bundler issue when running a ruby script

I am trying to run some older ruby script (with old ruby version) from within a ruby script. Here is a program:
old_ruby187.rb
#!/usr/ruby/1.8.7/bin/ruby
puts "Hello"
new_ruby230.rb
#!/usr/ruby/2.3.0/bin/ruby
require "rubygems"
require "bundler"
Bundler.setup # Code works if I comment this line
puts `old_ruby187.rb`
I get bundler load error. If I execute ./new_ruby230.rb, it gives an error for the last puts command line.:
'require': no such file to load -- rubygems (LoadError)
If I comment just Bundler.setup and run it, it works fine. Not sure if Bundler.setup tries to load something for system call. I need bundler for other gems used in new_ruby230.rb script.
Any help is appreciated.
Update (02/22/2018):
I ended up using ssh when calling old ruby script. Something like:
new_ruby230.rb
#!/usr/ruby/2.3.0/bin/ruby
require "rubygems"
require "bundler"
require "socket"
Bundler.setup
puts `ssh #{Socket.gethostname} old_ruby187.rb` # this worked!
Pretty sure you're not supposed to require rubygems like that. Bundler is there to manage your gems. Remove that require statement (require "rubygems") and you should be good to go.

How to write a batch script to install ruby gem

I'm writing a batch script as a setup for a ruby program I'm writing. It needs to be able to
a. Make sure Ruby is installed on the user's computer (and if not point them to the ruby download page)
b. make sure the ruby "yaml" gem is installed, which is a prerequisite for it. I've tried
gem install yaml
in the batch script to no avail. How can I write a batch script that will do these two things?
As far as I know, there is no yaml gem. Although it must be required in code that uses it, it is distributed as part of a Ruby installation. Try this:
ruby -ryaml -e"puts 'YAML found'"
It should work; and if you change the -r token to some nonexistent gem, you'll see an exception raised.
Instead of writing your own script, you could use bundler and create a gemfile. This way people can install all the gems on any operating system.
Example:
require 'rubygems'
require 'bundler/setup'
require 'nokogiri'
require 'rest-client'
#require all your gems like normal
def parse(site)
Nokogiri::HTML(RestClient.get(site))
end
And for the gem file:
source: "https://rubygems.org"
gem 'nokogiri', '~> 1.6.7.2' #<= you can specify which version
gem 'rest-client' #<= you don't have to specify a version though
After you've got everything set up, cd to the directory that has the gemfile and run bundle install this will install all the gems

How to include Ruby Gems on Github

So, I've created a GitHub to manage my latest Ruby project, and I want for it to utilize a couple of gems. On my PC, all I have to go is type
gem install "gemName"
and it loads it to my computer, and then all I have to do in my Ruby script is have
require "rubygems"
require "gemName"
How can I do this with GitHub? What I tried to do is create a subfolder from the main repository (called "RubyGems") and then in my main ruby script
require "/RubyGems/colorize"
require "/Rubygems/psych"
With the two gems (colorize and psych) in the "RubyGems" folder.
Is this the proper way to do this? Will this even work? What is the right way to do this? (Sorry, I'm kinda new to GitHub.)
A couple of things, unless you're using a really old version of Ruby (like 1.9) you don't need to require 'rubygems' because is already required by default, next I highly recommend you to get familiar with bundler.
Bundler is used for "bundling" the required gems you use, to so do you have to install the gem (gem install bundler) and then you create a Gemfile, like this:
source 'https://rubygems.org'
ruby '2.2.0'
gem 'colorize', git: 'https://github.com/fazibear/colorize.git'
gem 'psych'
Execute bundle install after, that will create Gemfile.lock file, make sure you push both files to your repository.
With that you would be able to bundle exec ./your-script.rb, assuming your script is something like this:
require 'psych'
require 'colorize'
# Here I do stuff with psych and colorize

Execute without `bundle exec` via rubygems-bundler

I have a standard gem scaffold, and in inside the bin directory I have a simple executable (bin/do_things.rb):
#!/usr/bin/env ruby
require 'my_gem'
MyGem::doThings()
The gem hasn't been installed via gem install, so running bin/do_things.rb without bundle exec fails (my Gemfile has the gemspec line in it).
Is there a simple way to have rubygems-bundler execute my script in the bundler context? Should I just modify the $LOAD_PATH in my executable instead?
I could create a wrapper script to execute under Bundler as well, but I'd rather leverage rubygems-bundler somehow.
Or should I just type bundle exec?
try:
bundle exec bash -l
it will set you into bundler context - it's an extra shell so running exit will get you back to bundler less context.
Change the file permission
chmod a+x bin/do_things.rb
and resolve bin path, ignoring symlinks
require "pathname"
bin_file = Pathname.new(__FILE__).realpath
post, add self to libpath
$:.unshift File.expand_path("../../lib", bin_file)
Generating binstubs via bundle install --binstubs creates a wrapper script for all executables listed in my gemspec.
#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'do_things.rb' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path('my_gem', 'do_things.rb')
However, by default, the binstubs path is bin, which conflicts with gem's executable path, and will overwrite files in bin.
Running bundle install --binstubs=SOME_DIR and then adding SOME_DIR to .gitignore seem to be the most maintainable way.
Then, I can simple execute SOME_DIR/do_things or any other project-specific executable I add down the line.

Bundler: how to use without rails?

I have a project using cucumber outside of rails. How can I load the gems with the versions specified in my gemfile?
Digging through the Bundler website:
Create Gemfile (run bundle init to create skeleton Gemfile)
bundle install
In your app:
# Only needed for ruby 1.8.x
require 'rubygems'
# The part that activates bundler in your app
require 'bundler/setup'
# require your gems as usual
require 'some_gem'
# ...or require all the gems in one statement
Bundler.require
Could be worth checking out:
Bundler.io - Using Bundler in Your Appplication
Bundler.io - Bundler.setup and Bundler.require
Are bundle exec and require 'bundler/setup' equivalent?
I just learned about a way to make Bundler automatically require dependencies from a Gemfile. Add this code at the beginning of a Ruby program that has a Gemfile:
require 'rubygems'
require 'bundler/setup'
Bundler.require
With Bundler.require there's no need to explicitly require the gems/libraries enumerated in the Gemfile.
This solution is from http://technotales.wordpress.com/2010/08/22/bundler-without-rails/
To be honest I'm not sure if the require rubygems part is needed either.
Here's the simplest and most straightforward approach:
bundler init will create the Gemfile for you
Specify gems in the Gemfile.
Add the following to your main Ruby file
require 'bundler/setup'
Bundler.require
Run bundler install to install the gems.
More information can (now) be found at http://bundler.io.
Casper has a pretty good answer (despite some passive aggressiveness) but I think the missing piece for you is bundle exec. When you run the $ rails ... commands on the command line, Rails uses bundler to load those dependencies/gems. Rake, for example, doesn't by default so in order to run rake test using an older version of cucumber than what is on your system, you have to use bundle exec rake test. It's a good habit to get into always using $ bundle exec ... when you're using Bundler — it's explicit, you're always sure you're using the right gems, and it ensures you don't forget to add a dependency to your Gemfile (i.e. you push to another server or another developer and they are having issues because you didn't note the need for something you use but they don't).

Resources