I have code from a project I am trying to make into a gem stored in a private git repo so we can re-use it in other projects.
Even though the gem stores the code, the *.rb files containing the code seem to be required. This would seem redundant to me as the *.rb files are now both in the repo of the gem and the gem itself. That, or my Gemfile / bundler setup is wrong.
Let's say I make this file:
~/code/holaPrj$ cat > hola.rb
class Hola
self.say(lang: :en)
end
end
... and I build the gem:
~/code/holaPrj$ cat hola.gemspec
Gem::Specification.new do |s|
s.name = 'hola'
s.version = '0.0.1'
s.date = '2019-08-14'
s.summary = "Custom gem in private repo testing"
s.authors = ["Julien Lamarche"]
s.email = ["jlam@credil.org"]
s.files = ["lib/hola.rb"]
s.license = 'Nonstandard'
end
~/code/holaPrj$ rvm default do gem build hola.gemspec
WARNING: no homepage specified
WARNING: See http://guides.rubygems.org/specification-reference/ for help
Successfully built RubyGem
Name: hola
Version: 0.0.1
File: hola-0.0.1.gem
I copy this gem to my ~/tmp/, then unpack it. I can see the files in the file system:
~/code/holaPrj$ cp hola-0.0.1.gem ~/tmp/
'hola-0.0.1.gem' -> '/home/jlam/tmp/hola-0.0.1.gem'
~/code/holaPrj$ cd ~/tmp/
lusk 16:33:18 ~/tmp$ rvm default do gem unpack hola-0.0.1.gem
Unpacked gem: '/home/jlam/tmp/hola-0.0.1'
lusk 16:33:28 ~/tmp$ ls hola-0.0.1/lib/hola.rb
hola-0.0.1/lib/hola.rb
Thus, it is esblish that a *.gem file will contain the ruby files in quesation.
Copying this gem and the gemspec file into a repo for internal publication:
~/code/holaPrj$ cp hola-0.0.1.gem ../holaGem/
'hola-0.0.1.gem' -> '../holaGem/hola-0.0.1.gem'
~/code/holaPrj$ cp hola.gemspec ../holaGem/
'hola.gemspec' -> '../holaGem/hola.gemspec'
~/code/holaPrj$
~/code/holaGem$ git add *
~/code/holaGem$ git commit -am "adding the gem and gemspec file"
[master (commit racine) 9c7807c] adding the gem and gemspec file
2 files changed, 11 insertions(+)
create mode 100644 hola-0.0.1.gem
create mode 100644 hola.gemspec
~/code/holaGem$ git remote add origin git+ssh://$ourServer/gems/hola
~/code/holaGem$ git push origin master
Décompte des objets: 4, fait.
Delta compression using up to 8 threads.
Compression des objets: 100% (4/4), fait.
Écriture des objets: 100% (4/4), 1.54 KiB | 0 bytes/s, fait.
Total 4 (delta 0), reused 0 (delta 0)
To git+ssh://$ourServer/gems/hola
* [new branch] master -> master
Added in Gemfile:
~/tmp/importMyGem$ cat Gemfile
source 'https://rubygems.org'
git_source(:our_gems){ |repo_name| "git+ssh://$ourServer/gems/#{repo_name}" }
gem 'hola', our_gems: 'hola'
Then we install it:
~/tmp/importMyGem$ rvm default do bundle install
Warning, new version of rvm available '1.29.9-next', you are using older version '1.29.3'.
You can disable this warning with: echo rvm_autoupdate_flag=0 >> ~/.rvmrc
You can enable auto-update with: echo rvm_autoupdate_flag=2 >> ~/.rvmrc
Fetching git+ssh://$ourServer/gems/hola
Fetching gem metadata from https://rubygems.org/
Resolving dependencies...
Using bundler 2.0.2
Using hola 0.0.1 from git+ssh://$ourServer/gems/hola (at master@9c7807c)
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
... and bundle knows where it is:
~/tmp/importMyGem$ rvm default do bundle info hola
* hola (0.0.1 9c7807c)
Summary: Custom gem in private repo testing
Path: /usr/local/rvm/gems/ruby-2.3.1/bundler/gems/hola-9c7807c88e90
~/tmp/importMyGem$ ls /usr/local/rvm/gems/ruby-2.3.1/bundler/gems/hola-9c7807c88e90/
hola-0.0.1.gem hola.gemspec
Loading up irb and the gem:
~/tmp/importMyGem$ rvm default do bundle exec irb
2.3.1 :001 > require 'hola'
LoadError: cannot load such file -- hola
from (irb):1:in `require'
from (irb):1
from /usr/local/rvm/rubies/ruby-2.3.1/bin/irb:11:in `<top (required)>'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/cli/exec.rb:74:in `load'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/cli/exec.rb:74:in `kernel_load'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/cli/exec.rb:28:in `run'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/cli.rb:465:in `exec'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/cli.rb:27:in `dispatch'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/cli.rb:18:in `start'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/exe/bundle:30:in `block in <top (required)>'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/lib/bundler/friendly_errors.rb:124:in `with_friendly_errors'
from /usr/local/rvm/gems/ruby-2.3.1/gems/bundler-2.0.2/exe/bundle:22:in `<top (required)>'
from /usr/local/rvm/gems/ruby-2.3.1/bin/bundle:23:in `load'
from /usr/local/rvm/gems/ruby-2.3.1/bin/bundle:23:in `<main>'
from /usr/local/rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `eval'
from /usr/local/rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `<main>'
This I would have expected to work.
Lets add the .rb files:
~/code/holaGem$ cp -r ../holaPrj/lib ./
'../holaPrj/lib' -> './lib'
'../holaPrj/lib/hola.rb' -> './lib/hola.rb'
~/code/holaGem$ ls
hola-0.0.1.gem hola.gemspec lib
~/code/holaGem$ git add lib/
~/code/holaGem$ git commit -am "adding the .rb files of the gem"
[master 1c6ee59] adding the .rb files of the gem
1 file changed, 7 insertions(+)
create mode 100644 lib/hola.rb
~/code/holaGem$ git push origin master
Décompte des objets: 4, fait.
Delta compression using up to 8 threads.
Compression des objets: 100% (3/3), fait.
Écriture des objets: 100% (4/4), 381 bytes | 0 bytes/s, fait.
Total 4 (delta 1), reused 0 (delta 0)
To git+ssh://$ourServer/gems/hola
9c7807c..1c6ee59 master -> master
... and lets upgrade the gem version to 0.0.2 just to make sure we know we have a new gem version (though I suppose the hash in bunlder or the Gemfile.lock would suffice):
~/code/holaGem$ cat hola.gemspec
Gem::Specification.new do |s|
s.name = 'hola'
s.version = '0.0.2'
s.date = '2019-08-14'
s.summary = "Custom gem in private repo testing"
s.authors = ["Julien Lamarche"]
s.email = ["jlam@credil.org"]
s.files = ["lib/hola.rb"]
s.license = 'Nonstandard'
end
~/code/holaGem$ vi hola.gemspec
~/code/holaGem$ git commit -am "wo#15499 - project .rb files added"
[master 87742bc] wo#15499 - project .rb files added
1 file changed, 1 insertion(+), 2 deletions(-)
lusk 17:51:38 (master) ~/code/holaGem$ git push origin master
Décompte des objets: 3, fait.
Delta compression using up to 8 threads.
Compression des objets: 100% (3/3), fait.
Écriture des objets: 100% (3/3), 366 bytes | 0 bytes/s, fait.
Total 3 (delta 1), reused 0 (delta 0)
To git+ssh://$ourServer/gems/hola
1c6ee59..87742bc master -> master
Going to the importing project, importMyGem, I update to 0.0.2!
~/tmp/importMyGem$ rvm default do bundle update
Fetching git+ssh://$ourServer/gems/hola
Fetching gem metadata from https://rubygems.org/
Resolving dependencies...
Using bundler 2.0.2
Using hola 0.0.2 (was 0.0.1) from git+ssh://$ourServer/gems/hola (at master@87742bc)
Bundle updated!
The *.rb files are now there:
$ ls /usr/local/rvm/gems/ruby-2.3.1/bundler/gems/hola-5b37daed4c3a
hola-0.0.1.gem hola.gemspec lib
And irb can find the file:
~/tmp/importMyGem$ rvm default do bundle exec irb
2.3.1 :001 > require 'hola'
=> true
So what's the point of having *.rb files inside the *.gem file if my private git repo requires it's own copy of the *.rb files for the importing project to find the *.rb files? Or rather, is there something wrong with my bundler or Gemfile setup?
A *.gem
file is really just a zip file that contains the contents (source code and other metadata) of your gem.
It is also a build artifact that developers don't usually check into a repo as it can be reproduced from the source code. And indeed, the contents of the *.gem
archive are the source code of the gem, so checking it in would be duplicating the contents of the repo.
For that reason, when Bundler implemented installing gems from a git source (the gem install
command itself doesn't support this) it required the git repo to include the source code and a .gemspec
file. From this it will actually build a *.gem
file and then install it with gem install
. Bundler is not set up and doesn't expect there to be a *.gem
file in a repo.
So, what you should do is check in the source code and not the *.gem
file.