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 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