dependabot-core 0.84.1 → 0.85.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,179 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Java versions use dots and dashes when tokenising their versions.
4
- # Gem::Version converts a "-" to ".pre.", so we override the `to_s` method.
5
- #
6
- # See https://maven.apache.org/pom.html#Version_Order_Specification for details.
7
-
8
- module Dependabot
9
- module Utils
10
- module Java
11
- class Version < Gem::Version
12
- NULL_VALUES = %w(0 final ga).freeze
13
- PREFIXED_TOKEN_HIERARCHY = {
14
- "." => { qualifier: 1, number: 4 },
15
- "-" => { qualifier: 2, number: 3 }
16
- }.freeze
17
- NAMED_QUALIFIERS_HIERARCHY = {
18
- "a" => 1, "alpha" => 1,
19
- "b" => 2, "beta" => 2,
20
- "m" => 3, "milestone" => 3,
21
- "rc" => 4, "cr" => 4,
22
- "snapshot" => 5,
23
- "ga" => 6, "" => 6, "final" => 6,
24
- "sp" => 7
25
- }.freeze
26
- VERSION_PATTERN =
27
- '[0-9a-zA-Z]+(?>\.[0-9a-zA-Z]*)*(-[0-9A-Za-z-]*(\.[0-9A-Za-z-]*)*)?'
28
- ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze
29
-
30
- def self.correct?(version)
31
- return false if version.nil?
32
-
33
- version.to_s.match?(ANCHORED_VERSION_PATTERN)
34
- end
35
-
36
- def initialize(version)
37
- @version_string = version.to_s
38
- super(version.to_s.tr("_", "-"))
39
- end
40
-
41
- def to_s
42
- @version_string
43
- end
44
-
45
- def prerelease?
46
- tokens.any? do |token|
47
- next false unless NAMED_QUALIFIERS_HIERARCHY[token]
48
-
49
- NAMED_QUALIFIERS_HIERARCHY[token] < 6
50
- end
51
- end
52
-
53
- private
54
-
55
- def tokens
56
- @tokens ||=
57
- begin
58
- version = @version_string.to_s.downcase
59
- version = fill_tokens(version)
60
- version = trim_version(version)
61
- split_into_prefixed_tokens(version).map { |t| t[1..-1] }
62
- end
63
- end
64
-
65
- def <=>(other)
66
- version = stringify_version(@version_string)
67
- version = fill_tokens(version)
68
- version = trim_version(version)
69
-
70
- other_version = stringify_version(other)
71
- other_version = fill_tokens(other_version)
72
- other_version = trim_version(other_version)
73
-
74
- version, other_version = convert_dates(version, other_version)
75
-
76
- prefixed_tokens = split_into_prefixed_tokens(version)
77
- other_prefixed_tokens = split_into_prefixed_tokens(other_version)
78
-
79
- prefixed_tokens, other_prefixed_tokens =
80
- pad_for_comparison(prefixed_tokens, other_prefixed_tokens)
81
-
82
- prefixed_tokens.count.times.each do |index|
83
- comp = compare_prefixed_token(
84
- prefix: prefixed_tokens[index][0],
85
- token: prefixed_tokens[index][1..-1] || "",
86
- other_prefix: other_prefixed_tokens[index][0],
87
- other_token: other_prefixed_tokens[index][1..-1] || ""
88
- )
89
- return comp unless comp.zero?
90
- end
91
-
92
- 0
93
- end
94
-
95
- def stringify_version(version)
96
- version = version.to_s.downcase
97
-
98
- # Not technically correct, but pragmatic
99
- version.gsub(/^v(?=\d)/, "")
100
- end
101
-
102
- def fill_tokens(version)
103
- # Add separators when transitioning from digits to characters
104
- version = version.gsub(/(\d)([A-Za-z])/, '\1-\2')
105
- version = version.gsub(/([A-Za-z])(\d)/, '\1-\2')
106
-
107
- # Replace empty tokens with 0
108
- version = version.gsub(/([\.\-])([\.\-])/, '\10\2')
109
- version = version.gsub(/^([\.\-])/, '0\1')
110
- version.gsub(/([\.\-])$/, '\10')
111
- end
112
-
113
- def trim_version(version)
114
- version.split("-").map do |v|
115
- parts = v.split(".")
116
- parts = parts[0..-2] while NULL_VALUES.include?(parts&.last)
117
- parts&.join(".")
118
- end.compact.reject(&:empty?).join("-")
119
- end
120
-
121
- def convert_dates(version, other_version)
122
- default = [version, other_version]
123
- return default unless version.match?(/^\d{4}-?\d{2}-?\d{2}$/)
124
- return default unless other_version.match?(/^\d{4}-?\d{2}-?\d{2}$/)
125
-
126
- [version.delete("-"), other_version.delete("-")]
127
- end
128
-
129
- def split_into_prefixed_tokens(version)
130
- ".#{version}".split(/(?=[\-\.])/)
131
- end
132
-
133
- def pad_for_comparison(prefixed_tokens, other_prefixed_tokens)
134
- prefixed_tokens = prefixed_tokens.dup
135
- other_prefixed_tokens = other_prefixed_tokens.dup
136
-
137
- longest = [prefixed_tokens, other_prefixed_tokens].max_by(&:count)
138
- shortest = [prefixed_tokens, other_prefixed_tokens].min_by(&:count)
139
-
140
- longest.count.times do |index|
141
- next unless shortest[index].nil?
142
-
143
- shortest[index] = longest[index].start_with?(".") ? ".0" : "-"
144
- end
145
-
146
- [prefixed_tokens, other_prefixed_tokens]
147
- end
148
-
149
- def compare_prefixed_token(prefix:, token:, other_prefix:, other_token:)
150
- token_type = token.match?(/^\d+$/) ? :number : :qualifier
151
- other_token_type = other_token.match?(/^\d+$/) ? :number : :qualifier
152
-
153
- hierarchy = PREFIXED_TOKEN_HIERARCHY.fetch(prefix).fetch(token_type)
154
- other_hierarchy =
155
- PREFIXED_TOKEN_HIERARCHY.fetch(other_prefix).fetch(other_token_type)
156
-
157
- hierarchy_comparison = hierarchy <=> other_hierarchy
158
- return hierarchy_comparison unless hierarchy_comparison.zero?
159
-
160
- compare_token(token: token, other_token: other_token)
161
- end
162
-
163
- def compare_token(token:, other_token:)
164
- if (token_hierarchy = NAMED_QUALIFIERS_HIERARCHY[token])
165
- return -1 unless NAMED_QUALIFIERS_HIERARCHY[other_token]
166
-
167
- return token_hierarchy <=> NAMED_QUALIFIERS_HIERARCHY[other_token]
168
- end
169
-
170
- return 1 if NAMED_QUALIFIERS_HIERARCHY[other_token]
171
-
172
- token = token.to_i if token.match?(/^\d+$/)
173
- other_token = other_token.to_i if other_token.match?(/^\d+$/)
174
- token <=> other_token
175
- end
176
- end
177
- end
178
- end
179
- end