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



由于我们无法访问rubygems网站,我们计划通过Chef食谱在本地解决gems及其依赖关系。我们希望在此过程中添加一个rakefile。我们在Rakefile中遵循的流程如下

  1. 创建具有正确版本的Gemfile(inspec)
  2. 捆绑安装
  3. 获取Gemfile.lock<==问题出在这里。它按字母顺序排序
  4. 我们需要创建一个具有依赖关系的数组,这样在循环中安装gem就不会发生冲突。此阵列是将流程自动化到未来版本所必需的

创建的数组遵循字母顺序,这会在安装过程中导致错误。

我们的Gemfile

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

当我们运行"bundle install"时,会创建一个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

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

结果:

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

要倒带45步,不如镜像您需要的宝石(https://github.com/rubygems/rubygems-mirror)然后使用localhost上的CCD_ 2来安装它们。这似乎少了很多工作。

至于你的实际问题:你可以试着问Bundler的维护人员,但我可以向你保证,他们会以超出范围的方式解决这个问题,因为这不是锁定文件的用途。

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

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

最新更新