Skip to content

Instantly share code, notes, and snippets.

@wycats
Created October 20, 2008 22:18
Show Gist options
  • Save wycats/18192 to your computer and use it in GitHub Desktop.
Save wycats/18192 to your computer and use it in GitHub Desktop.
require 'rubygems/remote_fetcher'
require 'zlib'
class GemSpec
include DataMapper::Resource
property :id, Integer, :serial => true
property :authors, DataMapper::Types::Object, :lazy => true
# property :dependencies, DataMapper::Types::Object, :lazy => true
property :description, DataMapper::Types::Text, :lazy => false
property :homepage, String, :size => 100
property :name, String
property :platform, DataMapper::Types::Object, :lazy => true
property :requirements, DataMapper::Types::Object, :lazy => true
property :summary, DataMapper::Types::Text, :lazy => false
property :version, String
class ParseError < StandardError; end
# Returns a list of all gem-specs, grouped by gem name, and with
# a list of all versions included.
def self.grouped_by_name(name = "")
return if name.size < 2
# If the name ends with !, we want an exact match
name = name =~ /!$/ ? name[0..-2] : "#{name}%"
specs = GemSpec.all(:name.like => name, :order => ["version"])
group(specs)
end
def self.group(specs)
gem_specs = Dictionary.new
specs.each do |spec|
gem_specs[spec.name] ||= {}
gem_specs[spec.name][:spec] = spec
gem_specs[spec.name][:versions] ||= []
gem_specs[spec.name][:versions] << spec.version
end
gem_specs
end
def self.from_text(text)
raise ArgumentError, "String expected, got #{text.class}" unless text.is_a?(String)
arr = text.split("\n").map {|x| x.strip}.reject {|x| x =~ /^\s*$/}
arr.map do |item|
m = item.match(/(.*)\s\((.*)\)/)
raise ParseError, "Parsing failed on #{item}" unless m && m[1] && m[2]
[m[1], m[2]]
end
end
def self.fresh_import
fetcher = Gem::RemoteFetcher.fetcher
data = fetcher.fetch_path "http://gems.rubyforge.org/Marshal.#{Gem.marshal_version}.Z"
data = Zlib::Inflate.inflate(data)
index = Marshal.load(data)
import_from_index(index)
end
def self.import_from_index(index)
i = 1
set = Merb::SimpleSet.new
self.all.each {|spec| set << "#{spec.name} #{spec.version}"}
added_set = Merb::SimpleSet.new
index.each do |name, spec|
i += 1
print "##{i.to_s.rjust(8)} of #{(index.size + 1).to_s.rjust(8)} Importing #{name.ljust(50)} " unless Merb.environment == 'test'
if set.include?("#{spec.name} #{spec.version.version}")
puts "Already imported" unless Merb.environment == 'test'
next
end
puts "Imported" unless Merb.environment == 'test'
create(
:authors => spec.authors,
:dependencies => spec.dependencies,
:description => spec.description,
:homepage => spec.homepage.is_a?(Array) ? spec.homepage.join(", ") : spec.homepage,
:name => spec.name,
:platform => spec.platform,
:requirements => spec.requirements,
:summary => spec.summary,
:version => spec.version.version
)
added_set << "#{spec.name} #{spec.version.version}"
end
added_set
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment