Ruby 1.9.1-p243 - 使用在运行时更新的gemspec构建gem

时间:2012-02-15 22:30:05

标签: ruby gem rake

我正在构建一个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

我是不是错了?

1 个答案:

答案 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