为什么私有存储库需要 *.rb 文件用于自定义 gem?

Why private repo requires *.rb file for a custom gem?

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

尽管 gem 存储了代码,但似乎需要包含代码的 *.rb 文件。这对我来说似乎是多余的,因为 *.rb 文件现在都在 gem 和 gem 本身的回购协议中。那,或者我的 Gemfile / bundler 设置错误。

假设我制作了这个文件:

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

self.say(lang: :en)
end
end

... 我构建了 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

我把这个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文件将包含问题.

中的ruby个文件

将此 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.

... 并且 bundle 知道它在哪里:

~/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 存储库需要它自己的 *.rb 文件副本以供导入项目查找,那么在 *.gem 文件中包含 *.rb 文件有什么意义*.rb 文件?或者更确切地说,我的捆绑器或 Gemfile 设置有问题吗?

*.gem 文件实际上只是一个 zip 文件,其中包含 gem.

的内容(源代码和其他元数据)

它也是一个构建工件,开发人员通常不会将其签入存储库,因为它可以从源代码中复制。事实上,*.gem 存档的内容是 gem 的源代码,因此签入它会复制 repo 的内容。

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

因此,您应该检查源代码而不是 *.gem 文件。