2010-02-21 21:52:35 -05:00
|
|
|
require "rubygems/version"
|
2007-11-10 02:48:56 -05:00
|
|
|
|
|
|
|
##
|
2010-02-21 21:52:35 -05:00
|
|
|
# A Requirement is a set of one or more version restrictions. It supports a
|
|
|
|
# few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators.
|
2008-06-17 18:04:18 -04:00
|
|
|
|
2007-11-10 02:48:56 -05:00
|
|
|
class Gem::Requirement
|
|
|
|
include Comparable
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
OPS = { #:nodoc:
|
2007-11-10 02:48:56 -05:00
|
|
|
"=" => lambda { |v, r| v == r },
|
|
|
|
"!=" => lambda { |v, r| v != r },
|
2010-02-21 21:52:35 -05:00
|
|
|
">" => lambda { |v, r| v > r },
|
|
|
|
"<" => lambda { |v, r| v < r },
|
2007-11-10 02:48:56 -05:00
|
|
|
">=" => lambda { |v, r| v >= r },
|
|
|
|
"<=" => lambda { |v, r| v <= r },
|
2009-06-09 17:38:59 -04:00
|
|
|
"~>" => lambda { |v, r| v = v.release; v >= r && v < r.bump }
|
2007-11-10 02:48:56 -05:00
|
|
|
}
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
|
|
|
|
PATTERN = /\A\s*(#{quoted})?\s*(#{Gem::Version::VERSION_PATTERN})\s*\z/
|
2007-11-10 02:48:56 -05:00
|
|
|
|
|
|
|
##
|
2010-02-21 21:52:35 -05:00
|
|
|
# Factory method to create a Gem::Requirement object. Input may be
|
|
|
|
# a Version, a String, or nil. Intended to simplify client code.
|
2007-11-10 02:48:56 -05:00
|
|
|
#
|
2010-02-21 21:52:35 -05:00
|
|
|
# If the input is "weird", the default version requirement is
|
|
|
|
# returned.
|
2008-06-17 18:04:18 -04:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def self.create input
|
2007-11-10 02:48:56 -05:00
|
|
|
case input
|
|
|
|
when Gem::Requirement then
|
|
|
|
input
|
|
|
|
when Gem::Version, Array then
|
|
|
|
new input
|
|
|
|
else
|
|
|
|
if input.respond_to? :to_str then
|
2010-02-21 21:52:35 -05:00
|
|
|
new [input.to_str]
|
2007-11-10 02:48:56 -05:00
|
|
|
else
|
2010-02-21 21:52:35 -05:00
|
|
|
default
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# A default "version requirement" can surely _only_ be '>= 0'.
|
|
|
|
#--
|
|
|
|
# This comment once said:
|
|
|
|
#
|
|
|
|
# "A default "version requirement" can surely _only_ be '> 0'."
|
2008-06-17 18:04:18 -04:00
|
|
|
|
2007-11-10 02:48:56 -05:00
|
|
|
def self.default
|
2010-02-21 21:52:35 -05:00
|
|
|
new '>= 0'
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
2010-02-21 21:52:35 -05:00
|
|
|
# Parse +obj+, returning an <tt>[op, version]</tt> pair. +obj+ can
|
|
|
|
# be a String or a Gem::Version.
|
|
|
|
#
|
|
|
|
# If +obj+ is a String, it can be either a full requirement
|
|
|
|
# specification, like <tt>">= 1.2"</tt>, or a simple version number,
|
|
|
|
# like <tt>"1.2"</tt>.
|
|
|
|
#
|
|
|
|
# parse("> 1.0") # => [">", "1.0"]
|
|
|
|
# parse("1.0") # => ["=", "1.0"]
|
|
|
|
# parse(Gem::Version.new("1.0")) # => ["=, "1.0"]
|
2007-11-10 02:48:56 -05:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def self.parse obj
|
|
|
|
return ["=", obj] if Gem::Version === obj
|
2008-06-17 18:04:18 -04:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
unless PATTERN =~ obj.to_s
|
|
|
|
raise ArgumentError, "Illformed requirement [#{obj.inspect}]"
|
|
|
|
end
|
|
|
|
|
|
|
|
[$1 || "=", Gem::Version.new($2)]
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
2008-06-17 18:04:18 -04:00
|
|
|
##
|
2010-02-21 21:52:35 -05:00
|
|
|
# An array of requirement pairs. The first element of the pair is
|
|
|
|
# the op, and the second is the Gem::Version.
|
2008-06-17 18:04:18 -04:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
attr_reader :requirements #:nodoc:
|
|
|
|
|
|
|
|
##
|
|
|
|
# Constructs a requirement from +requirements+. Requirements can be
|
|
|
|
# Strings, Gem::Versions, or Arrays of those. +nil+ and duplicate
|
|
|
|
# requirements are ignored. An empty set of +requirements+ is the
|
|
|
|
# same as <tt>">= 0"</tt>.
|
|
|
|
|
|
|
|
def initialize *requirements
|
|
|
|
requirements = requirements.flatten
|
|
|
|
requirements.compact!
|
|
|
|
requirements.uniq!
|
|
|
|
|
|
|
|
requirements << ">= 0" if requirements.empty?
|
|
|
|
@requirements = requirements.map! { |r| self.class.parse r }
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def as_list # :nodoc:
|
|
|
|
requirements.map { |op, version| "#{op} #{version}" }
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def hash # :nodoc:
|
|
|
|
requirements.hash
|
2009-06-09 17:38:59 -04:00
|
|
|
end
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def marshal_dump # :nodoc:
|
|
|
|
[@requirements]
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def marshal_load array # :nodoc:
|
|
|
|
@requirements = array[0]
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def prerelease?
|
|
|
|
requirements.any? { |r| r.last.prerelease? }
|
|
|
|
end
|
2008-06-17 18:04:18 -04:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def pretty_print q # :nodoc:
|
|
|
|
q.group 1, 'Gem::Requirement.new(', ')' do
|
|
|
|
q.pp as_list
|
|
|
|
end
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
2010-02-21 21:52:35 -05:00
|
|
|
# True if +version+ satisfies this Requirement.
|
2008-06-17 18:04:18 -04:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def satisfied_by? version
|
|
|
|
requirements.all? { |op, rv| OPS[op].call version, rv }
|
2009-06-09 17:38:59 -04:00
|
|
|
end
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def to_s # :nodoc:
|
|
|
|
as_list.join ", "
|
2007-11-10 02:48:56 -05:00
|
|
|
end
|
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
def <=> other # :nodoc:
|
2007-11-10 02:48:56 -05:00
|
|
|
to_s <=> other.to_s
|
|
|
|
end
|
2010-02-21 21:52:35 -05:00
|
|
|
end
|
2007-11-10 02:48:56 -05:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
# :stopdoc:
|
|
|
|
# Gem::Version::Requirement is used in a lot of old YAML specs. It's aliased
|
|
|
|
# here for backwards compatibility. I'd like to remove this, maybe in RubyGems
|
|
|
|
# 2.0.
|
2007-11-10 02:48:56 -05:00
|
|
|
|
2010-02-21 21:52:35 -05:00
|
|
|
::Gem::Version::Requirement = ::Gem::Requirement
|
|
|
|
# :startdoc:
|
2007-11-10 02:48:56 -05:00
|
|
|
|