File: version.rb

package info (click to toggle)
ruby-semantic-range 3.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 100 kB
  • sloc: ruby: 731; makefile: 4
file content (155 lines) | stat: -rw-r--r-- 4,200 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
module SemanticRange
  VERSION = "3.0.0"

  class Version
    attr_reader :major, :minor, :patch, :prerelease

    def initialize(version, loose: false)
      @raw = version
      @loose = loose

      @raw = version.raw if version.is_a?(Version)

      match = @raw.to_s.strip.match(loose ? LOOSE : FULL)

      raise InvalidVersion.new(version) if match.nil?

      if String(version.to_s).length > MAX_LENGTH
        raise InvalidVersion.new("#{version} is too long")
      end

      @major = match[1] ? match[1].to_i : 0
      @minor = match[2] ? match[2].to_i : 0
      @patch = match[3] ? match[3].to_i : 0

      @prerelease = PreRelease.new match[4]

      @build = match[5] ? match[5].split('.') : []
    end

    def format
      v = "#{@major}.#{@minor}.#{@patch}"
      prerelease.length > 0 ? "#{v}-#{prerelease}" : v
    end

    def to_s
      @version
    end

    def version
      format
    end

    def raw
      version
    end

    def compare(other)
      other = Version.new(other, loose: @loose) unless other.is_a?(Version)
      res = truthy(compare_main(other)) || truthy(compare_pre(other))
      res.is_a?(FalseClass) ? 0 : res
    end

    def compare_main(other)
      other = Version.new(other, loose: @loose) unless other.is_a?(Version)
      truthy(self.class.compare_identifiers(@major, other.major)) ||
      truthy(self.class.compare_identifiers(@minor, other.minor)) ||
      truthy(self.class.compare_identifiers(@patch, other.patch))
    end

    def truthy(val)
      return val unless val.is_a?(Integer)
      val.zero? ? false : val
    end

    def compare_pre(other)
      prerelease <=> other.prerelease
    end

    def self.compare_identifiers(a,b)
      anum = /^[0-9]+$/.match(a.to_s)
      bnum = /^[0-9]+$/.match(b.to_s)

      if anum && bnum
        a = a.to_i
        b = b.to_i
      end

      return (anum && !bnum) ? -1 :
             (bnum && !anum) ? 1 :
             a < b ? -1 :
             a > b ? 1 :
             0;
    end

    def increment!(release, identifier)
      case release
      when 'premajor'
        @prerelease.clear!
        @patch = 0
        @minor = 0
        @major = @major + 1
        increment! 'pre', identifier
      when 'preminor'
        @prerelease.clear!
        @patch = 0
        @minor = @minor + 1
        increment! 'pre', identifier
      when 'prepatch'
        # If this is already a prerelease, it will bump to the next version
        # drop any prereleases that might already exist, since they are not
        # relevant at this point.
        @prerelease.clear!
        increment! 'patch', identifier
        increment! 'pre', identifier

        # If the input is a non-prerelease version, this acts the same as
        # prepatch.
      when 'prerelease'
        if @prerelease.empty?
          increment! 'patch', identifier
        end
        increment! 'pre', identifier
      when 'major'
        # If this is a pre-major version, bump up to the same major version.
        # Otherwise increment major.
        # 1.0.0-5 bumps to 1.0.0
        # 1.1.0 bumps to 2.0.0
        if @minor != 0 || @patch != 0 || @prerelease.empty?
          @major = @major + 1
        end
        @minor = 0
        @patch = 0
        @prerelease.clear!
      when 'minor'
        # If this is a pre-minor version, bump up to the same minor version.
        # Otherwise increment minor.
        # 1.2.0-5 bumps to 1.2.0
        # 1.2.1 bumps to 1.3.0
        if @patch != 0 || @prerelease.empty?
          @minor = @minor + 1
        end
        @patch = 0
        @prerelease.clear!
      when 'patch'
        # If this is not a pre-release version, it will increment the patch.
        # If it is a pre-release it will bump up to the same patch version.
        # 1.2.0-5 patches to 1.2.0
        # 1.2.0 patches to 1.2.1
        if @prerelease.empty?
          @patch = @patch + 1
        end
        @prerelease.clear!

        # This probably shouldn't be used publicly.
        # 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
      when 'pre'
        @prerelease.increment!(identifier)
      else
        raise InvalidIncrement.new release
      end

      self
    end
  end
end