为什么私人仓库需要* .rb文件才能创建自定义gem?

时间:2019-08-19 22:15:43

标签: ruby rubygems bundler

我有一个项目的代码,我试图将其制作成一个存储在私有git repo中的gem,以便我们可以在其他项目中重复使用它。

即使gem存储了代码,但似乎仍需要包含代码的* .rb文件。对我来说,这似乎是多余的,因为* .rb文件现在都在gem的repo和gem本身中。那,或者我的Gemfile /捆绑器设置错误。

假设我制作了这个文件:

~/code/holaPrj$ cat > hola.rb 
class Hola

self.say(lang: :en)
end
end

...然后我制造了宝石:

~/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

我将此宝石复制到我的〜/ tmp /中,然后解压缩它。我可以在文件系统中看到文件:

~/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

因此,*。gem文件将包含有问题的红宝石文件

将此gem和gemspec文件复制到内部发布的回购中:

~/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

已添加到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'

然后我们安装它:

 ~/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.

...并且捆绑包知道它在哪里:

~/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

加载irb和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>'

这是我期望的。

让我们添加.rb文件:

 ~/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

...并让我们将gem版本升级到0.0.2,只是为了确保我们知道我们有一个新的gem版本(尽管我认为在bunlder中的哈希或Gemfile.lock就足够了):

~/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

转到导入项目importMyGem,我更新为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!

*。rb文件现在位于:

$ ls /usr/local/rvm/gems/ruby-2.3.1/bundler/gems/hola-5b37daed4c3a
hola-0.0.1.gem  hola.gemspec  lib

并且irb可以找到文件:

~/tmp/importMyGem$ rvm default do bundle exec irb
2.3.1 :001 > require 'hola'
 => true

那么,如果我的私人git repo要求* .rb文件是自己的* .rb文件副本以供导入项目查找* .rb文件,那么在* .gem文件中包含* .rb文件又有什么意义呢?或者说,我的捆绑程序或Gemfile设置有问题吗?

1 个答案:

答案 0 :(得分:1)

*.gem文件实际上只是一个zip文件,其中包含您gem的内容(源代码和其他元数据)。

这也是一个构建工件,开发人员通常不检入仓库,因为它可以从源代码中复制出来。实际上,*.gem归档文件的内容是gem的源代码,因此检入该文件将重复存储库的内容。

因此,当Bundler实现从git源安装gems时(gem install命令本身不支持此功能),它会required the git repo to include the source code and a .gemspec file。由此,它实际上将构建一个*.gem文件,然后使用gem install安装该文件。未设置Bundler,并且不希望回购中有*.gem个文件。

因此,您应该做的是检入源代码,而不要检入*.gem文件。