当您运行命令gem outdated -V
时,命令的输出显示类似于此的内容:
GET http://rubygems.org/latest_specs.4.8.gz
302 Found
GET http://production.s3.rubygems.org/latest_specs.4.8.gz
200 OK
这将向您发送一个gzip文件,其中包含另一个名为latest_specs.4.8
的文件,您可以Marshal.load
使用一个简单的Ruby应用程序,如下所示:
require 'pp'
require 'rubygems/version'
# This assumes you've downloaded the file to the current directory
pp Marshal.load(File.open('latest_specs.4.8'))
运行它,它会打印一个看起来像这样的多维Array
:
[
["rails", Gem::Version.new("2.3.5"), "ruby"],
["sinatra", Gem::Version.new("0.9.4"), "ruby"],
["watir", Gem::Version.new("1.6.5"), "ruby"]
]
非常简单,但我正在尝试制作一个C#RubyGems GUI应用程序,当你有过时的宝石时会提醒你。
现在,由于update_specs文件是由Ruby编组的,有没有办法在不运行系统命令gem outdated
的情况下在C#中访问它?
答案 0 :(得分:0)
查看Gem::Commands::OutdatedCommand docs,看起来抓住列表并不会太困难。
只需修改#execute
# File lib/rubygems/commands/outdated_command.rb, line 18
def execute
locals = Gem::SourceIndex.from_installed_gems
locals.outdated.sort.each do |name|
local = locals.find_name(name).last
dep = Gem::Dependency.new local.name, ">= #{local.version}"
remotes = Gem::SpecFetcher.fetcher.fetch dep
remote = remotes.last.first
say "#{local.name} (#{local.version} < #{remote.version})"
end
end
您可以执行类似
的操作def outdated_gems
locals = Gem::SourceIndex.from_gems_in *Gem::SourceIndex.installed_spec_directories
locals.outdated.sort.map {|name| locals.find_name(name).last }
end
def latest_remote_gem local
dep = Gem::Dependency.new local.name, ">= #{local.version}"
remotes = Gem::SpecFetcher.fetcher.fetch dep
remotes.last.first
end
#...
updated_gems = outdated_gems.map { |gem| [gem, latest_remote_gem(local)] }
updated_gems.each do |local,remote|
# do something interesting with local.name, local.version & remote.version
end