解析 Gemfile.lock 文件的直接和间接 Gem
Parsing direct and indirect Gems of Gemfile.lock file
我正在尝试解析以下 Gemfile.lock 以包含 GEM 规范中的所有 Gem(直接和间接依赖项):
GEM
remote: http://rubygems.org/
specs:
coderay (1.1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
http-accept (1.7.0)
http-cookie (1.0.4)
domain_name (~> 0.5)
json (2.5.1)
method_source (1.0.0)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0704)
netrc (0.11.0)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
yaml (0.1.1)
PLATFORMS
ruby
x86_64-darwin-20
DEPENDENCIES
json
rest-client
yaml
RUBY VERSION
ruby 2.7.3p183
BUNDLED WITH
2.2.23
但是使用我的函数我只能得到直接依赖而没有间接依赖。
例如:直接依赖: http-cookie (1.0.4)... 间接依赖: domain_name (~> 0.5)
我的代码:
require 'bundler'
def gemlock(file_path)
file = file_path
gemlock_array = []
context = Bundler::LockfileParser.new(Bundler.read_file(file))
# Gems
context.specs.each do |spec|
name = spec.name
version = spec.version.to_s
gemlock_array << {'name' => name, 'version' => version}
end
puts gemlock_array
end
gemlock('Gemfile.lock')
我得到以下哈希值:
{"name"=>"coderay", "version"=>"1.1.3"}
{"name"=>"domain_name", "version"=>"0.5.20190701"}
{"name"=>"http-accept", "version"=>"1.7.0"}
...
如您所见,间接依赖关系 被自动忽略了!但我还是需要得到它。
我没有任何使用捆绑器的经验,也不知道如何解决这个问题。
在此问题上的任何帮助将不胜感激!
提前致谢。
indirect dependencies were automatically ignored
如果您包含完整输出,将会有所帮助。我只是 运行 自己,你会得到:
[{"name"=>"coderay", "version"=>"1.1.3"},
{"name"=>"domain_name", "version"=>"0.5.20190701"},
{"name"=>"http-accept", "version"=>"1.7.0"},
{"name"=>"http-cookie", "version"=>"1.0.4"},
{"name"=>"json", "version"=>"2.5.1"},
{"name"=>"method_source", "version"=>"1.0.0"},
{"name"=>"mime-types", "version"=>"3.3.1"},
{"name"=>"mime-types-data", "version"=>"3.2021.0704"},
{"name"=>"netrc", "version"=>"0.11.0"},
{"name"=>"rest-client", "version"=>"2.1.0"},
{"name"=>"unf", "version"=>"0.1.4"}, # <------ !!!!!!!!!!!!
{"name"=>"unf_ext", "version"=>"0.0.7.7"},
{"name"=>"yaml", "version"=>"0.1.1"}]
所以总而言之,domain_name
的间接依赖,即 unf
,这大概就是您所指的, 包含在 的更下方列表。您的代码已经完全按照您的预期运行。
不过有一个小问题:您可以通过这样做稍微简化实现:
gemlock_array = context.specs.map { |s| {'name' => s.name, 'version' => s.version.to_s} }
在 ruby 中,分配一个临时数组并在 .each
循环中附加到它通常是次优的。使用 map
来直接构造数组。
我正在尝试解析以下 Gemfile.lock 以包含 GEM 规范中的所有 Gem(直接和间接依赖项):
GEM
remote: http://rubygems.org/
specs:
coderay (1.1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
http-accept (1.7.0)
http-cookie (1.0.4)
domain_name (~> 0.5)
json (2.5.1)
method_source (1.0.0)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0704)
netrc (0.11.0)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
yaml (0.1.1)
PLATFORMS
ruby
x86_64-darwin-20
DEPENDENCIES
json
rest-client
yaml
RUBY VERSION
ruby 2.7.3p183
BUNDLED WITH
2.2.23
但是使用我的函数我只能得到直接依赖而没有间接依赖。 例如:直接依赖: http-cookie (1.0.4)... 间接依赖: domain_name (~> 0.5)
我的代码:
require 'bundler'
def gemlock(file_path)
file = file_path
gemlock_array = []
context = Bundler::LockfileParser.new(Bundler.read_file(file))
# Gems
context.specs.each do |spec|
name = spec.name
version = spec.version.to_s
gemlock_array << {'name' => name, 'version' => version}
end
puts gemlock_array
end
gemlock('Gemfile.lock')
我得到以下哈希值:
{"name"=>"coderay", "version"=>"1.1.3"}
{"name"=>"domain_name", "version"=>"0.5.20190701"}
{"name"=>"http-accept", "version"=>"1.7.0"}
...
如您所见,间接依赖关系 被自动忽略了!但我还是需要得到它。
我没有任何使用捆绑器的经验,也不知道如何解决这个问题。 在此问题上的任何帮助将不胜感激!
提前致谢。
indirect dependencies were automatically ignored
如果您包含完整输出,将会有所帮助。我只是 运行 自己,你会得到:
[{"name"=>"coderay", "version"=>"1.1.3"},
{"name"=>"domain_name", "version"=>"0.5.20190701"},
{"name"=>"http-accept", "version"=>"1.7.0"},
{"name"=>"http-cookie", "version"=>"1.0.4"},
{"name"=>"json", "version"=>"2.5.1"},
{"name"=>"method_source", "version"=>"1.0.0"},
{"name"=>"mime-types", "version"=>"3.3.1"},
{"name"=>"mime-types-data", "version"=>"3.2021.0704"},
{"name"=>"netrc", "version"=>"0.11.0"},
{"name"=>"rest-client", "version"=>"2.1.0"},
{"name"=>"unf", "version"=>"0.1.4"}, # <------ !!!!!!!!!!!!
{"name"=>"unf_ext", "version"=>"0.0.7.7"},
{"name"=>"yaml", "version"=>"0.1.1"}]
所以总而言之,domain_name
的间接依赖,即 unf
,这大概就是您所指的, 包含在 的更下方列表。您的代码已经完全按照您的预期运行。
不过有一个小问题:您可以通过这样做稍微简化实现:
gemlock_array = context.specs.map { |s| {'name' => s.name, 'version' => s.version.to_s} }
在 ruby 中,分配一个临时数组并在 .each
循环中附加到它通常是次优的。使用 map
来直接构造数组。