2
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
4
# See LICENSE.txt for permissions.
7
require 'rubygems/version'
1
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).
4
# A Requirement is a set of one or more version restrictions. It supports a
5
# few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators.
16
7
class Gem::Requirement
20
attr_reader :requirements
23
11
"=" => lambda { |v, r| v == r },
24
12
"!=" => lambda { |v, r| v != r },
25
">" => lambda { |v, r| v > r },
26
"<" => lambda { |v, r| v < r },
13
">" => lambda { |v, r| v > r },
14
"<" => lambda { |v, r| v < r },
27
15
">=" => lambda { |v, r| v >= r },
28
16
"<=" => lambda { |v, r| v <= r },
29
"~>" => lambda { |v, r| v >= r && v < r.bump }
17
"~>" => lambda { |v, r| v = v.release; v >= r && v < r.bump }
32
OP_RE = /#{OPS.keys.map{ |k| Regexp.quote k }.join '|'}/o
20
quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
21
PATTERN = /\A\s*(#{quoted})?\s*(#{Gem::Version::VERSION_PATTERN})\s*\z/
35
# Factory method to create a Gem::Requirement object. Input may be a
36
# Version, a String, or nil. Intended to simplify client code.
24
# Factory method to create a Gem::Requirement object. Input may be
25
# a Version, a String, or nil. Intended to simplify client code.
38
# If the input is "weird", the default version requirement is returned.
27
# If the input is "weird", the default version requirement is
40
def self.create(input)
42
32
when Gem::Requirement then
60
50
# "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
57
# Parse +obj+, returning an <tt>[op, version]</tt> pair. +obj+ can
58
# be a String or a Gem::Version.
60
# If +obj+ is a String, it can be either a full requirement
61
# specification, like <tt>">= 1.2"</tt>, or a simple version number,
62
# like <tt>"1.2"</tt>.
64
# parse("> 1.0") # => [">", "1.0"]
65
# parse("1.0") # => ["=", "1.0"]
66
# parse(Gem::Version.new("1.0")) # => ["=, "1.0"]
69
return ["=", obj] if Gem::Version === obj
71
unless PATTERN =~ obj.to_s
72
raise ArgumentError, "Illformed requirement [#{obj.inspect}]"
75
[$1 || "=", Gem::Version.new($2)]
79
# An array of requirement pairs. The first element of the pair is
80
# the op, and the second is the Gem::Version.
82
attr_reader :requirements #:nodoc:
85
# Constructs a requirement from +requirements+. Requirements can be
86
# Strings, Gem::Versions, or Arrays of those. +nil+ and duplicate
87
# requirements are ignored. An empty set of +requirements+ is the
88
# same as <tt>">= 0"</tt>.
90
def initialize *requirements
91
requirements = requirements.flatten
95
requirements << ">= 0" if requirements.empty?
96
@none = (requirements == ">= 0")
97
@requirements = requirements.map! { |r| self.class.parse r }
101
@none ||= (to_s == ">= 0")
104
def as_list # :nodoc:
105
requirements.map { |op, version| "#{op} #{version}" }
86
112
def marshal_dump # :nodoc:
91
# Load custom marshal format
93
def marshal_load(array) # :nodoc:
116
def marshal_load array # :nodoc:
94
117
@requirements = array[0]
121
requirements.any? { |r| r.last.prerelease? }
124
def pretty_print q # :nodoc:
125
q.group 1, 'Gem::Requirement.new(', ')' do
131
# True if +version+ satisfies this Requirement.
133
def satisfied_by? version
134
requirements.all? { |op, rv| OPS[op].call version, rv }
98
137
def to_s # :nodoc:
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:
141
def <=> other # :nodoc:
155
142
to_s <=> other.to_s
147
# Gem::Version::Requirement is used in a lot of old YAML specs. It's aliased
148
# here for backwards compatibility. I'd like to remove this, maybe in RubyGems
151
::Gem::Version::Requirement = ::Gem::Requirement