2 # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
4 # See LICENSE.txt for permissions.
7 require 'rubygems/version'
10 # Requirement version includes a prefaced comparator in addition
11 # to a version number.
13 # A Requirement object can actually contain multiple, er,
14 # requirements, as in (> 1.2, < 2.0).
16 class Gem::Requirement
20 attr_reader :requirements
23 "=" => lambda { |v, r| v == r },
24 "!=" => lambda { |v, r| v != r },
25 ">" => lambda { |v, r| v > r },
26 "<" => lambda { |v, r| v < r },
27 ">=" => lambda { |v, r| v >= r },
28 "<=" => lambda { |v, r| v <= r },
29 "~>" => lambda { |v, r| v >= r && v < r.bump }
32 OP_RE = /#{OPS.keys.map{ |k| Regexp.quote k }.join '|'}/o
35 # Factory method to create a Gem::Requirement object. Input may be a
36 # Version, a String, or nil. Intended to simplify client code.
38 # If the input is "weird", the default version requirement is returned.
40 def self.create(input)
42 when Gem::Requirement then
44 when Gem::Version, Array then
47 if input.respond_to? :to_str then
48 self.new [input.to_str]
56 # A default "version requirement" can surely _only_ be '>= 0'.
58 # This comment once said:
60 # "A default "version requirement" can surely _only_ be '> 0'."
67 # Constructs a Requirement from +requirements+ which can be a String, a
68 # Gem::Version, or an Array of those. See parse for details on the
69 # formatting of requirement strings.
71 def initialize(requirements)
72 @requirements = case requirements
74 requirements.map do |requirement|
80 @version = nil # Avoid warnings.
84 # Marshal raw requirements, rather than the full object
86 def marshal_dump # :nodoc:
91 # Load custom marshal format
93 def marshal_load(array) # :nodoc:
94 @requirements = array[0]
104 @requirements.collect { |req|
105 "#{req[0]} #{req[1]}"
110 return if not defined? @version or @version.nil?
111 @requirements = [parse(@version)]
118 # True if this requirement satisfied by the Gem::Version +version+.
120 def satisfied_by?(version)
122 @requirements.all? { |op, rv| satisfy?(op, version, rv) }
126 # Is "+version+ +op+ +required_version+" satisfied?
128 def satisfy?(op, version, required_version)
129 OPS[op].call(version, required_version)
133 # Parse the version requirement obj returning the operator and version.
135 # The requirement can be a String or a Gem::Version. A String can be an
136 # operator (<, <=, =, =>, >, !=, ~>), a version number, or both, operator
141 when /^\s*(#{OP_RE})\s*([0-9.]+)\s*$/o then
142 [$1, Gem::Version.new($2)]
143 when /^\s*([0-9.]+)\s*$/ then
144 ['=', Gem::Version.new($1)]
145 when /^\s*(#{OP_RE})\s*$/o then
146 [$1, Gem::Version.new('0')]
147 when Gem::Version then
150 fail ArgumentError, "Illformed requirement [#{obj.inspect}]"
154 def <=>(other) # :nodoc: