11

This is happening in Puppet's bundle.

The Gemfile specifies

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

But one of the gems I installed in $GEM_HOME appears in $: after all.

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

This is not a problem in and of itself, but apparently Ruby will load Puppet 3.7.5 instead of the 3.7.3 I checked out of the git repo.

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

Why is Puppet not loaded from the git tree and how can I debug this further?

Update

Puppets .gemspec might be involved. It's clever about specifying the version. I now worry that Rubygems does in fact load the installed 3.7.5 gem so that Puppet.version would truthfully report a wrong value, throwing off bundler. Could that be what's happening?

Update 2

As suggested in the comments, I tried settings the path and version statically in the Gemfile.

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

As for the result, well - at least bundler is consistent in its views ;-)

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.
Felix Frank
  • 8,125
  • 1
  • 23
  • 30
  • What version of bundler are you using? This sounds like a known issue with bundler about 2 tagged releases ago. – Chase Apr 20 '15 at 19:30
  • @ChaseGilliam I can reproduce with bundler `1.7.4` and `1.9.4`, unfortunately. – Felix Frank Apr 22 '15 at 05:58
  • Try giving it an absolute path like gem "puppet", :path => "/home/puppy/puppet-git-clone" – Chase Apr 22 '15 at 12:03
  • @ChaseGilliam same effect. I prodded around using `bundle update --verbose` and will update the question with a minor finding. – Felix Frank Apr 22 '15 at 15:20
  • Reporting the version that way is fairly typical, I doubt that's the issue. Maybe try specifying the version in the gemfile. – Chase Apr 22 '15 at 16:41
  • @ChaseGilliam I did, and updated the question again. Thanks for the feedback so far! – Felix Frank Apr 24 '15 at 09:55
  • The Gemfile.lock could have been created when it was messed up, and be locking you to the wrong one. Might try backing it up, then regenerating, being sure that this dir isn't in the path. Alternatively, you could probably edit it by hand (always worked well for me ;) – Joshua Cheek Apr 27 '15 at 04:13
  • Have you tried removing the other gem? And what's the path situation really? I see both `/home/puppy` and `/home/ffrank` ... if you could post a gist of all this that'd be great. – digitalextremist Apr 27 '15 at 05:13
  • @digitalextremist Bah, sorry for mixing up paths. I was reproducing using two accounts, yes. Removing the gem *does* help, but my goal is to not have to. Will check out the approach from your answer. Will also give mucking around with `Gemfile.lock` another try, as @JoshuaCheek suggests. – Felix Frank Apr 27 '15 at 11:54
  • I actually have the exact problem you're talking about now. Awesome. – digitalextremist Apr 30 '15 at 04:12

6 Answers6

4

The quick fix is to add -Ilib to your ruby command:

$ 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

If we compare the load paths, you can see that adding -Ilib results in 3.7.5 not being present in the second load path:

$ 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

It seems like this should be the default behavior, so there may be a bug in bundler.

Nick Urban
  • 3,568
  • 2
  • 22
  • 36
  • 1
    I like the simplicity of it. When not calling `ruby` directly, this will also do it: `RUBYLIB=lib bundle exec puppet agent --version`. - But then this workaround feels redundant. I'll take it if no other answer works. – Felix Frank May 01 '15 at 20:36
1

Provided you've deleted your Gemfile.lock and removed all other versions of the gem before trying bundle exec ... although not explicitly defined by the same problem, this is a known problem with Bundler check this out:

And it ought to be fixed as of this merged Pull Request:

This will cause your "preferred source" to be favored, and used.

( Links used as answer because this refers to existing activities, not a solution I could put here in the answer. Not link-only answer. )

digitalextremist
  • 5,952
  • 3
  • 43
  • 62
  • Good call, I have a creeping suspicion that the `hiera` gem, which depends on the `puppet` gem is somehow involved. However, applying that patch to bundler `1.9.4` does not resolve the issue. Removing `Gemfile.lock` is ineffective. The `3.7` gem was **not** removed. This whole problem does not exist if no gem with a different version is installed. – Felix Frank Apr 29 '15 at 20:58
  • Sorry to hear this answer is not the one. Posted another I thought of after having similar problems. – digitalextremist Apr 29 '15 at 21:07
1

try this :

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

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

why do you need require false?

WebQube
  • 8,510
  • 12
  • 51
  • 93
1

After what you said in my previous answer, try this:

Add gemspec to your Gemfile near the top.

If you do this, the subsequent gem ... calls will override the gemspec which is ultimately setting the version.

Add it right here:

source ENV['GEM_SOURCE'] || "https://rubygems.org"
gemspec # and let me know if this fixes it
digitalextremist
  • 5,952
  • 3
  • 43
  • 62
  • Interesting. Still broken, but now I get this warning: `lib/puppet/version.rb:10: warning: already initialized constant PUPPETVERSION`, from the file in the git repo. – Felix Frank May 01 '15 at 20:38
  • Thanks for all the effort, but as there was no resolution, I cannot award you the cup in fairness. Better luck next time! – Felix Frank May 03 '15 at 00:09
1

Like I recently said, I found the same problem you had, in my own projects. And I've solved it by a workaround. The idea itself is what I'm giving here, I'm not saying it's the most efficient or bug-free way. A variation of this approach worked for me.

It involves hijacking Gemfile and perhaps gemspec, depending on what's the offender in reality -- that part is still unknown. My most recent answer, the second approach I gave could solve this already. If not, you may need a workaround. There are many standing impasses for Bundler.


As a work around, insert a curator.

I suggest, at the end of Gemfile you insert a processor such as this one, to curate Bundler::Dsl yourself. We can focus completely on the gem you're looking to resolve, but it could be done for any and all gems.

For example... this is mostly a concept, it may run, but it may have a bug. You will need to harden it. This will remove everything but the version you expect:

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

I'm not sure which version you actually want. There are three versions mentioned, 3.7.3, 3.7.5 ... just plug in the one you do want. Any other versions will be purged from the dependencies Bundler is working with.

digitalextremist
  • 5,952
  • 3
  • 43
  • 62
1

I had the same problem in past, I think you can specify your gem without the 'require: false' parameter and it will look for the Gemfile specific version.

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

If you specify the 'require' option with 'gem' and run the irb command with bundle exec irb it always load the latest version for the gems which has declared with require: false option.

meOn
  • 194
  • 1
  • 12
  • This is basically the answer from WebQube. Doing this does not help at all. `bundler` insists that `Source contains 'puppet' at: 3.7.3` – Felix Frank May 02 '15 at 12:58