puppetlabs/puppet — pull request #1516 by technicalpickles (2013-03-04 04:51:13+00:00)
Title: (#17616) Clean Bundler environment to fix gem package provider when run under bundler

*Note:* This is reworked from #1488, based on feedback from @adrienthebo

When puppet (or anything for that matter) is invoked with bundler,
bundler 'infects' the environment in order to make sure any subprocesses
get the same rubygems environment. In most cases, this is a boon, but is
a bane when trying to install rubygems via puppet.

The problem happens because the Bundler environmentment changes affect
the `gem` commands used by the gem package provider, to make any
dependencies of a gem to be installed appear as though they don't exist
anywhere. For example, the `foreground` gem depends on mixlib-cli, and
throws errors when using this simple command:

bundle exec puppet apply -e 'package { foreground: ensure => latest, provider => gem }'

The error is:

err: /Stage[main]//Package[foreground]/ensure: change from absent to latest failed: Could not update: Execution of '/Users/andy/.rvm/rubies/ruby-1.8.7-p358/bin/gem install --include-dependencies --no-rdoc --no-ri foreground' returned 1: ERROR:
Error installing foreground:
foreground requires mixlib-cli (~> 1.2.2)
INFO: `gem install -y` is now default and will be removed
INFO: use --ignore-dependencies to install only the gems you list at line 1

The way to uninfect the environment is to use a method provided by Bundler
called `with_clean_env`, which lets you call code in block with those
environment variables removed. This patch adds a `bundled_environment`
feature to detect when bundler is available, and updates the gem package
provider to override `Puppet::Provider`s execute methods to wrap the call
with `Bundler.with_clean_env` if running in a `bundled_environment`.