summaryrefslogtreecommitdiff
path: root/lib/rubygems/requirement.rb
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-11-10 07:48:56 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-11-10 07:48:56 +0000
commitfbf59bdbea63efd34ccc144e648467d2f52e7345 (patch)
tree244f0e7ae112cc7dd135e5d1ac24e6c70ba71b4a /lib/rubygems/requirement.rb
parent7a4aad75356496559460041a6c063bdb736c7236 (diff)
Import RubyGems trunk revision 1493.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13862 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems/requirement.rb')
-rw-r--r--lib/rubygems/requirement.rb157
1 files changed, 157 insertions, 0 deletions
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
new file mode 100644
index 0000000000..4dfba4fa61
--- /dev/null
+++ b/lib/rubygems/requirement.rb
@@ -0,0 +1,157 @@
+#--
+# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
+# All rights reserved.
+# See LICENSE.txt for permissions.
+#++
+
+require 'rubygems/version'
+
+##
+# Requirement version includes a prefaced comparator in addition
+# to a version number.
+#
+# A Requirement object can actually contain multiple, er,
+# requirements, as in (> 1.2, < 2.0).
+class Gem::Requirement
+
+ include Comparable
+
+ OPS = {
+ "=" => lambda { |v, r| v == r },
+ "!=" => lambda { |v, r| v != r },
+ ">" => lambda { |v, r| v > r },
+ "<" => lambda { |v, r| v < r },
+ ">=" => lambda { |v, r| v >= r },
+ "<=" => lambda { |v, r| v <= r },
+ "~>" => lambda { |v, r| v >= r && v < r.bump }
+ }
+
+ OP_RE = /#{OPS.keys.map{ |k| Regexp.quote k }.join '|'}/o
+
+ ##
+ # Factory method to create a Gem::Requirement object. Input may be a
+ # Version, a String, or nil. Intended to simplify client code.
+ #
+ # If the input is "weird", the default version requirement is returned.
+ #
+ def self.create(input)
+ case input
+ when Gem::Requirement then
+ input
+ when Gem::Version, Array then
+ new input
+ else
+ if input.respond_to? :to_str then
+ self.new [input.to_str]
+ else
+ self.default
+ 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'."
+ def self.default
+ self.new ['>= 0']
+ end
+
+ ##
+ # Constructs a Requirement from +requirements+ which can be a String, a
+ # Gem::Version, or an Array of those. See parse for details on the
+ # formatting of requirement strings.
+ def initialize(requirements)
+ @requirements = case requirements
+ when Array then
+ requirements.map do |requirement|
+ parse(requirement)
+ end
+ else
+ [parse(requirements)]
+ end
+ @version = nil # Avoid warnings.
+ end
+
+ # Marshal raw requirements, rather than the full object
+ def marshal_dump
+ [@requirements]
+ end
+
+ # Load custom marshal format
+ def marshal_load(array)
+ @requirements = array[0]
+ @version = nil
+ end
+
+ def to_s # :nodoc:
+ as_list.join(", ")
+ end
+
+ def as_list
+ normalize
+ @requirements.collect { |req|
+ "#{req[0]} #{req[1]}"
+ }
+ end
+
+ def normalize
+ return if not defined? @version or @version.nil?
+ @requirements = [parse(@version)]
+ @nums = nil
+ @version = nil
+ @op = nil
+ end
+
+ ##
+ # Is the requirement satifised by +version+.
+ #
+ # version:: [Gem::Version] the version to compare against
+ # return:: [Boolean] true if this requirement is satisfied by
+ # the version, otherwise false
+ #
+ def satisfied_by?(version)
+ normalize
+ @requirements.all? { |op, rv| satisfy?(op, version, rv) }
+ end
+
+ ##
+ # Is "version op required_version" satisfied?
+ #
+ def satisfy?(op, version, required_version)
+ OPS[op].call(version, required_version)
+ end
+
+ ##
+ # Parse the version requirement obj returning the operator and version.
+ #
+ # The requirement can be a String or a Gem::Version. A String can be an
+ # operator (<, <=, =, =>, >, !=, ~>), a version number, or both, operator
+ # first.
+ def parse(obj)
+ case obj
+ when /^\s*(#{OP_RE})\s*([0-9.]+)\s*$/o then
+ [$1, Gem::Version.new($2)]
+ when /^\s*([0-9.]+)\s*$/ then
+ ['=', Gem::Version.new($1)]
+ when /^\s*(#{OP_RE})\s*$/o then
+ [$1, Gem::Version.new('0')]
+ when Gem::Version then
+ ['=', obj]
+ else
+ fail ArgumentError, "Illformed requirement [#{obj.inspect}]"
+ end
+ end
+
+ def <=>(other)
+ to_s <=> other.to_s
+ end
+
+ def hash # :nodoc:
+ to_s.hash
+ end
+
+end
+