dependabot-bazel 0.344.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/dependabot/bazel/file_fetcher.rb +108 -0
- data/lib/dependabot/bazel/file_parser/starlark_parser.rb +359 -0
- data/lib/dependabot/bazel/file_parser.rb +358 -0
- data/lib/dependabot/bazel/file_updater/bzlmod_file_updater.rb +99 -0
- data/lib/dependabot/bazel/file_updater/declaration_parser.rb +78 -0
- data/lib/dependabot/bazel/file_updater/workspace_file_updater.rb +203 -0
- data/lib/dependabot/bazel/file_updater.rb +116 -0
- data/lib/dependabot/bazel/language.rb +26 -0
- data/lib/dependabot/bazel/metadata_finder.rb +28 -0
- data/lib/dependabot/bazel/package_manager.rb +43 -0
- data/lib/dependabot/bazel/requirement.rb +62 -0
- data/lib/dependabot/bazel/update_checker/registry_client.rb +133 -0
- data/lib/dependabot/bazel/update_checker/requirements_updater.rb +35 -0
- data/lib/dependabot/bazel/update_checker.rb +186 -0
- data/lib/dependabot/bazel/version.rb +24 -0
- data/lib/dependabot/bazel.rb +21 -0
- metadata +283 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9986d6161f75df0b7e9dc46b647dea94ceade605c4dda498b45ef01eed1af9ee
|
|
4
|
+
data.tar.gz: 15a41ede5c5d7dcb66129029f708e5b307790c7a4e68ad7d561653806201de68
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d3b028ba705574ade315d9c1c0b181f5ddf6cddd7b87edbfd2438ae8a177f6909c7c97765a4e48c442063978797e7e544957ebc1949d8eea4319f3b42bac5074
|
|
7
|
+
data.tar.gz: 2c1c9f95ab54ad3b4107d0d5138d658f68e5a22503f989eed42961146bb347c6470b371ea2a150ceedcbf3fdbf586b98179e7a7cd1b499e4a2c67ab2df7b9734
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "dependabot/file_fetchers"
|
|
5
|
+
require "dependabot/file_fetchers/base"
|
|
6
|
+
|
|
7
|
+
module Dependabot
|
|
8
|
+
module Bazel
|
|
9
|
+
class FileFetcher < Dependabot::FileFetchers::Base
|
|
10
|
+
extend T::Sig
|
|
11
|
+
|
|
12
|
+
WORKSPACE_FILES = T.let(%w(WORKSPACE WORKSPACE.bazel).freeze, T::Array[String])
|
|
13
|
+
MODULE_FILES = T.let(%w(MODULE.bazel).freeze, T::Array[String])
|
|
14
|
+
CONFIG_FILES = T.let(%w(.bazelrc MODULE.bazel.lock).freeze, T::Array[String])
|
|
15
|
+
SKIP_DIRECTORIES = T.let(%w(.git .bazel-* bazel-* node_modules .github).freeze, T::Array[String])
|
|
16
|
+
|
|
17
|
+
sig { override.returns(String) }
|
|
18
|
+
def self.required_files_message
|
|
19
|
+
"Repo must contain a WORKSPACE, WORKSPACE.bazel, or MODULE.bazel file."
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
sig { override.params(filenames: T::Array[String]).returns(T::Boolean) }
|
|
23
|
+
def self.required_files_in?(filenames)
|
|
24
|
+
filenames.any? { |name| WORKSPACE_FILES.include?(name) || MODULE_FILES.include?(name) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
sig { override.returns(T::Array[DependencyFile]) }
|
|
28
|
+
def fetch_files
|
|
29
|
+
unless allow_beta_ecosystems?
|
|
30
|
+
raise Dependabot::DependencyFileNotFound.new(
|
|
31
|
+
nil,
|
|
32
|
+
"Bazel support is currently in beta. To enable it, add `enable_beta_ecosystems: true` to the" \
|
|
33
|
+
" top-level of your `dependabot.yml`. See " \
|
|
34
|
+
"https://docs.github.com/en/code-security/dependabot/working-with-dependabot" \
|
|
35
|
+
"/dependabot-options-reference#enable-beta-ecosystems for details."
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
fetched_files = T.let([], T::Array[DependencyFile])
|
|
40
|
+
fetched_files += workspace_files
|
|
41
|
+
fetched_files += module_files
|
|
42
|
+
fetched_files += config_files
|
|
43
|
+
|
|
44
|
+
return fetched_files if fetched_files.any?
|
|
45
|
+
|
|
46
|
+
raise Dependabot::DependencyFileNotFound.new(nil, self.class.required_files_message)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
sig { override.returns(T.nilable(T::Hash[Symbol, T.untyped])) }
|
|
50
|
+
def ecosystem_versions
|
|
51
|
+
bazel_version = "unknown"
|
|
52
|
+
|
|
53
|
+
bazelversion_file = fetch_file_if_present(".bazelversion")
|
|
54
|
+
bazel_version = T.must(bazelversion_file.content).strip if bazelversion_file
|
|
55
|
+
|
|
56
|
+
{ package_managers: { "bazel" => bazel_version } }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
sig { returns(T::Array[DependencyFile]) }
|
|
62
|
+
def workspace_files
|
|
63
|
+
files = T.let([], T::Array[DependencyFile])
|
|
64
|
+
|
|
65
|
+
WORKSPACE_FILES.each do |filename|
|
|
66
|
+
file = fetch_file_if_present(filename)
|
|
67
|
+
files << file if file
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
files
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
sig { returns(T::Array[DependencyFile]) }
|
|
74
|
+
def module_files
|
|
75
|
+
files = T.let([], T::Array[DependencyFile])
|
|
76
|
+
|
|
77
|
+
MODULE_FILES.each do |filename|
|
|
78
|
+
file = fetch_file_if_present(filename)
|
|
79
|
+
files << file if file
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
files
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
sig { returns(T::Array[DependencyFile]) }
|
|
86
|
+
def config_files
|
|
87
|
+
files = T.let([], T::Array[DependencyFile])
|
|
88
|
+
|
|
89
|
+
CONFIG_FILES.each do |filename|
|
|
90
|
+
file = fetch_file_if_present(filename)
|
|
91
|
+
files << file if file
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
bazelversion = fetch_file_if_present(".bazelversion")
|
|
95
|
+
files << bazelversion if bazelversion
|
|
96
|
+
|
|
97
|
+
files
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
sig { params(dirname: String).returns(T::Boolean) }
|
|
101
|
+
def should_skip_directory?(dirname)
|
|
102
|
+
SKIP_DIRECTORIES.any? { |skip_dir| dirname.start_with?(skip_dir) }
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
Dependabot::FileFetchers.register("bazel", Dependabot::Bazel::FileFetcher)
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
require "dependabot/bazel/file_parser"
|
|
6
|
+
|
|
7
|
+
module Dependabot
|
|
8
|
+
module Bazel
|
|
9
|
+
class FileParser
|
|
10
|
+
class StarlarkParser
|
|
11
|
+
extend T::Sig
|
|
12
|
+
|
|
13
|
+
class FunctionCall < T::Struct
|
|
14
|
+
const :name, String
|
|
15
|
+
const :arguments, T::Hash[String, T.untyped]
|
|
16
|
+
const :positional_arguments, T::Array[T.untyped]
|
|
17
|
+
const :line, Integer
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
sig { params(content: String).void }
|
|
21
|
+
def initialize(content)
|
|
22
|
+
@content = content
|
|
23
|
+
@position = T.let(0, Integer)
|
|
24
|
+
@line = T.let(1, Integer)
|
|
25
|
+
@length = T.let(content.length, Integer)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
sig { returns(T::Array[FunctionCall]) }
|
|
29
|
+
def parse_function_calls
|
|
30
|
+
function_calls = T.let([], T::Array[FunctionCall])
|
|
31
|
+
|
|
32
|
+
while @position < @length
|
|
33
|
+
skip_whitespace_and_comments
|
|
34
|
+
|
|
35
|
+
next unless @position < @length
|
|
36
|
+
|
|
37
|
+
start_position = @position
|
|
38
|
+
function_call = try_parse_function_call
|
|
39
|
+
function_calls << function_call if function_call
|
|
40
|
+
|
|
41
|
+
move_to_next_char if @position == start_position
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
function_calls
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
sig { returns(T.nilable(String)) }
|
|
50
|
+
def current_char
|
|
51
|
+
return nil if @position >= @length
|
|
52
|
+
|
|
53
|
+
@content[@position]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
sig { params(offset: Integer).returns(T.nilable(String)) }
|
|
57
|
+
def peek_char(offset = 1)
|
|
58
|
+
peek_pos = @position + offset
|
|
59
|
+
return nil if peek_pos >= @length
|
|
60
|
+
|
|
61
|
+
@content[peek_pos]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
sig { void }
|
|
65
|
+
def move_to_next_char
|
|
66
|
+
@line += 1 if current_char == "\n"
|
|
67
|
+
@position += 1
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
sig { void }
|
|
71
|
+
def skip_whitespace_and_comments
|
|
72
|
+
while @position < @length
|
|
73
|
+
case current_char
|
|
74
|
+
when /\s/
|
|
75
|
+
move_to_next_char
|
|
76
|
+
when "#"
|
|
77
|
+
move_to_next_char while current_char && current_char != "\n"
|
|
78
|
+
move_to_next_char if current_char == "\n"
|
|
79
|
+
else
|
|
80
|
+
break
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
sig { returns(T.nilable(FunctionCall)) }
|
|
86
|
+
def try_parse_function_call
|
|
87
|
+
start_line = @line
|
|
88
|
+
|
|
89
|
+
function_name = parse_identifier
|
|
90
|
+
return nil unless function_name
|
|
91
|
+
|
|
92
|
+
skip_whitespace_and_comments
|
|
93
|
+
|
|
94
|
+
return nil unless current_char == "("
|
|
95
|
+
|
|
96
|
+
move_to_next_char
|
|
97
|
+
|
|
98
|
+
keyword_arguments, positional_arguments = parse_function_arguments
|
|
99
|
+
|
|
100
|
+
skip_whitespace_and_comments
|
|
101
|
+
return nil unless current_char == ")"
|
|
102
|
+
|
|
103
|
+
move_to_next_char
|
|
104
|
+
|
|
105
|
+
FunctionCall.new(
|
|
106
|
+
name: function_name,
|
|
107
|
+
arguments: keyword_arguments,
|
|
108
|
+
positional_arguments: positional_arguments,
|
|
109
|
+
line: start_line
|
|
110
|
+
)
|
|
111
|
+
rescue StandardError
|
|
112
|
+
move_to_next_char while current_char && current_char != "\n"
|
|
113
|
+
move_to_next_char if current_char == "\n"
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
sig { returns(T.nilable(String)) }
|
|
118
|
+
def parse_identifier
|
|
119
|
+
return nil unless current_char&.match?(/[a-zA-Z_]/)
|
|
120
|
+
|
|
121
|
+
identifier = T.let("", String)
|
|
122
|
+
while current_char&.match?(/[a-zA-Z0-9_]/)
|
|
123
|
+
char = current_char
|
|
124
|
+
identifier += char if char
|
|
125
|
+
move_to_next_char
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
identifier.empty? ? nil : identifier
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
sig { returns([T::Hash[String, T.untyped], T::Array[T.untyped]]) }
|
|
132
|
+
def parse_function_arguments
|
|
133
|
+
keyword_arguments = T.let({}, T::Hash[String, T.untyped])
|
|
134
|
+
positional_arguments = T.let([], T::Array[T.untyped])
|
|
135
|
+
|
|
136
|
+
skip_whitespace_and_comments
|
|
137
|
+
|
|
138
|
+
return [keyword_arguments, positional_arguments] if current_char == ")"
|
|
139
|
+
|
|
140
|
+
loop do
|
|
141
|
+
skip_whitespace_and_comments
|
|
142
|
+
break if current_char == ")"
|
|
143
|
+
|
|
144
|
+
if (keyword_arg = parse_keyword_argument)
|
|
145
|
+
keyword_arguments.merge!(keyword_arg)
|
|
146
|
+
else
|
|
147
|
+
positional_value = parse_value
|
|
148
|
+
positional_arguments << positional_value if positional_value
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
skip_whitespace_and_comments
|
|
152
|
+
|
|
153
|
+
break if current_char == ")"
|
|
154
|
+
|
|
155
|
+
break unless current_char == ","
|
|
156
|
+
|
|
157
|
+
move_to_next_char
|
|
158
|
+
skip_whitespace_and_comments
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
[keyword_arguments, positional_arguments]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
sig { returns(T.nilable(T::Hash[String, T.untyped])) }
|
|
165
|
+
def parse_keyword_argument
|
|
166
|
+
start_pos = @position
|
|
167
|
+
start_line = @line
|
|
168
|
+
|
|
169
|
+
param_name = parse_identifier
|
|
170
|
+
return nil unless param_name
|
|
171
|
+
|
|
172
|
+
skip_whitespace_and_comments
|
|
173
|
+
|
|
174
|
+
unless current_char == "="
|
|
175
|
+
@position = start_pos
|
|
176
|
+
@line = start_line
|
|
177
|
+
return nil
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
move_to_next_char
|
|
181
|
+
skip_whitespace_and_comments
|
|
182
|
+
|
|
183
|
+
value = parse_value
|
|
184
|
+
return nil if value.nil?
|
|
185
|
+
|
|
186
|
+
{ param_name => value }
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
sig { returns(T.untyped) }
|
|
190
|
+
def parse_value
|
|
191
|
+
skip_whitespace_and_comments
|
|
192
|
+
|
|
193
|
+
case current_char
|
|
194
|
+
when '"', "'"
|
|
195
|
+
parse_string
|
|
196
|
+
when /[0-9]/
|
|
197
|
+
parse_number
|
|
198
|
+
when "["
|
|
199
|
+
parse_array
|
|
200
|
+
when /[a-zA-Z_]/
|
|
201
|
+
identifier = parse_identifier
|
|
202
|
+
case identifier
|
|
203
|
+
when "True"
|
|
204
|
+
true
|
|
205
|
+
when "False"
|
|
206
|
+
false
|
|
207
|
+
when "None"
|
|
208
|
+
nil
|
|
209
|
+
else
|
|
210
|
+
identifier
|
|
211
|
+
end
|
|
212
|
+
else
|
|
213
|
+
parse_unknown_value
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
sig { returns(T.nilable(String)) }
|
|
218
|
+
def parse_string
|
|
219
|
+
quote_char = current_char
|
|
220
|
+
return nil unless quote_char == '"' || quote_char == "'"
|
|
221
|
+
|
|
222
|
+
move_to_next_char
|
|
223
|
+
string_value = T.let("", String)
|
|
224
|
+
|
|
225
|
+
while current_char && current_char != quote_char
|
|
226
|
+
if current_char == "\\"
|
|
227
|
+
string_value += parse_escape_sequence
|
|
228
|
+
elsif current_char
|
|
229
|
+
string_value += T.must(current_char)
|
|
230
|
+
end
|
|
231
|
+
move_to_next_char
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
move_to_next_char if current_char == quote_char
|
|
235
|
+
string_value
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
sig { returns(String) }
|
|
239
|
+
def parse_escape_sequence
|
|
240
|
+
move_to_next_char
|
|
241
|
+
case current_char
|
|
242
|
+
when "n"
|
|
243
|
+
"\n"
|
|
244
|
+
when "t"
|
|
245
|
+
"\t"
|
|
246
|
+
when "r"
|
|
247
|
+
"\r"
|
|
248
|
+
when "\\"
|
|
249
|
+
"\\"
|
|
250
|
+
when '"'
|
|
251
|
+
'"'
|
|
252
|
+
when "'"
|
|
253
|
+
"'"
|
|
254
|
+
else
|
|
255
|
+
current_char.to_s
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
sig { returns(T.untyped) }
|
|
260
|
+
def parse_number
|
|
261
|
+
number_str = T.let("", String)
|
|
262
|
+
|
|
263
|
+
while current_char&.match?(/[0-9.]/)
|
|
264
|
+
char = current_char
|
|
265
|
+
number_str += char if char
|
|
266
|
+
move_to_next_char
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
return nil if number_str.empty?
|
|
270
|
+
|
|
271
|
+
number_str.include?(".") ? number_str.to_f : number_str.to_i
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
sig { returns(T.nilable(T::Array[T.untyped])) }
|
|
275
|
+
def parse_array
|
|
276
|
+
return nil unless current_char == "["
|
|
277
|
+
|
|
278
|
+
move_to_next_char
|
|
279
|
+
|
|
280
|
+
array_items = T.let([], T::Array[T.untyped])
|
|
281
|
+
|
|
282
|
+
skip_whitespace_and_comments
|
|
283
|
+
|
|
284
|
+
if current_char == "]"
|
|
285
|
+
move_to_next_char
|
|
286
|
+
return array_items
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
loop do
|
|
290
|
+
skip_whitespace_and_comments
|
|
291
|
+
break if current_char == "]"
|
|
292
|
+
|
|
293
|
+
value = parse_value
|
|
294
|
+
array_items << value if value
|
|
295
|
+
|
|
296
|
+
skip_whitespace_and_comments
|
|
297
|
+
|
|
298
|
+
break if current_char == "]"
|
|
299
|
+
|
|
300
|
+
break unless current_char == ","
|
|
301
|
+
|
|
302
|
+
move_to_next_char
|
|
303
|
+
skip_whitespace_and_comments
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
move_to_next_char if current_char == "]"
|
|
307
|
+
array_items
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
sig { returns(T.nilable(String)) }
|
|
311
|
+
def parse_unknown_value
|
|
312
|
+
value = T.let("", String)
|
|
313
|
+
depth = 0
|
|
314
|
+
|
|
315
|
+
while current_char && @position < @length
|
|
316
|
+
char = current_char
|
|
317
|
+
|
|
318
|
+
case char
|
|
319
|
+
when "(", "[", "{"
|
|
320
|
+
depth += 1
|
|
321
|
+
when ")", "]", "}"
|
|
322
|
+
break unless depth.positive?
|
|
323
|
+
|
|
324
|
+
depth -= 1
|
|
325
|
+
when ","
|
|
326
|
+
break if depth.zero?
|
|
327
|
+
|
|
328
|
+
end
|
|
329
|
+
value += T.must(char)
|
|
330
|
+
|
|
331
|
+
move_to_next_char
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
value.strip.empty? ? nil : value.strip
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
sig { void }
|
|
338
|
+
def skip_to_next_argument
|
|
339
|
+
depth = 0
|
|
340
|
+
|
|
341
|
+
while current_char && @position < @length
|
|
342
|
+
case current_char
|
|
343
|
+
when "(", "[", "{"
|
|
344
|
+
depth += 1
|
|
345
|
+
when ")", "]", "}"
|
|
346
|
+
break unless depth.positive?
|
|
347
|
+
|
|
348
|
+
depth -= 1
|
|
349
|
+
when ","
|
|
350
|
+
break if depth.zero?
|
|
351
|
+
|
|
352
|
+
end
|
|
353
|
+
move_to_next_char
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
end
|