Bundler not installing private gem from git repo - ruby

I am having trouble creating a private gem, pushing it to a private git repo, and then USING that gem in my Gemfile via a :git reference.
The problem is that bundler (while giving no error) doesn't seem to install the gem for me.
I found that I can demonstrate this with any gem, not just mine. So I'm going to demonstrate it using the 'colorize' gem since it is already on github and rubygems, and is a simple gem that has no dependencies. Here is my test.rb file that uses the gem:
require 'colorize'
puts 'some blue text'.colorize(:blue)
CASE ONE (this works):
The Gemfile is as follows:
source 'https://rubygems.org'
gem 'colorize'
Bundle runs happily, and ruby test.rb outputs the blue text just fine.
I then run gem uninstall colorize to clean up before the next test.
CASE TWO (fails):
Now, I change the Gemfile to this:
#source 'https://rubygems.org'
gem 'colorize', :git => 'git#github.com:fazibear/colorize.git'
Note that I commented out the rubygems.org line to be sure I don't accidentally get the gem from rubygems.
Bundle again runs just fine, and can be seen to get the gem from the repo. So far so good. But now, ruby test.rb fails: require cannot load 'colorize'. It would seem that the gem didn't get installed, and indeed if I run gem uninstall colorize to clean up, it says that colorize is not installed!
So what am I doing wrong here, or failing to understand? I want to have the gem installed from a git repo, not rubygems, since the gem is a private gem.
Thanks,
-- Glenn

It seems to me your ssh connection to github is not setup properly.
Try doing a ssh -T git#github.com as suggested here on github, this will give you an error if things are misconfigured. Follow the steps mentioned in the link and then check again, things should work fine then. FWIW, I tried and was able to install the gem in this fashion.
If you were installing this gem on a server, run this command on the server itself.
An alternative to overcome this (the limitation of configuring ssh keys for each account to use git#github.com url in :git) is to instead use a https url (Check out this thread); this however beats all the purpose of using ssh keys.

Of course the gem isn't installed in second case, that is correct, since it was removed. But when bundler clones a git repo, or to use a path key to create a gem, it doesn't use ruby's gem utility, and to know weither the gem is installed successfully you have just to run, and to see the path of the installed gem:
$ bundle show colorize
/home/user/.rvm/gems/ruby-~.~.~#irb/gems/colorize-~.~.~
If case the gem isn't properly installed, you shell see:
Could not find gem 'colorize'.
And will have to issue bundle install again, and trap errors if any.
Since the bundler doesn't call the gem command, doesn't put the checked out gems from git repos or GitHub into common gem pull, and instead of it creates the gem itself inside its pull, and controls it. You should run your script using the bundler itself:
$ bundle exec ./test.rb
or
$ bundle exec ruby test.rb

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...)

Where does Bundler install gems pulled from Github?

I want to put a debugger in a file for testing, but can't find where Bundler installs gems pulled from Github on my local machine.
I've looked at this thread http://bundler.io/v1.5/git.html which shows how to setup a local file repo to pull from, but I would rather avoid this as my situation is a one off debugging scenario.
I use rbenv for my ruby and gem management. When I pull in a gem from a git repo, it places the files for the gem here:
/usr/local/var/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/bundler/gems/gem-name-SHA/
On my machine bundler installed the gem in:
~/.rvm/gems/ruby-2.3.3/bundler/gems/gem-from-github
gem which [GEM] doesn't work on its own, but bundle exec gem which [GEM] does.

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.

How could I install Gems from git repositories?

I need to install gem form git repository. repository contains .gemspec file. In my gem file i have following code:
gem 'echo_server', :git => 'http://127.0.0.1/org/echo_server.git'
When i am running bundle install gems are installer in .bundeler and not showing in gem list.
my question is:
How the gem will be available in system, so that i can use in require ?
There are some similar SOQ but it does't help me.
It is not showing up when you type gem list because it is not being installed like a regular gem. You can require it like you would any other library because Bundler knows about it and will set it up for you. You should see it in your $LOAD_PATH:
$LOAD_PATH.grep(/nameofgem/)
See the Bundler documentation on this for more information.
If instead you want to install it as a regular gem from the Git repository, you can clone the repository and then build and install the generated gem. For example:
gem build echo_server.gemspec
gem install echo_server-X.Y.Z.gem
There is also specific_install.

Bundler does not install from stash private repo, but reports that it does

My bundle file doesn't appear to be pulling down a gem from a private repository properly.
Inside of my Gemfile, I have:
group :internal do
gem 'private', git: 'ssh://git#internalserver.org:<port>/gems/private.git'
end
This runs, and verbose logging produces:
Updating ssh://git#internalserver.org:<port>/gems/private.git
Cloning into '/Users/<username>/.rvm/gems/ruby-2.0.0-p247/bundler/gems/private-ddec73caf50f'...
done.
When I navigate to /Users/<username>/.rvm/gems/ruby-2.0.0-p247/bundler/gems/, I see the correct repository cloned properly, with a gemspec with the correct name.
When bundler is finished running, gem list does not show the private gem. It produces an error when I attempt to require it.
I tried deleting the Gemfile.lock file in the repository and rerunning, and that did not work. All of the public gems in the Gemfile install correctly.
Relevant version numbers / software:
Bundler version 1.3.5
rvm 1.23.14
ruby 2.0.0p247
Atlassan Stash
Git gems are a Bundler-specific extension to Rubygems. The gem command does not know about these, so they're not listed by gem list. You can run bundle show to see the list of gems that are recognised by Bundler, which will include git gems.
To require the gem, you'll need to be sure that the load path is set up correctly by Bundler. There are three ways to do this:
Call require 'bundler/setup' in your app. This is typical for Rails apps. More on Bundler.setup
Call bundle exec <command> to run the command. This is more common when running commands from a gem, such as rake or rspec. More on bundle exec
Create binstubs for commands that you run frequently.
See http://bundler.io/v1.5/git.html for more information on git gems.

Resources