Class: VersionComponent

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_libversion.rb

Overview

This is a pure Ruby implementation of libversion, used as a fallback when the C extension is not available.

Constant Summary collapse

RANK_ORDERING =

Store the ranks in order, so that we can compare their indexes to determine which is greater.

%i[lower_bound pre_release zero post_release nonzero letter_suffix upper_bound]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(components, flags) ⇒ VersionComponent

Returns a new instance of VersionComponent.



9
10
11
12
13
14
# File 'lib/ruby_libversion.rb', line 9

def initialize(components, flags)
  # While we pass in a nil component to let determine_rank know we want padding, we set the actual value to 0 when we store it.
  @component = components[1].nil? ? '0' : components[1]

  @rank = determine_rank(components, flags)
end

Instance Attribute Details

#componentObject

Returns the value of attribute component.



4
5
6
# File 'lib/ruby_libversion.rb', line 4

def component
  @component
end

#rankObject

Returns the value of attribute rank.



4
5
6
# File 'lib/ruby_libversion.rb', line 4

def rank
  @rank
end

Instance Method Details

#<=>(other) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ruby_libversion.rb', line 54

def <=>(other)
  # Compare the rank of both components, and return the result unless they have the same rank.
  rank_comparison = RANK_ORDERING.index(self.rank) <=> RANK_ORDERING.index(other.rank)
  return rank_comparison unless rank_comparison.zero?

  # If both components are alphabetic, return the case-insensitive comparison of their first letters.
  return self.component[0].downcase <=> other.component[0].downcase if [self, other].none? { _1.component.match?(/[^[:alpha:]]/) }

  # If we are still here, return the integer comparison of both components.
  return self.component.to_i <=> other.component.to_i
end

#determine_rank(components, flags) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/ruby_libversion.rb', line 16

def determine_rank(components, flags)
  # If the current component is nil, it is padding.
  if components[1].nil?
    # When we are passed the lower bound flag, all padding is the lower_bound rank.
    if flags == Libversion::VERSIONFLAG_LOWER_BOUND
      return :lower_bound
    # When we are passed the upper bound flag, all padding is the upper_bound rank.
    elsif flags == Libversion::VERSIONFLAG_UPPER_BOUND
      return :upper_bound
    # If we have not been passed either bound flag, all padding is the zero rank.
    else
      return :zero
    end
  end

  # If the current component starts with a pre-release keyword (case insensitive), it is the pre_release rank.
  return :pre_release if components[1].downcase.start_with?('alpha', 'beta', 'rc', 'pre')

  # If the current component is an integer and has a value of zero, it is the zero rank.
  return :zero if Integer(components[1], exception: false)&.zero?

  # If the current component starts with a post-release keyword (case insensitive), or if the current component
  # starts with 'p' (case insensitive) and we were given the VERSIONFLAG_P_IS_PATCH flag, it is the post_release rank.
  return :post_release if components[1].start_with?('post', 'patch', 'pl', 'errata') || (flags == Libversion::VERSIONFLAG_P_IS_PATCH && components[1][0]&.downcase == 'p')

  # If the current component is an integer and has a nonzero value, it is the nonzero rank.
  return :nonzero if Integer(components[1], exception: false)&.nonzero?

  # If the previous component is an integer, the current component is alphabetic, and the next component is not an integer, the current component is the letter_suffix rank.
  return :letter_suffix unless Integer(components[0], exception: false).nil? || components[1].match?(/[^[:alpha:]]/) || !Integer(components[2], exception: false).nil?

  # If we were given the VERSIONFLAG_ANY_IS_PATCH flag, any remaining alphabetic component is of the post_release rank.
  return :post_release if flags == Libversion::VERSIONFLAG_ANY_IS_PATCH

  # Otherwise, any remaining alphabetic component is of the pre_release rank.
  return :pre_release
end

#empty?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/ruby_libversion.rb', line 66

def empty?
  @component.empty?
end