How to pick gems from a specific directory - ruby

I forked a gem I use a lot in order to code some enhancements on it. I want it to be installed in a subfolder called ~/codebase/ruby, where I keep all my Ruby projects, arranged in subdirectories.
To do that, I built and installed the gem with the following commands:
gem build my_gem.gemspec
gem install mygem-x.x.gem -i./mygem
mygem is installed in ~/codebase/ruby/mygem. I can't get my client code (which is in another directory) to grab mygem from there.
I've tried all of the following without success:
Running ruby with argument -I<path_to_mygem>.
Adding <path_to_mygem> to PATH.
Putting :gempath: <path_to_mygem> into ~/.gemrc.
I know I could put the gem in ~/.gem/ruby/<version> (since it appears in gem env) and that would probably work, but that would break my existing directory structure of Ruby code, forcing me to code in a different directory only for mygem, which is something I want to avoid unless it's the only option.
Thoughts?

Hopefully you are using Bundler to load the required gems. Then you just specify the path to the gem file in your Gemfile:
gem 'my_gem', :path => '~/codebase/ruby/mygem'

Related

Can't install gem using Bundler's Rakefile install task when developing a custom gem

I'm developing a couple of private gems and I think I don't understand correctly the PATH/GEM_PATH and/or Bundler/RVM installation flow, would love if someone could chip in.
I have a repository with two gems (A & B for simplicity sake). I've developed the gems using the scaffolding + following the guidelines provided by this bundler tutorial.
Thanks to the Bundler project I have a few Rakefile tasks like rake build, rake install, rake install:local and rake release. Because of the private nature of these gems I can't release them to RubyGems (and we haven't looked into hosting our rubygems).
My machines are using RVM to manage ruby versions and Bundler version 1.15.1
What I want to do: Assuming a new machine/developer trying out the project, ideally we would cd into each of the subfolders (currently 2, gem A and gem B), run rake install and after that we should have the gems available system wide for the current user.
What is happening: The gems are built and work properly, but they are only available inside the subfolder of each gem i.e. gem A is only available inside the subfolder A and gem B is only available inside subfolder B.
What I've tried: So, after rake build/install/install:local a new .gem file is generated under pkg. I've tried to manually install the "compiled" file using gem install pkg/A.gem, gem install --local pkg/A.gem and gem install --local --user-install pkg/A.gem without success. (there are plenty of SO questions/answers about this)
I believe this has something to do with the PATH variables, but like I said before I don't fully understand the way they are managed. I get the following results from these commands:
# Our gem
> gem which A
/home/ubuntu/.rvm/gems/ruby-2.4.0/gems/A-0.1.8/lib/A.rb
# Pry, available globally
> gem which pry
/home/ubuntu/.rvm/gems/ruby-2.4.0/gems/pry-0.11.1/lib/pry.rb
I've been lost and frustrated for far too long now, any help is appreciated. Also open to hear suggestions of better private gem installation flows :)
Yes, it has something to do with your PATH variables. Your installation seems to be good.
I advise you to first affirm your gems installation path with:
echo $GEM_HOME
The double check your PATH to ensure its present and also confirm that the GEM home is also where the gem got installed into from the rake install
echo $PATH
If not, put it in your path and you should be fine with something like this:
echo PATH=$PATH:$GEM_HOME >> ~/.bashrc
source ~/.bashrc
Build your gem as per that guide you linked. You should end up with a gem file. Distribute this as you see fit (I use rsync/crontab to download newer gem versions but anything goes). User can install the gem as follows:
gem install --user-install /path/to/your/file.gem
This will install the gem in the user's ~/.gem/ruby/<version>/gems/<your-gem-name> directory.
Tried it with an empty gem (foodie, as in that example guide) and it works fine. But if you don't specify the --user-install parameter it will try to install in the system ruby dir (/usr/lib/ruby/gems...)

Calling another Gem as a program from my Gem

I'm working on a command line tool (a ruby gem) to quickly and easily generate custom jekyll repositories from some basic user input for my company. I would like to add a feature where the gem can automatically build the repo and output the finished directory, but the jekyll gem doesn't seem to provide any internal ruby interface to do that, at least not one that would be easy to implement.
Is there a way I could have my gem call their gem as a program, i.e. system 'jekyll build', but without having to worry about whether or not the user has the jekyll gem installed?
You can add jekyll to your gems list of dependencies, by adding the following to your gem's .gemspec file. That means whenever someone installs your gem, jekyll would also be installed.
spec.add_dependency 'jekyll'

How to contribute to a Ruby Gem

I am trying to contribute to a Ruby gem and I don't understand how to test a local gem without using a globally installed gem.
The gem I want to contribute to is a command line interface gem. I clone the gem into a directory then cd into that directory. However, when I run commands in the terminal when I'm in the cloned project directory it still uses the global gem. I've even run
gem uninstall gemname
then while inside the newly cloned gem directory I redo
gem install gemname.
No matter what changes I make to the gem, I can't see the results or what my contributions are doing because it's always running the global gem.
When I do try to type a command line command that is supposed to interact with the gem while in the cloned gem directory I get:
-bash: ~/.gem/ruby/2.1.0/bin/githubrepo: No such file or directory
I've done a ton of research but I'm just not getting it. Help?
gem install gemname will look for a .gem file in the current directory. If not found it will look for it on the web.
gem install --local /path/to/your/gemname.gem will allow you to target a particular directory. You may need to gem build gemname.gemspec first, so it has your changes.
Instead of doing this, I would write tests in the gem directory itself. It's likely that when running code in there, you can simply require 'gemname' in Ruby to get the gem functionality.
If it's a well-written gem, it should have tests already. They will most likely be in a directory called test or spec. Have a look at these tests and try to carry on in that style to test your changes. This will make your code changes far far more likely to be accepted as a pull request.

Local gem repository? Install a ruby gem without 'gem'?

Is it possibile to have something like a 'local' gem repository for Ruby?
I'm working on a custom Linux distribution without admin rights. Ruby is installed on the machine (v.1.8.7) but apparently no 'gem' or 'bundle' or whatever are installed. I need to use some Ruby gems like Nokogiri.
Is it possible to use Ruby gems without installing them through gem install?
Yes. Any gem can be used standalone. You just have to either download the source from github, or download the gem and extract its contents manually.
After you've done that you have to add the lib folder of the gem into the load path ($:) of Ruby. For example:
$:.unshift(File.expand_path("nokogiri-1.6.1/lib"))
require 'nokogiri'
Assuming you are running Ruby in the current directory and the Nokogiri source is in the folder nokogiri-1.6.1.
But remember that first you have to do the same with all Nokogiri prerequisites. I.e. all the libraries Nokogiri depends on.
Another option, which is what I would do, is to install RubyGems in your home directory. That can get a little bit tricky though, but it's possible by downloading the RubyGems package and running something like:
ruby setup.rb --prefix=/home/my_user_name/rubygems
Then you need to set up the ENV variables GEM_HOME and GEM_PATH to point to a location in your home directory where you want all your gems to be installed. See "What's the difference between GEM_HOME and GEM_PATH?" for a description of what they do.
You will also need to add something like /home/my_user_name/rubygems/bin to your PATH so that the gem command can be found by the shell.

How to refer a local gem in ruby?

I pack some ruby code into a gem. I want to refer the code in the gem in some other code.
So in the Gemfile I specify the gem's name, version, and local path. Like:
gem 'gemname','0.x', :path => 'RELATIVE_PATH_TO_GEM_FILE'
After bundle install, I see
Using gemname (0.x) from source at RELATIVE_PATH_TO_GEM_FILE
But when I run the code, it can't find the code in the gem. LOAD_PATH shows ABSOLUTE_PATH_TO_GEM_FILE/lib.
No wonder it can't find the code, there's only gem file under ABSOLUTE_PATH_TO_GEM_FILE. it's not unpacked. So there's no lib directory.
if I gem install that gem file into my system, then all works fine. I can see the gem file was unpacked into source code files.
But my question is if it can refer the local gem file directly somehow?
No, you can't refer to a .gem file directly.
In your terminology, you need to use an "unpacked" gem.
:path => '/foo/bar/'
where /foo/bar/ is a (gem) directory with lib/, etc.
We made a local (not system-wide) gems location. We set these environment variables:
GEM_HOME=/path/to/rubygems-1.3.4
RUBYLIB=/path/to/rubygems-1.3.4/lib/
By setting those, we can then do 'gem install ...' to put the built gem into that directory, and ruby knows where to find them.

Resources