Class: Richcss::VersionKit::Version

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/richcss/vendor/version_kit/lib/version_kit/version.rb,
lib/richcss/vendor/version_kit/lib/version_kit/version/helper.rb,
lib/richcss/vendor/version_kit/lib/version_kit/version/components_helper.rb

Overview

Model class which provides support for versions according to the [Semantic Versioning Specification](semver.org).

Currently based on Semantic Versioning 2.0.0.

Example version: 1.2.3-rc.1+2014.01.01

Glossary:

  • version: a string representing a specific release of a software.

  • component: a version can have 3 components the number (1.2.3), the pre-release metadata (rc.1), and the Build component (2014.01.01).

  • identifier: each component in turn is composed by multiple identifier separated by a dot (like 1, 2, or 01).

  • bumping: the act of increasing by a single unit one identifier of the version.

Defined Under Namespace

Modules: ComponentsHelper, Helper

Constant Summary collapse

VERSION_PATTERN =

The components have the following characteristics:

  • Number component: Three dot-separated numeric elements.

  • Pre-release component: Hyphen, followed by any combination of digits, letters, or hyphens separated by periods.

  • Build component: Plus sign, followed by any combination of digits, letters, or hyphens separated by periods.

Returns:

  • (RegEx)

    The regular expression to use to validate a string representation of a version.

/\A
  [0-9]+\.[0-9]+\.[0-9]+           (?# Number component)
  ([-][0-9a-z-]+(\.[0-9a-z-]+)*)?  (?# Pre-release component)
  ([+][0-9a-z-]+(\.[0-9a-z-]+)*)?  (?# Build component)
\Z/xi

Instance Attribute Summary collapse

Class methods collapse

Semantic Versioning collapse

Object methods collapse

Instance Method Summary collapse

Constructor Details

#initialize(version_or_components) ⇒ Version

The Semantic Versioning Specification mandates a number component composed by 3 identifiers. Therefore strictly speaking 1 and 1.0 are not versions according the specification. This class accepts those values normalizing them to 1.0.0. To ensure strict adherence to the standard clients can use the Version::valid? method to check any string.

rubocop:disable MethodLength

Parameters:

  • version (#to_s, Array<Array<String, Fixnum>>)

    A representation of a version convertible to a string or the components of a version.

Raises:

  • If initialized with a string which cannot be converted to a version.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 63

def initialize(version_or_components)
  if version_or_components.is_a?(Array)
    components = self.class.normalize_components(version_or_components)
    unless ComponentsHelper.validate_components?(components)
      raise ArgumentError, "Malformed version components `#{components}`"
    end
    @components = components

  else
    version = self.class.normalize(version_or_components)
    unless self.class.valid?(version)
      raise ArgumentError, "Malformed version `#{version}`"
    end
    @components = ComponentsHelper.split_components(version)
  end
end

Instance Attribute Details

#componentsArray<Array<Fixnum,String>> (readonly)

version.

Returns:

  • (Array<Array<Fixnum,String>>)

    The list of the components of the



45
46
47
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 45

def components
  @components
end

Class Method Details

.normalize(version) ⇒ String

Normalizes the given string representation of a version by defaulting the minor and the patch version to 0 if possible.

Parameters:

  • version (#to_s)

    The string representation to normalize.

Returns:

  • (String)

    The normalized or the original version.



93
94
95
96
97
98
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 93

def self.normalize(version)
  version = version.to_s.strip
  version << '.0' if version  =~ /\A[0-9]+\Z/
  version << '.0' if version  =~ /\A[0-9]+\.[0-9]+\Z/
  version
end

.normalize_components(components) ⇒ Array

Normalizes the given version components by defaulting the minor and the patch version to 0 if possible.

Parameters:

  • components (Array<Array<String, Fixnum>>)

    The components to normalize.

Returns:

  • (Array)

    The normalized or the original components.



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 108

def self.normalize_components(components)
  if components.is_a?(Array) && components[0].is_a?(Array)
    count = components.count
    components = components.fill([], count, 3 - count) if count < 3

    number_count = components[0].count
    if number_count < 3
      components[0] = components[0].fill(0, number_count, 3 - number_count)
    end
  end

  components
end

.valid?(version) ⇒ Bool

Returns Whether a string representation of a version is can be accepted by this class. This comparison is much more lenient than the requirements described in the SemVer specification to support the diversity of versioning practices found in practice.

Returns:

  • (Bool)

    Whether a string representation of a version is can be accepted by this class. This comparison is much more lenient than the requirements described in the SemVer specification to support the diversity of versioning practices found in practice.



127
128
129
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 127

def self.valid?(version)
  !(version.to_s =~ VERSION_PATTERN).nil?
end

Instance Method Details

#<=>(other) ⇒ Fixnum, Nil

Note:

From semver.org:

  • Major, minor, and patch versions are always compared numerically.

  • When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version.

  • Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined by comparing each dot separated identifier from left to right until a difference is found as follows:

    • identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are compared lexically in ASCII sort order.

    • Numeric identifiers always have lower precedence than non-numeric identifiers.

    • A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal.

  • Build metadata SHOULD be ignored when determining version precedence.

Compares the instance to another version to determine how it sorts.

Parameters:

  • The (Object)

    object to compare.

Returns:

  • (Fixnum)

    -1 means self is smaller than other. 0 means self is equal to other. 1 means self is bigger than other.

  • (Nil)

    If the two objects could not be compared.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 259

def <=>(other)
  return nil unless other.class == self.class
  result = nil

  result ||= ComponentsHelper.compare_number_component(
    number_component, other.number_component
  )

  result ||= ComponentsHelper.compare_pre_release_component(
    pre_release_component, other.pre_release_component
  )

  result || 0
end

#==(other) ⇒ Bool

Returns:

  • (Bool)


207
208
209
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 207

def ==(other)
  to_s == other.to_s
end

#build_componentArray<String, Fixnum>

Returns The list of the identifiers of the build component.

Returns:

  • (Array<String, Fixnum>)

    The list of the identifiers of the build component.



151
152
153
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 151

def build_component
  @components[2]
end

#eql?(other) ⇒ Bool

Returns whether a hash should consider equal two versions for being used as a key. To be considered equal versions should be specified with the same precision (i.e. ‘’1.0’ != ‘1.0.0’‘)

Parameters:

  • The (Object)

    object to compare.

Returns:

  • (Bool)

    whether a hash should consider other as an equal key to the instance.



220
221
222
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 220

def eql?(other)
  self.class == other.class && to_s == other.to_s
end

#hashFixnum

Returns The hash value for this instance.

Returns:

  • (Fixnum)

    The hash value for this instance.



226
227
228
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 226

def hash
  [to_s].hash
end

#inspectString

Returns a string representation suitable for debugging.

Returns:

  • (String)

    a string representation suitable for debugging.



201
202
203
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 201

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

#major_versionFixnum

Returns The major version.

Returns:

  • (Fixnum)

    The major version.



157
158
159
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 157

def major_version
  number_component[0]
end

#minorFixnum

Returns The minor version.

Returns:

  • (Fixnum)

    The minor version.



163
164
165
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 163

def minor
  number_component[1]
end

#number_componentArray<Fixnum>

Returns The list of the identifiers of the number component.

Returns:

  • (Array<Fixnum>)

    The list of the identifiers of the number component.



137
138
139
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 137

def number_component
  @components[0]
end

#patchFixnum

Returns The patch version.

Returns:

  • (Fixnum)

    The patch version.



169
170
171
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 169

def patch
  number_component[2]
end

#pre_release?Boolean

Returns Indicates whether or not the version is a pre-release version.

Returns:

  • (Boolean)

    Indicates whether or not the version is a pre-release version.



176
177
178
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 176

def pre_release?
  !pre_release_component.empty?
end

#pre_release_componentArray<String, Fixnum>

Returns The list of the identifiers of the pre-release component.

Returns:

  • (Array<String, Fixnum>)

    The list of the identifiers of the pre-release component.



144
145
146
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 144

def pre_release_component
  @components[1]
end

#to_sString

Returns The string representation of the version.

Returns:

  • (String)

    The string representation of the version.



185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/richcss/vendor/version_kit/lib/version_kit/version.rb', line 185

def to_s
  result = number_component.join('.')

  if pre_release_component.count > 0
    result << '-' << pre_release_component.join('.')
  end

  if build_component.count > 0
    result << '+' << build_component.join('.')
  end

  result
end