Загрузка маршалированного объекта Ruby в C # - PullRequest
1 голос
/ 01 марта 2010

Когда вы запускаете команду 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, которое будет предупреждать вас, если у вас устаревшие гемы.

Теперь, так как файл latest_specs маршалируется Ruby, есть ли способ получить к нему доступ в C # без выполнения системной команды gem outdated?

1 Ответ

0 голосов
/ 01 марта 2010

Глядя на документы Gem :: Commands :: OutdatedCommand , похоже, что захват списка не составит большого труда.

Просто измените код с #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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...