aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/requirement.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/requirement.rb')
-rw-r--r--lib/rubygems/requirement.rb87
1 files changed, 62 insertions, 25 deletions
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
index 7abff01c39..b80e8dca19 100644
--- a/lib/rubygems/requirement.rb
+++ b/lib/rubygems/requirement.rb
@@ -1,5 +1,3 @@
-require "rubygems/version"
-
##
# A Requirement is a set of one or more version restrictions. It supports a
# few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators.
@@ -13,14 +11,16 @@ require "rubygems/version"
require "rubygems/version"
require "rubygems/deprecate"
-class Gem::Requirement
- include Comparable
+# If we're being loaded after yaml was already required, then
+# load our yaml + workarounds now.
+Gem.load_yaml if defined? ::YAML
+class Gem::Requirement
OPS = { #:nodoc:
"=" => 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 },
"<=" => lambda { |v, r| v <= r },
"~>" => lambda { |v, r| v >= r && v.release < r.bump }
@@ -29,6 +29,10 @@ class Gem::Requirement
quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
PATTERN = /\A\s*(#{quoted})?\s*(#{Gem::Version::VERSION_PATTERN})\s*\z/
+ DefaultRequirement = [">=", Gem::Version.new(0)]
+
+ class BadRequirementError < ArgumentError; end
+
##
# Factory method to create a Gem::Requirement object. Input may be
# a Version, a String, or nil. Intended to simplify client code.
@@ -36,6 +40,9 @@ class Gem::Requirement
# If the input is "weird", the default version requirement is
# returned.
+ # REFACTOR: There's no reason that this can't be unified with .new.
+ # .new is the standard Ruby factory method.
+
def self.create input
case input
when Gem::Requirement then
@@ -53,10 +60,6 @@ class Gem::Requirement
##
# 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
new '>= 0'
@@ -74,14 +77,23 @@ class Gem::Requirement
# parse("1.0") # => ["=", "1.0"]
# parse(Gem::Version.new("1.0")) # => ["=, "1.0"]
+ # REFACTOR: Little two element arrays like this have no real semantic
+ # value. I'd love to see something like this:
+ # Constraint = Struct.new(:operator, :version); (or similar)
+ # and have a Requirement be a list of Constraints.
+
def self.parse obj
return ["=", obj] if Gem::Version === obj
unless PATTERN =~ obj.to_s
- raise ArgumentError, "Illformed requirement [#{obj.inspect}]"
+ raise BadRequirementError, "Illformed requirement [#{obj.inspect}]"
end
- [$1 || "=", Gem::Version.new($2)]
+ if $1 == ">=" && $2 == "0"
+ DefaultRequirement
+ else
+ [$1 || "=", Gem::Version.new($2)]
+ end
end
##
@@ -101,13 +113,23 @@ class Gem::Requirement
requirements.compact!
requirements.uniq!
- requirements << ">= 0" if requirements.empty?
- @none = (requirements == ">= 0")
- @requirements = requirements.map! { |r| self.class.parse r }
+ if requirements.empty?
+ @requirements = [DefaultRequirement]
+ else
+ @requirements = requirements.map! { |r| self.class.parse r }
+ end
end
+ ##
+ # true if this gem has no requirements.
+
+ # FIX: maybe this should be using #default ?
def none?
- @none ||= (to_s == ">= 0")
+ if @requirements.size == 1
+ @requirements[0] == DefaultRequirement
+ else
+ false
+ end
end
def as_list # :nodoc:
@@ -135,6 +157,7 @@ class Gem::Requirement
instance_variable_set "@#{ivar}", val
end
+ Gem.load_yaml
fix_syck_default_key_in_requirements
end
@@ -142,6 +165,18 @@ class Gem::Requirement
yaml_initialize coder.tag, coder.map
end
+ def to_yaml_properties
+ ["@requirements"]
+ end
+
+ def encode_with(coder)
+ coder.add 'requirements', @requirements
+ end
+
+ ##
+ # A requirement is a prerelease if any of the versions inside of it
+ # are prereleases
+
def prerelease?
requirements.any? { |r| r.last.prerelease? }
end
@@ -156,6 +191,8 @@ class Gem::Requirement
# True if +version+ satisfies this Requirement.
def satisfied_by? version
+ raise ArgumentError, "Need a Gem::Version: #{version.inspect}" unless
+ Gem::Version === version
# #28965: syck has a bug with unquoted '=' YAML.loading as YAML::DefaultKey
requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv }
end
@@ -176,12 +213,14 @@ class Gem::Requirement
as_list.join ", "
end
- def <=> other # :nodoc:
- to_s <=> other.to_s
+ # DOC: this should probably be :nodoc'd
+ def == other
+ Gem::Requirement === other and to_s == other.to_s
end
private
+ # DOC: this should probably be :nodoc'd
def fix_syck_default_key_in_requirements
Gem.load_yaml
@@ -194,11 +233,9 @@ class Gem::Requirement
end
end
-# :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.
-
-::Gem::Version::Requirement = ::Gem::Requirement
-# :startdoc:
+# This is needed for compatibility with older yaml
+# gemspecs.
+class Gem::Version
+ Requirement = Gem::Requirement
+end