Почему провайдер использует более одного места для создания драгоценных камней?

Это происходит в пакете Puppet's.

Gemfile указывает

gem "puppet", :path => File.dirname(__FILE__), :require => false

Но один из камней, которые я установил в $GEM_HOME, появляется в $: в конце концов.

$ bundle exec ruby -e 'puts $:'
...
/home/puppy/puppet-git-clone/lib
...
/usr/lib/ruby/vendor_ruby
...
/home/puppy/gems/gems/puppet-3.7.5/lib
...

Это не проблема сама по себе, но, по-видимому, Ruby будет загружать Puppet 3.7.5 вместо 3.7.3, который я проверил из репозитория git.

$ bundle exec irb
irb(main):001:0> require 'puppet'
=> true
irb(main):002:0> Facter.value(:puppetversion)
=> "3.7.5"

Почему Puppet не загружается из дерева git и как я могу отлаживать это дальше?

Update

Могут быть задействованы куклы .gemspec. Это умный об определении версии. Теперь я беспокоюсь, что Rubygems фактически загружает установленный 3.7.5 драгоценный камень, так что Puppet.version правдиво сообщает неправильное значение, отбрасывая связующее. Может быть, что происходит?

Обновление 2

Как было предложено в комментариях, я попытался установить путь и версию статически в Gemfile.

gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone", :require => false

Что касается результата, то, по крайней мере, bundler является последовательным в его представлениях; -)

Could not find gem 'puppet (= 3.4.2) ruby' in source at /home/ffrank/git/puppet.
Source contains 'puppet' at: 3.7.3
Run `bundle install` to install missing gems.

Ответ 1

Быстрое исправление заключается в добавлении -Ilib к вашей рубиновой команде:

$ bundle exec ruby -e "require 'puppet'; puts Facter.value(:puppetversion)"
3.7.5

$ bundle exec ruby -Ilib -e "require 'puppet'; puts Facter.value(:puppetversion)"
3.7.3

Если мы сравниваем пути загрузки, вы можете видеть, что добавление -Ilib приводит к тому, что 3.7.5 не присутствует во втором пути загрузки:

$ diff <(bundle exec ruby -e 'puts $:') <(bundle exec ruby -Ilib -e 'puts $:') | grep 'puppet-'
< /Library/Ruby/Gems/2.0.0/gems/puppet-3.7.5/lib

Кажется, что это должно быть поведение по умолчанию, поэтому может быть ошибка в bundler.

Ответ 2

Если вы удалили свой Gemfile.lock и удалили все другие версии драгоценного камня, прежде чем пытаться bundle exec... хотя это явно не определено одной и той же проблемой, это известная проблема с Bundler проверить это:

И это должно быть исправлено с этого объединенного запроса Pull:

Это приведет к тому, что ваш "предпочтительный источник" будет одобрен и использован.

(Ссылки используются как ответ, потому что это относится к существующим видам деятельности, а не к решению, которое я мог бы поставить здесь в ответ. Не ответ только для ссылок.)

Ответ 3

попробуйте следующее:

source "file://home/puppy/puppet-git-clone"

gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"

зачем вам нужно false?

Ответ 4

После того, что вы сказали в моем предыдущем ответе, попробуйте следующее:

Добавьте gemspec к Gemfile вверху.

Если вы сделаете это, последующие вызовы gem ... переопределяют gemspec, который в конечном итоге устанавливает версию.

Добавьте его прямо здесь:

source ENV['GEM_SOURCE'] || "https://rubygems.org"
gemspec # and let me know if this fixes it

Ответ 5

Как я недавно сказал, я нашел ту же проблему, что и у меня, в моих собственных проектах. И я решил это обходным путем. Сама идея - это то, что я даю здесь, я не говорю об этом как о самом эффективном или без ошибок. Вариант этого подхода работал у меня.

Он включает захват Gemfile и, возможно, gemspec, в зависимости от того, что нарушитель в действительности - эта часть еще неизвестна. Мой последний ответ, второй подход, который я дал, может решить это уже. Если нет, вам может понадобиться обходной путь. Есть много постоянных тупиков для Бундлера.


Как работа, вставьте куратор.

Я предлагаю, чтобы в конце Gemfile вы вставляли процессор, такой как этот, чтобы курировать Bundler::Dsl самостоятельно. Мы можем полностью сосредоточиться на драгоценном камне, который вы хотите решить, но это может быть сделано для любых драгоценных камней.

Например... это в основном концепция, она может работать, но может иметь ошибку. Вам нужно будет ожесточить его. Это приведет к удалению всего, кроме ожидаемой версии:

PUPPET_VERSION = 'version desired'
until(current = self.dependencies.find { |d| d.name == 'puppet' }) == 1
    current.each { |gem|
        if !gem.version == PUPPET_VERSION
            self.dependencies.delete(current)
        end
    }
end

Я не уверен, какую версию вы действительно хотите. Существует три версии: 3.7.3, 3.7.5... просто подключите ту, которую вы хотите. Любые другие версии будут удалены из зависимостей, с которыми работает Bundler.

Ответ 6

У меня была такая же проблема в прошлом, я думаю, что вы можете указать свой драгоценный камень без параметра "require: false", и он будет искать конкретную версию Gemfile.

gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"

Если вы укажете опцию "require" с "gem" и запустите команду irb с помощью bundle exec irb, она всегда загружает последнюю версию для драгоценных камней, которая объявила с опцией require: false.