Class: Gem::Version

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/rubygems/version.rb,
lib/rubygems/requirement.rb

Constant Summary collapse

VERSION_PATTERN =

:nodoc:

'[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?'.freeze
ANCHORED_VERSION_PATTERN =

:nodoc:

/\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze
Requirement =

This is needed for compatibility with older yaml gemspecs.

Gem::Requirement
@@all =
{}
@@bump =
{}
@@release =
{}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(version) ⇒ Version

Constructs a Version from the version string. A version string is a series of digits or ASCII letters separated by dots.



214
215
216
217
218
219
220
221
222
223
224
# File 'lib/rubygems/version.rb', line 214

def initialize(version)
  unless self.class.correct?(version)
    raise ArgumentError, "Malformed version number string #{version}"
  end

  # If version is an empty string convert it to 0
  version = 0 if version.is_a?(String) && version =~ /\A\s*\Z/

  @version = version.to_s.strip.gsub("-",".pre.")
  @segments = nil
end

Class Method Details

.correct?(version) ⇒ Boolean

True if the version string matches RubyGems’ requirements.

Returns:

  • (Boolean)


174
175
176
177
178
179
180
# File 'lib/rubygems/version.rb', line 174

def self.correct?(version)
  unless Gem::Deprecate.skip
    warn "nil versions are discouraged and will be deprecated in Rubygems 4" if version.nil?
  end

  !!(version.to_s =~ ANCHORED_VERSION_PATTERN)
end

.create(input) ⇒ Object

Factory method to create a Version object. Input may be a Version or a String. Intended to simplify client code.

ver1 = Version.create('1.3.17')   # -> (Version object)
ver2 = Version.create(ver1)       # -> (ver1)
ver3 = Version.create(nil)        # -> nil


190
191
192
193
194
195
196
197
198
# File 'lib/rubygems/version.rb', line 190

def self.create(input)
  if self === input # check yourself before you wreck yourself
    input
  elsif input.nil?
    nil
  else
    new input
  end
end

.new(version) ⇒ Object

:nodoc:



204
205
206
207
208
# File 'lib/rubygems/version.rb', line 204

def self.new(version) # :nodoc:
  return super unless Gem::Version == self

  @@all[version] ||= super
end

Instance Method Details

#<=>(other) ⇒ Object

Compares this version with other returning -1, 0, or 1 if the other version is larger, the same, or smaller than this one. Attempts to compare to something that’s not a Gem::Version return nil.



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/rubygems/version.rb', line 346

def <=>(other)
  return unless Gem::Version === other
  return 0 if @version == other._version || canonical_segments == other.canonical_segments

  lhsegments = canonical_segments
  rhsegments = other.canonical_segments

  lhsize = lhsegments.size
  rhsize = rhsegments.size
  limit  = (lhsize > rhsize ? lhsize : rhsize) - 1

  i = 0

  while i <= limit
    lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
    i += 1

    next      if lhs == rhs
    return -1 if String  === lhs && Numeric === rhs
    return  1 if Numeric === lhs && String  === rhs

    return lhs <=> rhs
  end

  return 0
end

#approximate_recommendationObject

A recommended version for use with a ~> Requirement.



328
329
330
331
332
333
334
335
336
337
338
# File 'lib/rubygems/version.rb', line 328

def approximate_recommendation
  segments = self.segments

  segments.pop    while segments.any? {|s| String === s }
  segments.pop    while segments.size > 2
  segments.push 0 while segments.size < 2

  recommendation = "~> #{segments.join(".")}"
  recommendation += ".a" if prerelease?
  recommendation
end

#bumpObject

Return a new version object where the next to the last revision number is one greater (e.g., 5.3.1 => 5.4).

Pre-release (alpha) parts, e.g, 5.3.1.b.2 => 5.4, are ignored.



232
233
234
235
236
237
238
239
240
241
# File 'lib/rubygems/version.rb', line 232

def bump
  @@bump[self] ||= begin
                     segments = self.segments
                     segments.pop while segments.any? {|s| String === s }
                     segments.pop if segments.size > 1

                     segments[-1] = segments[-1].succ
                     self.class.new segments.join(".")
                   end
end

#canonical_segmentsObject



373
374
375
376
377
378
# File 'lib/rubygems/version.rb', line 373

def canonical_segments
  @canonical_segments ||=
    _split_segments.map! do |segments|
      segments.reverse_each.drop_while {|s| s == 0 }.reverse
    end.reduce(&:concat)
end

#encode_with(coder) ⇒ Object

:nodoc:



289
290
291
# File 'lib/rubygems/version.rb', line 289

def encode_with(coder) # :nodoc:
  coder.add 'version', @version
end

#eql?(other) ⇒ Boolean

A Version is only eql? to another version if it’s specified to the same precision. Version “1.0” is not the same as version “1”.

Returns:

  • (Boolean)


247
248
249
# File 'lib/rubygems/version.rb', line 247

def eql?(other)
  self.class === other and @version == other._version
end

#freezeObject



380
381
382
383
384
# File 'lib/rubygems/version.rb', line 380

def freeze
  prerelease?
  canonical_segments
  super
end

#hashObject

:nodoc:



251
252
253
# File 'lib/rubygems/version.rb', line 251

def hash # :nodoc:
  canonical_segments.hash
end

#init_with(coder) ⇒ Object

:nodoc:



255
256
257
# File 'lib/rubygems/version.rb', line 255

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

#inspectObject

:nodoc:



259
260
261
# File 'lib/rubygems/version.rb', line 259

def inspect # :nodoc:
  "#<#{self.class} #{version.inspect}>"
end

#marshal_dumpObject

Dump only the raw version string, not the complete object. It’s a string for backwards (RubyGems 1.3.5 and earlier) compatibility.



267
268
269
# File 'lib/rubygems/version.rb', line 267

def marshal_dump
  [version]
end

#marshal_load(array) ⇒ Object

Load custom marshal format. It’s a string for backwards (RubyGems 1.3.5 and earlier) compatibility.



275
276
277
# File 'lib/rubygems/version.rb', line 275

def marshal_load(array)
  initialize array[0]
end

#prerelease?Boolean

A version is considered a prerelease if it contains a letter.

Returns:

  • (Boolean)


296
297
298
299
300
301
# File 'lib/rubygems/version.rb', line 296

def prerelease?
  unless instance_variable_defined? :@prerelease
    @prerelease = !!(@version =~ /[a-zA-Z]/)
  end
  @prerelease
end

#pretty_print(q) ⇒ Object

:nodoc:



303
304
305
# File 'lib/rubygems/version.rb', line 303

def pretty_print(q) # :nodoc:
  q.text "Gem::Version.new(#{version.inspect})"
end

#releaseObject

The release for this version (e.g. 1.2.0.a -> 1.2.0). Non-prerelease versions return themselves.



311
312
313
314
315
316
317
318
319
# File 'lib/rubygems/version.rb', line 311

def release
  @@release[self] ||= if prerelease?
                        segments = self.segments
                        segments.pop while segments.any? {|s| String === s }
                        self.class.new segments.join('.')
                      else
                        self
                      end
end

#segmentsObject

:nodoc:



321
322
323
# File 'lib/rubygems/version.rb', line 321

def segments # :nodoc:
  _segments.dup
end

#to_yaml_propertiesObject

:nodoc:



285
286
287
# File 'lib/rubygems/version.rb', line 285

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

#versionObject Also known as: to_s

A string representation of this Version.



165
166
167
# File 'lib/rubygems/version.rb', line 165

def version
  @version.dup
end

#yaml_initialize(tag, map) ⇒ Object

:nodoc:



279
280
281
282
283
# File 'lib/rubygems/version.rb', line 279

def yaml_initialize(tag, map) # :nodoc:
  @version = map['version']
  @segments = nil
  @hash = nil
end