Why is the executable not loading my cli file - ruby

I am following the gem guide in the bundler documentation.
when i reached the command line part where i have to require 'foodie/cli' on the executable, i keep getting error.
/Users/suyesh/.rbenv/versions/2.3.3/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- foodie/cli (LoadError)
from /Users/suyesh/.rbenv/versions/2.3.3/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from exe/foodie:2:in `<main>'
here is my code in the executable
#!/usr/bin/env ruby
require 'foodie/cli'
Foodie::CLI.start
here is my cli which is in lib/foodie/cli.rb
require 'thor'
require 'foodie'
module Foodie
class CLI < Thor
desc "portray ITEM", "Determines if a piece of food is gross or sdeliciour."
def portray(name)
puts Foodie::Food.portray(name)
end
end
end
What am i doing wrong?

Depending on how you call your executable and how your paths are set up it should work (tm).
Use bundle exec path/to/my/executable in your development environment (assuming you are writing a gem - which is nearly always a good idea). If you followed the other steps in the Bundler tutorial I believe you should have a gemspec file which tells bundler where to look for ([lib/]foodie/cli.rb).
Use ruby -Iinc/lude/dir/for/example/lib path/to/my/executable to tell your ruby to (temporarily) also look in the directory inc/lude/dir/for/example/lib for source files (in your case foodie/cli.rb). Since you are learning bundler, dont use this approach, but it might be interesting to others, and to cast some light in the area where lib-, load- and include-paths live.

Related

After adding a Ruby Gem to a Gemfile and running bundle exec file.rb, I still get a file not found error

This is in my Gemfile:
gem "trinsic_service_clients", "~> 1.1"
This is at the top of my file named instantiate_clients.rb
require_relative 'trinsic_service_clients
However, when I run bundle exec ruby instantiate_clients.rb I still get this error:
Traceback (most recent call last):
1: from instantiate_clients.rb:1:in `<main>'
instantiate_clients.rb:1:in `require_relative': cannot load such file -- /home/runner/DefenselessGrowlingExtraction/trinsic_service_clients (LoadError)
When I type bundler exec gem which trinsic_service_clients I get the following:
/home/runner/DefenselessGrowlingExtraction/.bundle/ruby/2.5.0/gems/trinsic_service_clients-1.1.5018/lib/trinsic_service_clients.rb
require_relative is for code in your application. It is not for code stored in gems. For those you should use require as it will look through $LOAD_PATH for the required files.
The easy way to make use of Gemfile is to load everything in via one shot:
require 'bundler'
Bundler.require(:default)
This not only adds the gem declarations, but does default require calls as well, as in this should already require your declared gem.
There's also require 'bundler/setup' which only adds the load paths, you still need to require, but this can help minimize load times if you may not necessarily need all the gems.
require 'bundler/setup'
require 'trinsic_service_clients'
This can be useful if your Gemfile has a lot of dependencies, but the scripts you're running may only use a small subset of them.

why lib/pp.rb requires lib/pp/room which does not exist

I am trying to create gem using bundler. This gem requires pp gem to make 'pretty print'. I have require 'pp' at the top of the source and after that I use pp where needed. However, a runtime error occurs.
D:/PRJ/git/smde/vendor/bundle/ruby/2.5.0/gems/pp-0.1.1/lib/pp.rb:1:in `require': cannot load such file -- pp/room (LoadError)
There is no room file in lib/pp directory in pp gem. Why?
What is more interestingly, pp gem works well when I start my gem scripts directly, i.e. "ruby myscript.rb". The lack of pp/lib/room is not essential.
The "pp" gem is not required for using pretty print. That gem is related to Campfire, which does have the concept of a room. See https://www.rubydoc.info/gems/pp/0.1.1/Pp
Pretty print is available to you without requiring anything: notice if you run irb, you can immediately type
pp "something"
And it will print as you want.

Ruby script cannot load a gem installed via bundler

I am trying to include the ruby-mysql gem in my ruby script. I have installed the gem using bundler but when I run bundle exec ./mysql_connector, I receive the error ./mysql_connector:4:in ``require': cannot load such file -- ruby-mysql (LoadError). Can you please help me troubleshoot what the problem is?
What I did
Installed rails in my home directory.
I do not have root access to the server so I have installed rails in my local directory by following the instructions here:
http://www.r-bloggers.com/installing-ruby-on-linux-as-a-user-other-than-root/
Created a directory for my application.
My application resides in my home directory in a folder called connector. It has a Gemfile that looks like this:
source 'https://rubygems.org'
gem 'ruby-mysql'
Call bundle install.
Using ruby-mysql 2.9.14
Using bundler 1.11.2
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Bundled gems are installed into ./vendor/bundle.
Add dependencies to my script. My script is in connector/mysql_connector and it reads:
#!/home/dcox/bin/ruby
require 'rubygems'
require 'bundler/setup'
require 'ruby-mysql'
Make script executable. I saw that you need to run bundle exec using an executable file, so I followed the instructions here to make my script executable: http://commandercoriander.net/blog/2013/02/16/making-a-ruby-script-executable/
Run the script. I execute using bundle exec mysql_connector and see:
/home/dcox/bin/mysql_connector:4:in `require': cannot load such file -- ruby-mysql (LoadError)
from /home/dcox/bin/mysql_connector:4:in `<main>'
Is it the $LOAD_PATH? After searching around for answers, I discovered a lot of SO answers as well as a blog post (https://codedecoder.wordpress.com/2013/09/23/require-and-load-in-ruby-loaderror-cannot-load-such-file/) that seem to suggest the problem is that the gem is not installed in a directory on the $LOAD_PATH. Here is what I see when I run $LOAD_PATH from IRB:
irb(main):002:0> $LOAD_PATH
=> ["/home/dcox/lib/ruby/site_ruby/2.1.0",
"/home/dcox/lib/ruby/site_ruby/2.1.0/x86_64-linux",
"/home/dcox/lib/ruby/site_ruby", "/home/dcox/lib/ruby/vendor_ruby/2.1.0",
"/home/dcox/lib/ruby/vendor_ruby/2.1.0/x86_64-linux",
"/home/dcox/lib/ruby/vendor_ruby", "/home/dcox/lib/ruby/2.1.0",
"/home/dcox/lib/ruby/2.1.0/x86_64-linux"]
Next I checked to see the location of ruby-mysql:
dcox#analytics1:~/connector$ bundle show ruby-mysql
/data/home/dcox/connector/vendor/bundle/ruby/2.1.0/gems/ruby-mysql-2.9.14
Obviously my connector/vendor/bundle path is not on the $LOAD_PATH. I could add it, but I have a feeling I am missing something simple here because bundler is supposed to work as long as you follow the instructions, right?
Any advice or help is very much appreciated! Thanks!!
If you just want to require this specific gem, require 'mysql' should work (e.g., https://github.com/tmtm/ruby-mysql/blob/master/test/test_mysql.rb#L10).
Your file should call Bundler.setup http://bundler.io/bundler_setup.html
Better yet, if you instead call Bundler.require(:default) it will setup and require all the gems in your Gemfile for you.

How do command line utility gems work?

How do gems like "rails", "rspec", and "cucumber" allow user to use commands that start with their gem name??
rails new project
rspec spec
cucumber features
Not all gems have this ability. For example, when I type json even though I have it installed, I get
-bash: json: command not found
Gem's .gemspec file looks like this:
Gem::Specification.new do |s|
s.name = "haml"
s.version = "3.1.8"
....
s.executables = ["haml", "html2haml"]
end
This means that when installing this Gem (haml-3.1.8 in this case) also links to executables (also called "binstubs") will be created for the files haml and html2haml which are found inside the gem's bin/ directory.
In this case, for example the file bin/haml could look like:
#!/usr/bin/env ruby
require 'rubygems'
require 'haml'
puts Haml::VERSION
From rubygems.org documentation on building Gems:
In addition to providing libraries of Ruby code, gems can also expose
one or many executable files to your shell’s PATH. Probably the best
known example of this is rake. Another very useful one is
prettify_json.rb, included with the JSON gem, which formats JSON in a
readable manner (and is included with Ruby 1.9).
[...]
Adding an executable to a gem is a simple process. You just need to
place the file in your gem’s bin directory, and then add it to the
list of executables in the gemspec. Let’s add one for the Hola gem.
[...]
The executable file itself just needs a shebang in order to figure out
what program to run it with.
[...]
All it’s doing is loading up the gem, and passing the first command
line argument as the language to say hello with.
These gems have binaries that can be executed from the CLI. Most gems do not need this functionality and only provide code extensions.
Edit: They may not be 'binaries'. They can be just executable Ruby code as well. Thanks #holger

OSX Ruby Gems Add to ruby path?

I am just starting to learn ruby. It seems that the default gems install path is not part of Ruby. Is this normal behavior? How can I set the default ruby path? Example:
[11:53:33]wuntee:/Library/Ruby/Gems/1.8/gems/packetfu-1.0.0/examples$ sudo ruby arphood.rb
Fetching the oui.txt from IEEE, it'll be a second. Avoid this with arphood.rb <filename>.
arphood.rb:30:in `require': no such file to load -- packetfu (LoadError)
from arphood.rb:30:in `arp_everyone'
from arphood.rb:51
As you can see packetfu is installed in /Library/Ruby/Gems/1.8/gems/, but ruby cant find it...
that's because you're not in the directory where packetfu.rb file lies and there's no require 'rubygems' to add the gems paths in your script

Resources