Loading a marshaled Ruby object in C#
When you run the command gem outdated -V
, the output of the command displays something similar to this:
GET http://rubygems.org/latest_specs.4.8.gz
302 Found
GET http://production.s3.rubygems.org/latest_specs.4.8.gz
200 OK
This will send you a gzip file that contains another file called latest_specs.4.8
which you can Marshal.load
with a simple Ruby app like so:
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'))
Run this and it will pretty print a multi-dimensional Array
that looks like so:
[
["rails", Gem::Version.new("2.3.5"), "ruby"],
["sinatra", Gem::Version.new("0.9.4"), "ruby"],
["watir", Gem::Version.new("1.6.5"), "ruby"]
]
Pretty simple, but I am trying to make a C# RubyGems GUI application that would alert you when y开发者_开发知识库ou have outdated gems.
Now, since the latest_specs file is marshaled by Ruby, is there any way I could access it within C# without running the system command gem outdated
?
Looking at the Gem::Commands::OutdatedCommand docs, it looks like grabbing the list would not be too difficult.
Just modify the code from #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
You could do something like
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
精彩评论