如何从 extconf.rb 读取 gem 文件规范?
How to read the gem file specifications from extconf.rb?
我正在构建一个 Ruby gem 文件,该文件具有各种第 3 方可执行要求(一些非 ruby 工具,gem 然后将通过系统使用这些工具电话)。
需求列表是使用 gemspec 信息性 requirements
列表指定的,我的任务是创建一个设置,在安装过程中验证该需求列表 - 本质上是转换 requirements
列表从信息丰富到权威。
我最初的方法是使用 extensions
,就像在 extconf.rb
模式中一样,在安装过程中 运行 一些 ruby 代码将验证需求列表和不满足要求安装失败
所以我当前的实现是使用 ext/Rakefile
,它使用硬编码路径读取 gemspec 文件,使用自定义(但直截了当)解析 requirements
列表和简单的)语法和 运行 对所需可执行文件的一些简单测试。
我真的很想排除对 gemspec 文件路径的依赖,这样我就可以在其他项目中以模块化的方式重用代码。
为了完成(并希望它对某人有用),这是我的代码 - 它使用 Gem::Ext::Builder
"Rakefile mode" 只是 运行 一些任意代码。
require 'rubygems'
require 'mkmf'
def verify_requirement(reqspec)
exe, version_spec, version_regex = reqspec.split(/\s*,\s*/,3)
exe = if exe =~ /\[([^\]]+)\]/ # support human readable alias for executable name
abort "Missing required executable #{exe}!" unless find_executable(exe)
return unless version_spec # no version is specified, so executable existing is good enough
version = %x|#{exe} --version 2>&1|.chomp
version = %x|#{exe} -version 2>&1|.chomp unless $?.success?
abort "Error checking for version of #{exe}: (#{$?.exitstatus}) #{version}" unless $?.success?
if version_regex
abort "Version test '#{version_regex}' failed to match '#{version}'!" unless version =~ /#{version_regex}/m
abort "Version test '#{version_regex}' failed to generate a version number!" unless
version =
end
abort "Failed to locate a valid version number for #{exe}, found '#{version}'" unless version =~ /^[0-9\.]+/
abort "Insufficient version '#{version}' for #{exe} - requires #{version_spec}" unless Gem::Dependency.new(exe, version_spec).match? exe, version
end
task :default do
gemspec = File.absolute_path('../my.gemspec')
Gem::Specification::load(gemspec).requirements.each do |req|
verify_requirement(req)
end
end
此代码要求 requirements
使用以下任一语法:
exe-file[, <semantic-version-spec>[, <version-garabbing-regex>]]
alias '[' exe-file ']'[, <semantic-version-spec>[, <version-garabbing-regex>]]
例如:
spec.requirements << 'sox'
spec.requirements << 'ffmpeg, >= 2.5, ffmpeg version ([\d\.]+)'
spec.requirements << 'ImageMagick [convert], >= 6.7.5, ImageMagick ([\d\.]+)'
Gem::Specification
class 可用于加载和解析 gemspec
。我在 ext/Rakefile
中使用以下代码来执行基于 gemspec
文件的任务:
task :default do
gemspec = File.absolute_path('../gemname.gemspec')
Gem::Specification::load(gemspec).requirements.each do |req|
verify_requirement(req)
end
end
我正在构建一个 Ruby gem 文件,该文件具有各种第 3 方可执行要求(一些非 ruby 工具,gem 然后将通过系统使用这些工具电话)。
需求列表是使用 gemspec 信息性 requirements
列表指定的,我的任务是创建一个设置,在安装过程中验证该需求列表 - 本质上是转换 requirements
列表从信息丰富到权威。
我最初的方法是使用 extensions
,就像在 extconf.rb
模式中一样,在安装过程中 运行 一些 ruby 代码将验证需求列表和不满足要求安装失败
所以我当前的实现是使用 ext/Rakefile
,它使用硬编码路径读取 gemspec 文件,使用自定义(但直截了当)解析 requirements
列表和简单的)语法和 运行 对所需可执行文件的一些简单测试。
我真的很想排除对 gemspec 文件路径的依赖,这样我就可以在其他项目中以模块化的方式重用代码。
为了完成(并希望它对某人有用),这是我的代码 - 它使用 Gem::Ext::Builder
"Rakefile mode" 只是 运行 一些任意代码。
require 'rubygems'
require 'mkmf'
def verify_requirement(reqspec)
exe, version_spec, version_regex = reqspec.split(/\s*,\s*/,3)
exe = if exe =~ /\[([^\]]+)\]/ # support human readable alias for executable name
abort "Missing required executable #{exe}!" unless find_executable(exe)
return unless version_spec # no version is specified, so executable existing is good enough
version = %x|#{exe} --version 2>&1|.chomp
version = %x|#{exe} -version 2>&1|.chomp unless $?.success?
abort "Error checking for version of #{exe}: (#{$?.exitstatus}) #{version}" unless $?.success?
if version_regex
abort "Version test '#{version_regex}' failed to match '#{version}'!" unless version =~ /#{version_regex}/m
abort "Version test '#{version_regex}' failed to generate a version number!" unless
version =
end
abort "Failed to locate a valid version number for #{exe}, found '#{version}'" unless version =~ /^[0-9\.]+/
abort "Insufficient version '#{version}' for #{exe} - requires #{version_spec}" unless Gem::Dependency.new(exe, version_spec).match? exe, version
end
task :default do
gemspec = File.absolute_path('../my.gemspec')
Gem::Specification::load(gemspec).requirements.each do |req|
verify_requirement(req)
end
end
此代码要求 requirements
使用以下任一语法:
exe-file[, <semantic-version-spec>[, <version-garabbing-regex>]]
alias '[' exe-file ']'[, <semantic-version-spec>[, <version-garabbing-regex>]]
例如:
spec.requirements << 'sox'
spec.requirements << 'ffmpeg, >= 2.5, ffmpeg version ([\d\.]+)'
spec.requirements << 'ImageMagick [convert], >= 6.7.5, ImageMagick ([\d\.]+)'
Gem::Specification
class 可用于加载和解析 gemspec
。我在 ext/Rakefile
中使用以下代码来执行基于 gemspec
文件的任务:
task :default do
gemspec = File.absolute_path('../gemname.gemspec')
Gem::Specification::load(gemspec).requirements.each do |req|
verify_requirement(req)
end
end