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

发布于 01-05 19:54 字数 1688 浏览 4 评论 0原文

我正在构建一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烟雨凡馨2025-01-12 19:54:47

Gem::Specification.load 不允许我操作的属性
gemspec 因为它只返回 nil。

您使用的是最新的 RubyGems 吗?如果 Gem::Specification.load 成功评估 gem 规范文件,则返回 Gem::Specification 的实例...也许是拼写错误?请参阅 https://github.com/rubygems/rubygems/blob/ master/lib/rubygems/specification.rb

Gem::Specification.load doesn't let me manipulate the attributes of
the gemspec since it just returns nil.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文