Add ruby script in gem to path - ruby

I just created a very simple rubygem which has only one file that takes a couple of parameters.
I want to automatically add this ruby script to the path when I install it so that i can use it from anywhere in terminal like:
myruby "param1" "param2"

Have a look at this documentation from RubyGems.
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. First create the file and make it executable:
This article also seems to be pretty good and it covers the essential details of adding an executable.

Related

Creating Ruby gems with same name executables?

I want to have a Ruby Gem that will have the same executable as another Gem.
When called with command args it will either do something, or pass the command on to the other Gem.
The first problem I have is that it isn't able to run two same named executables. I get this error:
Bundler is using a binstub that was created for a different gem. This is deprecated, in future versions you may need to bundle binstub yourgem to work around a system/bundle conflict.
How can I have Gems with the same named executables and ensure that the target one executes?
You cannot rely on Bundler or Rubygems to manage this for you. All it does it copy an executable that you specified in your gem spec to its bin/ directory.
The first problem you'll have is that the executable that runs may be dependent on the order in which the gems were installed which you can't guarantee.
Another problem that you'll have is that you cannot execute code on gem installation so you will be unable to run code that would try to automate this set up for people who install your gem.
I believe your gem should provide a non-conflicting executable. You can then supply post install instructions in your gem spec that are displayed to a user installing the gem, in the README, in a blog post, etc. you can tell the user that they need to set up an alias that points to your executable. In all shells that I'm aware of aliases will be executed before filesystem executables.
For the times when people want to bypass your alias and execute the original executable you can tell people to escape the command, e.g. \original-gem. That bypasses alias and function lookup in most shells and will allow users to have your super awesome version as the default (thru the alias) and a way to easily access the original.

How to require ruby gem from a specific location?

I am new to ruby, and is trying to write a git hook in ruby. I want to use the rugged gem in my script. The gem is already available in /opt/gitlab/embedded/service/gem/ruby/2.1.0/ as part of GitLab installation (Files List). How can I require that gem in my script?
I have tried $LOAD_PATH.unshift "/opt/gitlab/embedded/service/gem/ruby/2.1.0/" and then require "rugged", as mentioned in another stackoverflow answer, but it did not work.
Look carefully at how $LOAD_PATH is configured for each gem after you include it. Normally it's the full path to where the base gemname.rb is located, like in your case where rugged.rb is.
The way the $LOAD_PATH works is it scans through that list looking for rugged.rb and if it doesn't find it, moves on to the next possible location. You're specifying a directory which doesn't have that, so find the right path and fill that in, and you should be good.

How to make my ruby script shippable

I want to ship a ruby script and not ask the end consumer to run gem install or some bundler command. I just wants him to open the zip and run my script.
I understand that I will need to bundle my gems inside my zip but I am not sure how it can be achieved.
Today I am using bundler with the following .bundle/config:
---
BUNDLE_PATH: lib/vendor/bundle
BUNDLE_DISABLE_SHARED_GEMS: '1'
BUNDLE_FROZEN: '1'
and I do some nasty manipulation on library search path, in the beginning of my script:
$:.unshift File.dirname(__FILE__) + "/vendor/bundle/ruby/2.0.0/gems/colored-1.2/lib"
To conclude, What is the right way to create a statically linked (without external dependencies) ruby shippable script?
You're on the right track. You might want to look at bundle install --standalone, which generates a file that does all of the necessary load path manipulation.
http://myronmars.to/n/dev-blog/2012/03/faster-test-boot-times-with-bundler-standalone

How to I load a gem from source?

I have git cloned a repo from Github, now I want to experiment with it, as in I want to poke around the code and mess with it. I've created a file test.rb that should load this gem, but I want to load my locally checked out version, what's the right way to do this?
Right now I'm just using a bunch of "require_relative 'the_gem_name/lib/file'", which feels wrong.
When you require 'foo' Ruby checks all the directories in the load path for a file foo.rb and loads the first one it finds. If no file named foo.rb is found, and you’re not using Rubygems, a LoadError is raised.
If you are using Rubygems (which is likely given that it is included in Ruby 1.9+), then instead of immediately raising a LoadError all the installed Gems are searched to see if one contains a file foo.rb. If such a Gem is found, then it is added to the load path and the file is loaded.
You can manipulate the load path yourself if you want to ensure a particular version of a library is used. Normally this isn’t something that’s recommended, but this is the kind of situation that you’d want to do it.
There are two ways of adding directories to the load path. First you can do it in the actual code, using the $LOAD_PATH (or $:) global variable:
$LOAD_PATH.unshift '/path/to/the/gems/lib/'
require 'the_gem'
Note that you normally want to add the lib dir of the gem, not the top level dir of the gem (actually this can vary depending on the actual Gem, and it’s possible to need to add more than one dir, but lib is the norm).
The other way is to use the -I command line switch to the ruby executable:
$ ruby -I/path/to/the/gems/lib/ test.rb
This way might be a bit cleaner, as normally you don’t want to be messing with the load path from inside your code, but if you’re just testing the library it probably doesn’t matter much.
Following apneadiving's suggestion in the comments, I created a Gemfile and added this line
source "http://rubygems.org"
gem 'gem_name', path: '~/path/to/gem/source/folder'
Then bundle install, and bundle exec ruby test.rb and it worked.

Rubygem Executable $LOAD_PATH Issues

I'm writing an IDE in Ruby, and I'm stumped on how to get all my files to get "required" when I run the program on the command line, AND when its installed as a Rubygem.
My Rubygem has an executable file named "vr" in it. I need to make this "vr" executable file "require" all the other files from my project.
When I'm developing, its easy to require all my project's files. I simply "require" a relative path to them like this:
require_all Dir.glob(File.expand_path(File.dirname(__FILE__)) + "/../bin/**/*.rb")
The require_all gem will work perfectly. However, I get a big problem when I install this program as a rubygem. When my "vr" executable is installed by rubygems, it copies the "vr" executable to a special directory:
/home/eric/.rvm/gems/ruby-1.9.3-p125/bin
This directory is totally separated from my project's root folder. And so all my project's files are no longer found by the "require" statement.
Rubygems makes this directory for my gem's root:
/home/eric/.rvm/gems/ruby-1.9.3-p125/visualruby-0.0.55
I need to be able to "require" all the files from that directory into my project.
My solution so far, is to make a second file called "visualruby.rb" that resides in my project's lib folder. It has the require_all statement in it to require all the project files. Then I just have to link the executable to it by adding this code to my "vr" executable file:
base_file = File.dirname(__FILE__) + '/lib/visualruby.rb'
if File.file?(base_file)
require base_file #load from project
else
require 'visualruby.rb' #load from gem
end
It is necessary to check if there's a file named "visualruby.rb" relative to the current file because when I'm developing, it will always find the installed gem's version of "visualruby.rb" So when I make a change to a file, it has no effect. I have to force it to load the version from my development project for changes to work.
Also, my IDE creates projects from scratch, so it would be nice to know the general solution to this. I'd like to have a consistent project file system for all projects, but I'm not sure that's possible. I had the general solution of making a file called "requires.rb" for all projects, but I don't think it will work because every project will have the same filename added to the $LOAD_PATH.
Please help me understand how I can make a consistent file structure where I can develop, and make rubygems.
I found the answer to my own question:
The problem was that I was installing my rubygems using the rubygems API:
Gem::Installer.new(file_name)
This created syslinks that messed up my paths. There is an option to make wrappers instead of syslinks and that seems to be the standard way to install:
Gem::Installer.new(file_name, :wrappers => true)
Now the a wrapper is copied to my gem's bin directory and it uses the correct path. Now I can have a universal file that can be made into a gem. And everything runs the same in development and in the gem.
A happy ending...

Resources