Class: Gel::Support::GemRequirement

Inherits:
Object
  • Object
show all
Defined in:
lib/gel/support/gem_requirement.rb

Overview

A Requirement is a set of one or more version restrictions. It supports a few (=, !=, >, <, >=, <=, ~>) different restriction operators.

See Gem::Version for a description on how versions and requirements work together in RubyGems.

Defined Under Namespace

Classes: BadRequirementError

Constant Summary collapse

OPS =

:nodoc:

{ #: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 && v.release < r.bump }
}
SOURCE_SET_REQUIREMENT =

:nodoc:

Struct.new(:for_lockfile).new "!"
PATTERN_RAW =

:nodoc:

"\\s*(#{quoted})?\\s*(#{Gel::Support::GemVersion::VERSION_PATTERN})\\s*"
PATTERN =

A regular expression that matches a requirement

/\A#{PATTERN_RAW}\z/
DefaultRequirement =

The default requirement matches any version

[">=", Gel::Support::GemVersion.new(0)]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*requirements) ⇒ GemRequirement

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 ">= 0".



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/gel/support/gem_requirement.rb', line 129

def initialize *requirements
  requirements = requirements.flatten
  requirements.compact!
  requirements.uniq!

  if requirements.empty?
    @requirements = [DefaultRequirement]
  else
    @requirements = requirements.map! { |r| self.class.parse r }
  end
end

Instance Attribute Details

#requirementsObject (readonly)

An array of requirement pairs. The first element of the pair is the op, and the second is the Gem::Version.



121
122
123
# File 'lib/gel/support/gem_requirement.rb', line 121

def requirements
  @requirements
end

Class Method Details

.create(*inputs) ⇒ Object

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.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/gel/support/gem_requirement.rb', line 56

def self.create *inputs
  return new inputs if inputs.length > 1

  input = inputs.shift

  case input
  when Gel::Support::GemRequirement then
    input
  when Gel::Support::GemVersion, Array then
    new input
  when '!' then
    source_set
  else
    if input.respond_to? :to_str then
      new [input.to_str]
    else
      default
    end
  end
end

.defaultObject

A default “version requirement” can surely only be ‘>= 0’.



80
81
82
# File 'lib/gel/support/gem_requirement.rb', line 80

def self.default
  new '>= 0'
end

.parse(obj) ⇒ Object

Parse obj, returning an [op, version] pair. obj can be a String or a Gem::Version.

If obj is a String, it can be either a full requirement specification, like ">= 1.2", or a simple version number, like "1.2".

parse("> 1.0")                 # => [">", Gem::Version.new("1.0")]
parse("1.0")                   # => ["=", Gem::Version.new("1.0")]
parse(Gem::Version.new("1.0")) # => ["=,  Gem::Version.new("1.0")]


103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/gel/support/gem_requirement.rb', line 103

def self.parse obj
  return ["=", obj] if Gel::Support::GemVersion === obj

  unless PATTERN =~ obj.to_s
    raise BadRequirementError, "Illformed requirement [#{obj.inspect}]"
  end

  if $1 == ">=" && $2 == "0"
    DefaultRequirement
  else
    [$1 || "=", Gel::Support::GemVersion.new($2)]
  end
end

.source_setObject

A source set requirement, used for Gemfiles and lockfiles



87
88
89
# File 'lib/gel/support/gem_requirement.rb', line 87

def self.source_set # :nodoc:
  SOURCE_SET_REQUIREMENT
end

Instance Method Details

#==(other) ⇒ Object

:nodoc:



261
262
263
# File 'lib/gel/support/gem_requirement.rb', line 261

def == other # :nodoc:
  Gel::Support::GemRequirement === other and to_s == other.to_s
end

#as_listObject

:nodoc:



187
188
189
# File 'lib/gel/support/gem_requirement.rb', line 187

def as_list # :nodoc:
  requirements.map { |op, version| "#{op} #{version}" }.sort
end

#concat(new) ⇒ Object

Concatenates the new requirements onto this requirement.



144
145
146
147
148
149
150
151
# File 'lib/gel/support/gem_requirement.rb', line 144

def concat new
  new = new.flatten
  new.compact!
  new.uniq!
  new = new.map { |r| self.class.parse r }

  @requirements.concat new
end

#encode_with(coder) ⇒ Object

:nodoc:



217
218
219
# File 'lib/gel/support/gem_requirement.rb', line 217

def encode_with coder # :nodoc:
  coder.add 'requirements', @requirements
end

#exact?Boolean

true if the requirement is for only an exact version

Returns:

  • (Boolean)


182
183
184
185
# File 'lib/gel/support/gem_requirement.rb', line 182

def exact?
  return false unless @requirements.size == 1
  @requirements[0][0] == "="
end

#for_lockfileObject

Formats this requirement for use in a Gem::RequestSet::Lockfile.



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/gel/support/gem_requirement.rb', line 156

def for_lockfile # :nodoc:
  return if [DefaultRequirement] == @requirements

  list = requirements.sort_by { |_, version|
    version
  }.map { |op, version|
    "#{op} #{version}"
  }.uniq

  " (#{list.join ', '})"
end

#hashObject

:nodoc:



191
192
193
# File 'lib/gel/support/gem_requirement.rb', line 191

def hash # :nodoc:
  requirements.sort.hash
end

#init_with(coder) ⇒ Object

:nodoc:



209
210
211
# File 'lib/gel/support/gem_requirement.rb', line 209

def init_with coder # :nodoc:
  yaml_initialize coder.tag, coder.map
end

#marshal_dumpObject

:nodoc:



195
196
197
# File 'lib/gel/support/gem_requirement.rb', line 195

def marshal_dump # :nodoc:
  [@requirements]
end

#marshal_load(array) ⇒ Object

:nodoc:



199
200
201
# File 'lib/gel/support/gem_requirement.rb', line 199

def marshal_load array # :nodoc:
  @requirements = array[0]
end

#none?Boolean

true if this gem has no requirements.

Returns:

  • (Boolean)


171
172
173
174
175
176
177
# File 'lib/gel/support/gem_requirement.rb', line 171

def none?
  if @requirements.size == 1
    @requirements[0] == DefaultRequirement
  else
    false
  end
end

#prerelease?Boolean

A requirement is a prerelease if any of the versions inside of it are prereleases

Returns:

  • (Boolean)


225
226
227
# File 'lib/gel/support/gem_requirement.rb', line 225

def prerelease?
  requirements.any? { |r| r.last.prerelease? }
end

#pretty_print(q) ⇒ Object

:nodoc:



229
230
231
232
233
# File 'lib/gel/support/gem_requirement.rb', line 229

def pretty_print q # :nodoc:
  q.group 1, 'Gel::Support::GemRequirement.new(', ')' do
    q.pp as_list
  end
end

#satisfied_by?(version) ⇒ Boolean Also known as: ===, =~

True if version satisfies this Requirement.

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


238
239
240
241
242
243
# File 'lib/gel/support/gem_requirement.rb', line 238

def satisfied_by? version
  raise ArgumentError, "Need a Gel::Support::GemVersion: #{version.inspect}" unless
    Gel::Support::GemVersion === version
  # #28965: syck has a bug with unquoted '=' YAML.loading as YAML::DefaultKey
  requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv }
end

#specific?Boolean

True if the requirement will not always match the latest version.

Returns:

  • (Boolean)


251
252
253
254
255
# File 'lib/gel/support/gem_requirement.rb', line 251

def specific?
  return true if @requirements.length > 1 # GIGO, > 1, > 2 is silly

  not %w[> >=].include? @requirements.first.first # grab the operator
end

#to_sObject

:nodoc:



257
258
259
# File 'lib/gel/support/gem_requirement.rb', line 257

def to_s # :nodoc:
  as_list.join ", "
end

#to_yaml_propertiesObject

:nodoc:



213
214
215
# File 'lib/gel/support/gem_requirement.rb', line 213

def to_yaml_properties # :nodoc:
  ["@requirements"]
end

#yaml_initialize(tag, vals) ⇒ Object

:nodoc:



203
204
205
206
207
# File 'lib/gel/support/gem_requirement.rb', line 203

def yaml_initialize(tag, vals) # :nodoc:
  vals.each do |ivar, val|
    instance_variable_set "@#{ivar}", val
  end
end