saisureshiva saisureshiva - 6 months ago 26
Ruby Question

Gemfile.lock should sort via dependency priority rather than alphabetical order

Since we don't have access to rubygems website, we are planning to solve the gems and its dependency locally via Chef cookbook. We would like to add a rakefile to this process.
The process we followed in Rakefile is as follows


  1. Create Gemfile with proper version (inspec)

  2. bundle install

  3. Got Gemfile.lock <== Here is the problem. It sorts in alphabetical order

  4. We need to create an array with dependency in order so that it doesn't conflict to install gems in a loop. This array is needed for automating the process to future releases.



The array created follows the alphabetical order which results out an error during installation.

The
Gemfile
we have is

source 'https://rubygems.org'

gem "inspec", "0.22.1"


When we run "bundle install" a Gemfile.lock is created as follows:

GEM
remote: https://rubygems.org/
specs:
builder (3.2.2)
coderay (1.1.1)
diff-lcs (1.2.5)
docker-api (1.26.2)
excon (>= 0.38.0)
json
erubis (2.7.0)
excon (0.49.0)
ffi (1.9.10-x86-mingw32)
gssapi (1.2.0)
ffi (>= 1.0.1)
gyoku (1.3.1)
builder (>= 2.1.2)
hashie (3.4.4)
httpclient (2.8.0)
inspec (0.22.1)
hashie (~> 3.4)
json (~> 1.8)
method_source (~> 0.8)
pry (~> 0)
r-train (~> 0.12)
rainbow (~> 2)
rspec (~> 3)
rspec-its (~> 1.2)
rubyzip (~> 1.1)
thor (~> 0.19)
json (1.8.3)
little-plugger (1.1.4)
logging (2.1.0)
little-plugger (~> 1.1)
multi_json (~> 1.10)
method_source (0.8.2)
mixlib-shellout (2.2.6-universal-mingw32)
win32-process (~> 0.8.2)
wmi-lite (~> 1.0)
multi_json (1.12.0)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (3.1.1)
nori (2.6.0)
pry (0.10.3)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
r-train (0.12.0)
docker-api (~> 1.26.2)
json (~> 1.8)
mixlib-shellout (~> 2.0)
net-scp (~> 1.2)
net-ssh (>= 2.9, < 4.0)
winrm (~> 1.6)
winrm-fs (~> 0.3)
rainbow (2.1.0)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.4)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-its (1.2.0)
rspec-core (>= 3.0.0)
rspec-expectations (>= 3.0.0)
rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
rubyntlm (0.6.0)
rubyzip (1.2.0)
slop (3.6.0)
thor (0.19.1)
win32-process (0.8.3)
ffi (>= 1.0.0)
winrm (1.8.1)
builder (>= 2.1.2)
gssapi (~> 1.2)
gyoku (~> 1.0)
httpclient (~> 2.2, >= 2.2.0.2)
logging (>= 1.6.1, < 3.0)
nori (~> 2.0)
rubyntlm (~> 0.6.0)
winrm-fs (0.4.2)
erubis (~> 2.7)
logging (>= 1.6.1, < 3.0)
rubyzip (~> 1.1)
winrm (~> 1.5)
wmi-lite (1.0.0)

PLATFORMS
x86-mingw32

DEPENDENCIES
inspec (= 0.22.1)

BUNDLED WITH
1.11.2


Rakefile:

require 'bundler'
require 'json/pure'

parsed_Gemfile_lock = Bundler::LockfileParser.new( File.read(File.dirname(__FILE__) + "\\Gemfile.lock"))

# Print a Ruby Array
parsed_Gemfile_lock.specs.each do |spec|
gem_array = spec.to_s.split
gem_name = gem_array[0]
gem_version = gem_array[1]
gem_version = gem_version.gsub(/[()]/,"'")
print "'" + gem_name + "'=>" + gem_version + ", "
end


Result:

'builder'=>'3.2.2', 'coderay'=>'1.1.1', 'diff-lcs'=>'1.2.5', 'docker-api'=>'1.26.2', 'erubis'=>'2.7.0', 'excon'=>'0.49.0', 'ffi'=>'1.9.10', 'gssapi'=>'1.2.0', 'gyoku'=>'1.3.1', 'hashie'=>'3.4.4', 'httpclient'=>'2.8.0', 'inspec'=>'0.22.1', 'json'=>'1.8.3', 'little-plugger'=>'1.1.4', 'logging'=>'2.1.0', 'method_source'=>'0.8.2', 'mixlib-shellout'=>'2.2.6', 'multi_json'=>'1.12.0', 'net-scp'=>'1.2.1', 'net-ssh'=>'3.1.1', 'nori'=>'2.6.0', 'pry'=>'0.10.3', 'r-train'=>'0.12.0', 'rainbow'=>'2.1.0', 'rspec'=>'3.4.0', 'rspec-core'=>'3.4.4', 'rspec-expectations'=>'3.4.0', 'rspec-its'=>'1.2.0', 'rspec-mocks'=>'3.4.1', 'rspec-support'=>'3.4.1', 'rubyntlm'=>'0.6.0', 'rubyzip'=>'1.2.0', 'slop'=>'3.6.0', 'thor'=>'0.19.1', 'win32-process'=>'0.8.3', 'winrm'=>'1.8.1', 'winrm-fs'=>'0.4.2', 'wmi-lite'=>'1.0.0',


Error while executing via chef cookbook:

===============================================================================
Error executing action `upgrade` on resource 'chef_gem[inspec]'
================================================================================

Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '2'
---- Begin output of /opt/chef/embedded/bin/gem install /var/chef/cache/rubygems/inspec-0.22.1.gem -q --no-rdoc --no-ri -v "0.22.1" --local ----
STDOUT:
STDERR: ERROR: Could not find a valid gem 'r-train' (~> 0.12) in any repository
---- End output of /opt/chef/embedded/bin/gem install /var/chef/cache/rubygems/inspec-0.22.1.gem -q --no-rdoc --no-ri -v "0.22.1" --local ----
Ran /opt/chef/embedded/bin/gem install /var/chef/cache/rubygems/inspec-0.22.1.gem -q --no-rdoc --no-ri -v "0.22.1" --local returned 2


Let me know if there are any alternate/easy solution to this issue or guide me out in creating the proper Rakefile to this process.

Answer

I have found an alternate solution.

namespace :gem_attribute_array do
desc 'Generate gems attribute array'
task :generate do
puts "Generating gems attribute array and downloading all the dependent gem packages to ./vendor/cache :"
result = Mixlib::ShellOut.new('bundle package')
result.run_command
result.stdout.split("\n").each do |line|
  if line =~ /Using / or line =~ /Installing / then
    str=line.split(" ")
    gem_name=str[1]
    gem_version=str[2]
    print "'" + gem_name + "'=>'" + gem_version + "', "
  end #if loop
end # foreach loop
puts "\n" #Dummy line
end  #task
end  #namespace
Comments