@@ -9,8 +9,9 @@ load("@rules_pkg//pkg:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo"
9
9
load ("@rules_python//python:defs.bzl" , "py_binary" )
10
10
11
11
def _make_internal (name ):
12
- def internal (suffix = "internal" ):
13
- return "%s-%s" % (name , suffix )
12
+ def internal (suffix = "internal" , * args ):
13
+ args = (name , suffix ) + args
14
+ return "-" .join (args )
14
15
15
16
return internal
16
17
@@ -133,17 +134,63 @@ _extract_pkg_filegroup = rule(
133
134
} | _PLAT_DETECTION_ATTRS ,
134
135
)
135
136
136
- def _imported_zips_manifest_impl (ctx ):
137
+ _ZipInfo = provider (fields = {"zips_to_prefixes" : "mapping of zip files to prefixes" })
138
+
139
+ def _zip_info_impl (ctx ):
140
+ zips = {}
141
+ for zip_target , prefix in ctx .attr .srcs .items ():
142
+ for zip in zip_target .files .to_list ():
143
+ zips [zip ] = prefix
144
+ return [
145
+ _ZipInfo (zips_to_prefixes = zips ),
146
+ ]
147
+
148
+ _zip_info = rule (
149
+ implementation = _zip_info_impl ,
150
+ doc = """
151
+ This internal rule simply instantiates a _ZipInfo provider out of `zips`.
152
+ """ ,
153
+ attrs = {
154
+ "srcs" : attr .label_keyed_string_dict (
155
+ doc = "mapping from zip files to install prefixes" ,
156
+ allow_files = [".zip" ],
157
+ ),
158
+ },
159
+ )
160
+
161
+ def _zip_info_filter_impl (ctx ):
137
162
platform = _detect_platform (ctx )
163
+ filtered_zips = {}
164
+ for zip_info in ctx .attr .srcs :
165
+ for zip , prefix in zip_info [_ZipInfo ].zips_to_prefixes .items ():
166
+ zip_kind , expanded_prefix = _expand_path (prefix , platform )
167
+ if zip_kind == ctx .attr .kind :
168
+ filtered_zips [zip ] = expanded_prefix
169
+ return [
170
+ _ZipInfo (zips_to_prefixes = filtered_zips ),
171
+ ]
172
+
173
+ _zip_info_filter = rule (
174
+ implementation = _zip_info_filter_impl ,
175
+ doc = """
176
+ This internal rule transforms a _ZipInfo provider so that:
177
+ * only zips matching `kind` are included
178
+ * a kind of a zip is given by its prefix: if it contains {CODEQL_PLATFORM} it is arch, otherwise it's generic
179
+ * in the former case, {CODEQL_PLATFORM} is expanded
180
+ """ ,
181
+ attrs = {
182
+ "srcs" : attr .label_list (doc = "_ZipInfos to transform" , providers = [_ZipInfo ]),
183
+ "kind" : attr .string (doc = "Which zip kind to consider" , values = ["generic" , "arch" ]),
184
+ } | _PLAT_DETECTION_ATTRS ,
185
+ )
138
186
187
+ def _imported_zips_manifest_impl (ctx ):
139
188
manifest = []
140
189
files = []
141
- for zip , prefix in ctx .attr .zips .items ():
142
- # we don't care about the kind here, as we're taking all zips together
143
- _ , expanded_prefix = _expand_path (prefix , platform )
144
- zip_files = zip .files .to_list ()
145
- manifest += ["%s:%s" % (expanded_prefix , f .short_path ) for f in zip_files ]
146
- files += zip_files
190
+ for zip_info in ctx .attr .srcs :
191
+ zip_info = zip_info [_ZipInfo ]
192
+ manifest += ["%s:%s" % (p , z .short_path ) for z , p in zip_info .zips_to_prefixes .items ()]
193
+ files += list (zip_info .zips_to_prefixes )
147
194
148
195
output = ctx .actions .declare_file (ctx .label .name + ".params" )
149
196
ctx .actions .write (
@@ -162,30 +209,39 @@ _imported_zips_manifest = rule(
162
209
{CODEQL_PLATFORM} can be used as zip prefixes and will be expanded to the relevant codeql platform.
163
210
""" ,
164
211
attrs = {
165
- "zips " : attr .label_keyed_string_dict (
166
- doc = "mapping from zip files to install prefixes" ,
167
- allow_files = [".zip" ],
212
+ "srcs " : attr .label_list (
213
+ doc = "mappings from zip files to install prefixes in _ZipInfo format " ,
214
+ providers = [_ZipInfo ],
168
215
),
169
- } | _PLAT_DETECTION_ATTRS ,
216
+ },
170
217
)
171
218
172
219
def _zipmerge_impl (ctx ):
173
220
zips = []
174
- filename = ctx .attr .zip_name + "-"
175
- platform = _detect_platform (ctx )
176
- filename = "%s-%s.zip" % (ctx .attr .zip_name , platform if ctx .attr .kind == "arch" else "generic" )
177
- output = ctx .actions .declare_file (filename )
178
- args = [output .path , "--prefix=%s" % ctx .attr .prefix , ctx .file .base .path ]
179
- for zip , prefix in ctx .attr .zips .items ():
180
- zip_kind , expanded_prefix = _expand_path (prefix , platform )
181
- if zip_kind == ctx .attr .kind :
182
- args .append ("--prefix=%s/%s" % (ctx .attr .prefix , expanded_prefix .rstrip ("/" )))
183
- args += [f .path for f in zip .files .to_list ()]
184
- zips .append (zip .files )
221
+ transitive_zips = []
222
+ output = ctx .actions .declare_file (ctx .attr .out )
223
+ args = [output .path ]
224
+ for zip_target in ctx .attr .srcs :
225
+ if _ZipInfo in zip_target :
226
+ zip_info = zip_target [_ZipInfo ]
227
+ for zip , prefix in zip_info .zips_to_prefixes .items ():
228
+ args += [
229
+ "--prefix=%s/%s" % (ctx .attr .prefix , prefix .rstrip ("/" )),
230
+ zip .path ,
231
+ ]
232
+ zips .append (zip )
233
+ else :
234
+ zips = zip_target .files .to_list ()
235
+ for zip in zips :
236
+ if zip .extension != "zip" :
237
+ fail ("%s file found while expecting a .zip file " % zip .short_path )
238
+ args .append ("--prefix=%s" % ctx .attr .prefix )
239
+ args += [z .path for z in zips ]
240
+ transitive_zips .append (zip_target .files )
185
241
ctx .actions .run (
186
242
outputs = [output ],
187
243
executable = ctx .executable ._zipmerge ,
188
- inputs = depset ([ ctx . file . base ] , transitive = zips ),
244
+ inputs = depset (zips , transitive = transitive_zips ),
189
245
arguments = args ,
190
246
)
191
247
@@ -196,30 +252,22 @@ def _zipmerge_impl(ctx):
196
252
_zipmerge = rule (
197
253
implementation = _zipmerge_impl ,
198
254
doc = """
199
- This internal rule merges a `base` zip file with the ones indicated by the `zips` mapping where the prefix
200
- indicates a matching kind between arch and generic. An imported zip file will be considered arch-specific
201
- if its prefix contains `{CODEQL_PLATFORM}` (and this prefix will have that expanded to the appropriate
202
- platform).
203
-
204
- The output filename will be either `{zip_name}-generic.zip` or `{zip_name}-{CODEQL_PLATFORM}.zip`, depending on
205
- the requested `kind`.
255
+ This internal rule merges a zip files together
206
256
""" ,
207
257
attrs = {
208
- "base" : attr .label (
209
- doc = "Base zip file to which zips from `zips` will be merged with" ,
210
- allow_single_file = [".zip" ],
211
- ),
212
- "zips" : attr .label_keyed_string_dict (
213
- doc = "mapping from zip files to install prefixes" ,
214
- allow_files = [".zip" ],
215
- ),
216
- "zip_name" : attr .string (doc = "Prefix to use for the output file name" ),
217
- "kind" : attr .string (doc = "Which zip kind to consider" , values = ["generic" , "arch" ]),
258
+ "srcs" : attr .label_list (doc = "Zip file to include, either as straight up `.zip` files or `_ZipInfo` data" ),
259
+ "out" : attr .string (doc = "output file name" ),
218
260
"prefix" : attr .string (doc = "Prefix posix path to add to the zip contents in the archive" ),
219
261
"_zipmerge" : attr .label (default = "//misc/bazel/internal/zipmerge" , executable = True , cfg = "exec" ),
220
- } | _PLAT_DETECTION_ATTRS ,
262
+ },
221
263
)
222
264
265
+ def _get_zip_filename (name_prefix , kind ):
266
+ if kind == "arch" :
267
+ return name_prefix + "-" + _detect_platform () + ".zip" # using + because there's a select
268
+ else :
269
+ return "%s-generic.zip" % name_prefix
270
+
223
271
def codeql_pack (
224
272
* ,
225
273
name ,
@@ -252,47 +300,57 @@ def codeql_pack(
252
300
zip_filename = zip_filename or name
253
301
zips = zips or {}
254
302
pkg_filegroup (
255
- name = internal ("base " ),
303
+ name = internal ("all " ),
256
304
srcs = srcs ,
257
305
visibility = ["//visibility:private" ],
258
306
** kwargs
259
307
)
308
+ if zips :
309
+ _zip_info (
310
+ name = internal ("zip-info" ),
311
+ srcs = zips ,
312
+ visibility = ["//visibility:private" ],
313
+ )
260
314
for kind in ("generic" , "arch" ):
261
315
_extract_pkg_filegroup (
262
316
name = internal (kind ),
263
- src = internal ("base " ),
317
+ src = internal ("all " ),
264
318
kind = kind ,
265
319
visibility = ["//visibility:private" ],
266
320
)
267
321
if zips :
268
322
pkg_zip (
269
- name = internal (kind + "- zip-base" ),
323
+ name = internal (kind , " zip-base" ),
270
324
srcs = [internal (kind )],
271
325
visibility = ["//visibility:private" ],
272
326
compression_level = compression_level ,
273
327
)
274
- _zipmerge (
275
- name = internal (kind + "-zip" ),
276
- base = internal (kind + "-zip-base" ),
277
- zips = zips ,
278
- zip_name = zip_filename ,
328
+ _zip_info_filter (
329
+ name = internal (kind , "zip-info" ),
279
330
kind = kind ,
331
+ srcs = [internal ("zip-info" )],
332
+ visibility = ["//visibility:private" ],
333
+ )
334
+ _zipmerge (
335
+ name = internal (kind , "zip" ),
336
+ srcs = [internal (kind , "zip-base" ), internal (kind , "zip-info" )],
337
+ out = _get_zip_filename (name , kind ),
280
338
prefix = name ,
281
339
visibility = visibility ,
282
340
)
283
341
else :
284
342
pkg_zip (
285
- name = internal (kind + "- zip" ),
343
+ name = internal (kind , " zip" ),
286
344
srcs = [internal (kind )],
287
- visibility = [ "// visibility:private" ] ,
345
+ visibility = visibility ,
288
346
package_dir = name ,
289
- package_file_name = name + "-" + ( _detect_platform () if kind == "arch" else "generic" ) + ".zip" ,
347
+ package_file_name = _get_zip_filename ( name , kind ) ,
290
348
compression_level = compression_level ,
291
349
)
292
350
if zips :
293
351
_imported_zips_manifest (
294
352
name = internal ("zip-manifest" ),
295
- zips = zips ,
353
+ srcs = [ internal ( "generic-zip-info" ), internal ( "arch-zip-info" )] ,
296
354
visibility = ["//visibility:private" ],
297
355
)
298
356
0 commit comments