How to add executable to path on gem install with rubygems? - ruby

I've created a program that I want to bundle into a gem that will add the executable located in the bin directory to the path. I'm wondering if there is something inside the gemspec that I have to set to make this happen, or if it's something else. I want to be able to use gem install gem_name and it will add the executable to the path. How do I do this?

Declare the executables in the gemspec file:
Gem::Specification.new do |s|
s.name = 'hola'
s.version = '0.0.1'
s.executables << 'hola'
end
http://guides.rubygems.org/make-your-own-gem/#adding-an-executable

Related

Building gem, executable not found

I'm in the process of writing my first ruby gem and I'm a little new at the whole structure of setting up gems. My understanding from reading this guide is that in order to create an executable for my gem I need to do the following:
Add a line to my gemspec specifiying the name of the executable like this:
s.executables << 'gemname'
Build the gem with
gem build gemname.gemspec
Install the gem locally (if you try to install by pushing to rubygems each time you'll end up having to change versions constantly) with
gem install gemname-0.0.1.pre.gem
Then test it out with
gemname foo-arguments, --bar-options
If I go through all these steps then on #4 I get the following error:
$ gemname
zsh: command not found: gemname
Assuming that the executable a file starting with a shebang and located at gemname/bin/gemname
Everything works just fine if I navigate to the root of the gem folder and run bin/gemname to test out the executable.
Here is a gist of my current gemspec and the gem source is available on github here.
You need to add all the files that need be included with the gem in spec.files. You missed to add the files that you have in the bin directory.
For example, I have the following configuration from one of my gems:
Gem::Specification.new do |spec|
spec.files = Dir["{bin,lib}/**/*", "LICENSE", "README.md"]
spec.test_files = Dir["spec/**/*"]
spec.require_paths = ["lib"]
spec.executables = ["yarr"]
end
Your gemspec is trying to change the load path. I would suggest fixing that first, because what you're reporting seems to be consistent with a gem not being able to find its files.
Look at your gemspec for this code:
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
Then see http://guides.rubygems.org/patterns/
"Gems should not change the $LOAD_PATH variable. RubyGems manages this for you. Code like this should not be necessary ..."
See http://guides.rubygems.org/patterns/ for various solutions to load using the existing load path, and helpers such as require_relative.
In addition you need to ensure your executable is, well, executable.
$ chmod a+x bin/gemname
Otherwise the command won't be available after building the gem.

What are `files`, `executables`, `test_files`, and `require_paths` in gemspec file?

I am not clear on what certain specifications in the .gemspec file are doing. Specifically,
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
Can someone explain how these relate to the functionality of a Ruby Gem and why they are necessary?
executables:
Executables included in the gem. For example, the rake gem has rake as an executable. These files must be executable Ruby files.
files:
Files included in the gem. These are the files that will be included in your gem when it is built.
require_paths:
Contains an Array of directories and files which should be added to the $LOAD_PATH on gem activation. By default it is ["lib"].
test_files
Test files included in the gem.

How to make a Ruby gem executable

I can use gems like RSpec or Rails or Pry by calling their respective gem names, e.g. rspec, rails, pry on the commandline. How can I achieve this with gems I create? I'm using bundler for the basic gem creation.
I actually had my executable in the /bin folder.
Turns out my issue was that bundler's gem template is too smart for it's own good, and only includes files that have been committed to git. I hadn't actually committed the executable yet, so it wasn't picking it up:
# gemname.gemspec
gem.files = `git ls-files`.split($\)
According to documentation of Gemspec file you must put your executable in bin/ folder.
To make your gem executable in CLI, you should set the followings up.
Place your executable file the bin folder, like bin/hello
Make that executable by set permissions (chmod u+x bin/hello)
Set up gemspec configuration accordingly (hello.gemspec)
spec.files = `git ls-files -Z`.split("\x0")
spec.bindir = 'bin'
spec.executables << 'hello'
spec.executables considers bin as default folder for binaries and executables, though you can change it.
You can find documentation about this here: Gemspec#executables.

Created a simple gem, but irb can't see it

I created a simple gem by doing:
testgem.gemspec
Gem::Specification.new do |s|
s.name = 'testgem'
s.version = '0.0.1'
s.summary = "code generation"
s.authors = ['asdf']
end
created the following file layout:
testgem.gemspec
Gemfile
lib/
lib/testgem.rb
lib/testgem/other.rb
ran the following:
gem build testgem.gemspec
WARNING: no description specified
WARNING: no email specified
WARNING: no homepage specified
Successfully built RubyGem
Name: testgem
Version: 0.0.1
File: testgem-0.0.1.gem
installed it:
gem install ./testgem-0.0.1.gem
Successfully installed testgem-0.0.1
1 gem installed
tested to see if irb can see it:
irb
require 'testgem'
oadError: cannot load such file -- testgem
I'm using Ruby 1.9.3-p194
It seems to be installed if I do:
gem list
..
testgem (0.0.1)
..
What could be the issue?
You need to add your lib to the search path. Just add
$:.push File.expand_path("../lib", __FILE__)
on top of your .gemspec
When you use require in Ruby, you are trying to load a file, not a gem. The file could of course be contained in a gem, and by convention a gem will have a file with the same name as the gem itself so that if you wanted to use the gem foo you would use require 'foo'. This isn’t always the case though, for example to use the bcrypt-ruby gem you need to require 'bcrypt'.
Additionally a gem doesn’t necessarily have to contain any filles at all. An example of this is the rails gem, which doesn’t contain any files itself (at least in version 3.2), but has dependencies to the various Rails components, so that you can install them all in one step.
In your case, although you have a lib/testgem.rb file in your gems project directory, you are not including it in your gem. You need to specify which files should be included, the default is to not include anything.
To simply include all the files in your project directory, you can add something like:
s.files = Dir.glob '**/*'
to your gemspec.
You need to require 'rubygems' first.

Requiring files in executables in a gem

I am building a gem using ruby 1.9.3 and bundler 1.1.3. In my gemspec, I use the executables method to specify that `bin/curd" is executable:
Gem::Specification.new do |gem|
...
gem.executables = ["curd"]
...
end
The gem source directory has a bin and a lib directory:
bin/
curd
lib/
curd.rb
The bin/curd file uses code defined in lib/curd, but I haven't been able to properly require it.
How can I require the lib/curd file so that when the gem is installed, bin/curd can see it?
Add to bin/curd:
require 'curd'
This will require curd gem after installation.

Resources