Class: Vendor::Version

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/vendor/version.rb

Constant Summary collapse

VERSION_PATTERN =

:nodoc:

'[0-9]+(\.[0-9a-zA-Z]+)*'
ANCHORED_VERSION_PATTERN =

:nodoc:

/\A\s*(#{VERSION_PATTERN})*\s*\z/

Instance Attribute Summary collapse

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.

Raises:

  • (ArgumentError)


45
46
47
48
49
50
51
# File 'lib/vendor/version.rb', line 45

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

  @version = version.to_s
  @version.strip!
end

Instance Attribute Details

#versionObject (readonly) Also known as: to_s

A string representation of this Version.



13
14
15
# File 'lib/vendor/version.rb', line 13

def version
  @version
end

Class Method Details

.correct?(version) ⇒ Boolean

True if the version string matches Vendor’s requirements.

Returns:

  • (Boolean)


19
20
21
# File 'lib/vendor/version.rb', line 19

def self.correct? version
  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


31
32
33
34
35
36
37
38
39
# File 'lib/vendor/version.rb', line 31

def self.create input
  if input === Vendor::Version
    input
  elsif input.nil? then
    nil
  else
    new input
  end
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 Vendor::Version return nil.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/vendor/version.rb', line 148

def <=> other
  return unless Vendor::Version === other
  return 0 if @version == other.version

  lhsegments = segments
  rhsegments = other.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

#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.



59
60
61
62
63
64
65
66
# File 'lib/vendor/version.rb', line 59

def bump
  segments = self.segments.dup
  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

#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)


72
73
74
# File 'lib/vendor/version.rb', line 72

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

#inspectObject

:nodoc:



76
77
78
# File 'lib/vendor/version.rb', line 76

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.



84
85
86
# File 'lib/vendor/version.rb', line 84

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.



92
93
94
# File 'lib/vendor/version.rb', line 92

def marshal_load array
  initialize array[0]
end

#prerelease?Boolean

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

Returns:

  • (Boolean)


99
100
101
# File 'lib/vendor/version.rb', line 99

def prerelease?
  @prerelease ||= @version =~ /[a-zA-Z]/
end

#pretty_print(q) ⇒ Object

:nodoc:



103
104
105
# File 'lib/vendor/version.rb', line 103

def pretty_print q # :nodoc:
  q.text "Vendor::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.



111
112
113
114
115
116
117
# File 'lib/vendor/version.rb', line 111

def release
  return self unless prerelease?

  segments = self.segments.dup
  segments.pop while segments.any? { |s| String === s }
  self.class.new segments.join('.')
end

#segmentsObject

:nodoc:



119
120
121
122
123
124
125
126
127
# File 'lib/vendor/version.rb', line 119

def segments # :nodoc:

  # segments is lazy so it can pick up version values that come from
  # old marshaled versions, which don't go through marshal_load.

  @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
    /^\d+$/ =~ s ? s.to_i : s
  end
end

#spermy_recommendationObject

A recommended version for use with a ~> Requirement.



132
133
134
135
136
137
138
139
140
# File 'lib/vendor/version.rb', line 132

def spermy_recommendation
  segments = self.segments.dup

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

  "~> #{segments.join(".")}"
end