Class: Philiprehberger::Semver::Version

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

Overview

Immutable SemVer 2.0.0 version value object.

Includes Comparable, so standard Ruby comparison operators work per SemVer 2.0.0 precedence rules.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(major, minor, patch, pre_release: nil, build_metadata: nil) ⇒ Version

Returns a new instance of Version.

Parameters:

  • major (Integer, String)

    major version

  • minor (Integer, String)

    minor version

  • patch (Integer, String)

    patch version

  • pre_release (String, nil) (defaults to: nil)

    pre-release identifier (without leading -)

  • build_metadata (String, nil) (defaults to: nil)

    build metadata (without leading +++)



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

def initialize(major, minor, patch, pre_release: nil, build_metadata: nil)
  @major = major.to_i
  @minor = minor.to_i
  @patch = patch.to_i
  @pre_release = pre_release
  @build_metadata = 
  freeze
end

Instance Attribute Details

#build_metadataString? (readonly)

Returns the build metadata string, or nil.

Returns:

  • (String, nil)

    the build metadata string, or nil



25
26
27
# File 'lib/philiprehberger/semver/version.rb', line 25

def 
  @build_metadata
end

#majorInteger (readonly)

Returns the major version number.

Returns:

  • (Integer)

    the major version number



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

def major
  @major
end

#minorInteger (readonly)

Returns the minor version number.

Returns:

  • (Integer)

    the minor version number



16
17
18
# File 'lib/philiprehberger/semver/version.rb', line 16

def minor
  @minor
end

#patchInteger (readonly)

Returns the patch version number.

Returns:

  • (Integer)

    the patch version number



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

def patch
  @patch
end

#pre_releaseString? (readonly)

Returns the pre-release identifier string, or nil.

Returns:

  • (String, nil)

    the pre-release identifier string, or nil



22
23
24
# File 'lib/philiprehberger/semver/version.rb', line 22

def pre_release
  @pre_release
end

Instance Method Details

#<=>(other) ⇒ Integer?

Compare two versions per SemVer 2.0.0 precedence rules.

Build metadata is ignored. Pre-release versions sort lower than their release counterpart; pre-release identifiers are compared token-by-token (numerics numerically, alphas lexicographically).

Parameters:

  • other (Version)

    the other version to compare against

Returns:



49
50
51
52
53
54
55
56
# File 'lib/philiprehberger/semver/version.rb', line 49

def <=>(other)
  return nil unless other.is_a?(Version)

  result = [major, minor, patch] <=> [other.major, other.minor, other.patch]
  return result unless result.zero?

  compare_pre_release(pre_release, other.pre_release)
end

#bump(level) ⇒ Version

Return a new Philiprehberger::Semver::Version with the given level bumped.

Lower segments are reset to zero, and any pre-release / build metadata is dropped.

Parameters:

  • level (Symbol)

    one of :major, :minor, or :patch

Returns:

  • (Version)

    a new bumped version

Raises:

  • (Error)

    if level is not a recognized symbol



66
67
68
69
70
71
72
73
# File 'lib/philiprehberger/semver/version.rb', line 66

def bump(level)
  case level
  when :major then self.class.new(major + 1, 0, 0)
  when :minor then self.class.new(major, minor + 1, 0)
  when :patch then self.class.new(major, minor, patch + 1)
  else raise Error, "unknown bump level: #{level}"
  end
end

#next_pre_release(label: 'alpha') ⇒ Version

Return a new Philiprehberger::Semver::Version with its pre-release identifier iterated.

When self is stable (no pre-release), the result is promoted to a pre-release using the given label with a numeric suffix of 1 (e.g. 1.2.3 with label: ‘alpha’ becomes 1.2.3-alpha.1).

When self is already a pre-release, the label keyword is ignored and the existing pre-release string is iterated:

  • if the last dot-separated token is numeric, that token is incremented (alpha.1 -> alpha.2, rc.4 -> rc.5)

  • otherwise .1 is appended (rc -> rc.1, alpha.beta -> alpha.beta.1)

build_metadata is preserved on the returned Philiprehberger::Semver::Version. self is not mutated.

Parameters:

  • label (String) (defaults to: 'alpha')

    pre-release label to use when promoting a stable version. Ignored when self is already a pre-release.

Returns:



94
95
96
97
98
99
100
101
102
103
# File 'lib/philiprehberger/semver/version.rb', line 94

def next_pre_release(label: 'alpha')
  new_pre_release =
    if pre_release.nil?
      "#{label}.1"
    else
      iterate_pre_release(pre_release)
    end

  self.class.new(major, minor, patch, pre_release: new_pre_release, build_metadata: )
end

#pre_release?Boolean

Returns true if the version has a pre-release segment.

Returns:

  • (Boolean)

    true if the version has a pre-release segment



119
120
121
# File 'lib/philiprehberger/semver/version.rb', line 119

def pre_release?
  !@pre_release.nil?
end

#prerelease_identifiersArray<String>

Return the dot-separated pre-release identifiers as an array.

Numeric identifiers remain strings (SemVer-compliant identifiers are strings even when numeric). Returns an empty array when the version has no pre-release segment.

Returns:

  • (Array<String>)

    the pre-release identifiers, or [] if none



112
113
114
115
116
# File 'lib/philiprehberger/semver/version.rb', line 112

def prerelease_identifiers
  return [] if @pre_release.nil?

  @pre_release.split('.')
end

#stable?Boolean

Returns true if major >= 1 and there is no pre-release.

Returns:

  • (Boolean)

    true if major >= 1 and there is no pre-release



124
125
126
# File 'lib/philiprehberger/semver/version.rb', line 124

def stable?
  @pre_release.nil? && @major >= 1
end

#to_aArray<Integer>

Returns [major, minor, patch].

Returns:

  • (Array<Integer>)

    [major, minor, patch]



129
130
131
# File 'lib/philiprehberger/semver/version.rb', line 129

def to_a
  [@major, @minor, @patch]
end

#to_sString

Returns the canonical SemVer string.

Returns:

  • (String)

    the canonical SemVer string



134
135
136
137
138
139
# File 'lib/philiprehberger/semver/version.rb', line 134

def to_s
  str = "#{major}.#{minor}.#{patch}"
  str = "#{str}-#{pre_release}" if pre_release
  str = "#{str}+#{}" if 
  str
end