我正在构建一个rake任务,它可以下载一个repo,运行一些规范并构建一个gem,如果它们都通过的话。
gemspec文件附带了repo的原始签出,并且我想在构建gem时(即运行任务时)碰撞版本。 Gem :: Specification.load不允许我操纵gemspec的属性,因为它只返回nil。到目前为止,我唯一能做到这一点的方法是创建一个临时gemspec,用我想要的版本替换版本行,然后将它放在当前的gemspec上。
但是,在(我认为)进程退出之前,文件不会更新。路径和文件名义上在那里,但文件本身没有内容,它只是空白。在irb中测试时,退出会话后会出现gemspec的内容。
这是宝石建设的rake任务:
desc "Build new vulnerability tests gem"
task :build_gem do
Process.fork { update_gemspec_version 'foo.gemspec' }
gemspec = Gem::Specification.load('foo.gemspec')
builder = Gem::Builder.new(gemspec)
puts "Building gem from #{gemspec.file_name}"
builder.build
end
(你可以看到我认为运行该方法的过程会解决问题,但它只是使用原始gemspec来构建gem并且在rake任务完成之前没有更新任何内容。)
update_gemspec_version辅助方法:
def update_gemspec_version(gemspec)
temp_file = Tempfile.new "#{gemspec}"
time = Time.now
minor_rev = 0
base = time.year.to_s + '.' + time.month.to_s + '.' + time.day.to_s
File.open("#{gemspec}", 'r') do |file|
file.each do |line|
if line =~ /^\s*s\.version\s=\s'(\d+\.\d+\.\d+\.(\d+))'$/
if $1 >= base + '.' + minor_rev.to_s
while minor_rev <= $2.to_i
minor_rev += 1
end
replacement = line.gsub($1, base + '.' + minor_rev.to_s)
puts replacement
temp_file.puts replacement
else
replacement = line.gsub($1, base + '.' + minor_rev.to_s)
puts replacement
temp_file.puts replacement
end
else
temp_file.puts line
end
end
end
FileUtils.mv(temp_file.path, File.expand_path("#{gemspec}"))
nil
end
我是不是错了?
答案 0 :(得分:0)
Gem :: Specification.load不允许我操纵属性 gemspec,因为它只返回nil。
您使用的是最新的RubyGems吗? Gem :: Specification.load如果成功评估gem规范文件,则返回Gem :: Specification的实例...可能是拼写错误?见https://github.com/rubygems/rubygems/blob/master/lib/rubygems/specification.rb