Gemfile.lock应该通过依赖优先级而不是字母顺序排序

时间:2016-05-23 15:26:09

标签: ruby rubygems chef rake bundle

由于我们无法访问rubygems网站,因此我们计划通过Chef cookbook在本地解决宝石及其依赖性。我们想在这个过程中添加一个rakefile。 我们在Rakefile中遵循的过程如下

  1. 使用正确的版本(inspec)创建Gemfile
  2. 捆绑安装
  3. 得到Gemfile.lock< == 这是问题所在。它按字母顺序排序
  4. 我们需要按顺序创建一个具有依赖关系的数组,这样就不会在循环中安装gems。这个数组是将流程自动化到未来版本所必需的。
  5. 创建的数组遵循按字母顺序排列,在安装过程中会产生错误。

    我们拥有的Gemfile

    source 'https://rubygems.org'
    
    gem "inspec", "0.22.1"
    

    当我们运行"捆绑安装"创建Gemfile.lock如下:

    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
    

    Rake文件:

    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
    

    结果:

    '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 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
    

    让我知道是否有任何替代/简单的解决方案来解决此问题,或者指导我为此过程创建正确的Rakefile。

2 个答案:

答案 0 :(得分:0)

要像45个步骤一样快退,那么您需要镜像所需的宝石(https://github.com/rubygems/rubygems-mirror),然后在localhost上使用gem serve来安装它们。这似乎少了很多工作。

至于你的实际问题:你可以尝试询问Bundler维护者,但我可以保证他们会将问题关闭超出范围,因为这不是锁文件的用途。

答案 1 :(得分:0)

我找到了另一种解决方案。

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