Search code examples
windowsrakebundlerberkshelfalbacore

Bundler error when executing berks command from a rake task on windows


I wrote a rake task to execute the berks package command on a Berksfile in a sub-directory:

task :cook do
  `berks package ./cookbooks.tar.gz -b ./cookbook/Berksfile`
end

I've also tried these variations:

task :cook do
  `.\\scripts\\berks_package.bat` # containing stuff
end

task :cook do
  `C:\\opscode\\chefdk\\embedded\\bin\\ruby.exe "C:\\opscode\\chefdk\\bin\\berks" package ..\\cookbooks.tar.gz -b ..\\cookbook\\Berksfile`
end

No matter the way I execute berks, the task fails with the following error:

C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/resolver.rb:434:in `version_conflict': Bundler could not find compatible versions for gem "nokogiri": (Bundler::VersionConflict)
  In snapshot (Gemfile.lock):
    nokogiri (1.6.5)

  In Gemfile:
    albacore (~> 2.0.0) x86-mingw32 depends on
      nokogiri (~> 1.5) x86-mingw32

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/resolver.rb:232:in `resolve_for_conflict'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/resolver.rb:250:in `resolve_conflict'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/resolver.rb:373:in `resolve'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/resolver.rb:166:in `start'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/resolver.rb:129:in `resolve'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/definition.rb:193:in `resolve'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/definition.rb:132:in `specs'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/definition.rb:177:in `specs_for'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/definition.rb:166:in `requested_specs'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/environment.rb:18:in `requested_specs'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/runtime.rb:13:in `setup'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler.rb:122:in `setup'
        from C:/tools/ruby213/lib/ruby/gems/2.1.0/gems/bundler-1.7.9/lib/bundler/setup.rb:17:in `<top (required)>'
        from C:/opscode/chefdk/embedded/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        from C:/opscode/chefdk/embedded/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:54:in `require'
rake aborted!
Albacore::CommandFailedError: Command failed with status (1):
  .\scripts\berks_package.bat

Executing berks package ./cookbooks.tar.gz -b ./cookbook/Berksfile from a command prompt works as does executing other normal system commands inside the task.

Gemfile:

source 'https://rubygems.org'
gem 'albacore', '~> 2.0.0'
gem 'semver2', '~> 3.4.0'

Gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    albacore (2.0.16)
      map (~> 6.5)
      nokogiri (~> 1.5)
      rake (~> 10)
      semver2 (~> 3.4)
    map (6.5.5)
    mini_portile (0.6.1)
    nokogiri (1.6.5-x64-mingw32)
      mini_portile (~> 0.6.0)
    rake (10.4.2)
    semver2 (3.4.0)

PLATFORMS
  x64-mingw32

DEPENDENCIES
  albacore (~> 2.0.0)
  semver2 (~> 3.4.0)

Solution

  • I figured out the problem as I wrote the question and stumbled upon new ideas.

    The root problem was that the Ruby binary and gems installed with the ChefDK were conflicting with the system install of Ruby. Specifically, the rake task was executed under the system Ruby installation, but when berks was executed, it ran under the embedded ChefDK Ruby. I'm not clear on this next part, but it seems that the ChefDK Ruby was aware of the Gemfile and tried to resolve the dependencies itself, but because nokogiri cannot be resolved (i.e. built) by bundler on Windows without pain, it failed.

    Here is what I did to resolve the issue:

    1. Uninstalled the system Ruby
    2. Added C:\opscode\chefdk\bin to the system PATH variable so I could run ruby, rake, gem, bundle, etc.
    3. Ran gem install nokogiri (now executed under the ChefDK's Ruby)
    4. Recreated the Gemfile.lock file by running bundle install
    5. Surrounded the berks system call with a Bundler.with_clean_env block (this is key!)

    The task now looks like:

    task :cook do
      Bundler.with_clean_env do
        `berks package cookbooks.tar.gz -b .\\cookbook\\Berksfile`
      end
    end