Ruby 1.9.1-p243 - 使用在运行时更新的 gemspec 构建 gem
我正在构建一个 rake 任务,它会拉下一个存储库,运行一些规范,并在它们全部通过时构建一个 gem。
gemspec 文件附带了存储库的原始签出,我想在构建 gem 时(即运行任务时)更改版本。 Gem::Specification.load 不允许我操作 gemspec 的属性,因为它只返回 nil。到目前为止,我想到的唯一方法是创建一个临时 gemspec,用我想要的内容替换版本行,然后将其 mv 覆盖当前的 gemspec。
但是,直到(我认为)进程退出,该文件才会更新。路径和文件名义上都在那里,但文件本身没有内容,只是空白。在 irb 中测试时,gemspec 的内容会在退出会话后出现。
这是 gem 构建的 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
我的做法是错误的吗?
I'm building a rake task that pulls down a repo, runs some specs and builds a gem if they all pass.
The gemspec file comes with the original checkout of the repo, and I'd like to bump the version whenever the gem is built (i.e. when the task is run). Gem::Specification.load doesn't let me manipulate the attributes of the gemspec since it just returns nil. The only way I've figured out to do this so far is to create a temp gemspec, replace the version line with what I want and mv it over the current gemspec.
However, the file is not updated until (I think) the process exits. The path and file are nominally there, but there is no content in the file itself, it's just blank. When testing in irb, the gemspec's content appears after exiting the session.
Here's the rake task for gem building:
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
(You can see I thought forking the process to run the method would fix the problem, but it just used the original gemspec to build the gem and didn't update anything until the rake task completed.)
And the update_gemspec_version helper method:
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
Am I going about this all wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

您使用的是最新的 RubyGems 吗?如果 Gem::Specification.load 成功评估 gem 规范文件,则返回 Gem::Specification 的实例...也许是拼写错误?请参阅 https://github.com/rubygems/rubygems/blob/ master/lib/rubygems/specification.rb
Are you using the latest RubyGems? Gem::Specification.load returns an instance of Gem::Specification if it evaluates the gem spec file successfully... maybe a typo? See https://github.com/rubygems/rubygems/blob/master/lib/rubygems/specification.rb