@@ -5,11 +5,11 @@ Wrappers and helpers around `rules_pkg` to build codeql packs.
5
5
load ("@rules_pkg//pkg:install.bzl" , "pkg_install" )
6
6
load ("@rules_pkg//pkg:mappings.bzl" , "pkg_attributes" , "pkg_filegroup" , "pkg_files" , _strip_prefix = "strip_prefix" )
7
7
load ("@rules_pkg//pkg:pkg.bzl" , "pkg_zip" )
8
+ load ("@rules_pkg//pkg:providers.bzl" , "PackageFilegroupInfo" , "PackageFilesInfo" )
8
9
load ("@rules_python//python:defs.bzl" , "py_binary" )
9
- load ("//:defs.bzl" , "codeql_platform" )
10
10
11
11
def _make_internal (name ):
12
- def internal (suffix ):
12
+ def internal (suffix = "internal" ):
13
13
return "%s-%s" % (name , suffix )
14
14
15
15
return internal
@@ -20,151 +20,166 @@ def _get_subrule(label, suffix):
20
20
path , _ , pkg = label .rpartition ("/" )
21
21
return "%s/%s:%s-%s" % (path , pkg , pkg , suffix )
22
22
23
+ CodeqlFilesInfo = provider (
24
+ doc = """Wrapper around `rules_pkg` `PackageFilesInfo` splitting into generic and arch-specific files.""" ,
25
+ fields = {
26
+ "generic" : "list of `(PackageFilesInfo, Label)` tuples for generic files." ,
27
+ "arch" : "list of `(PackageFilesInfo, Label)` tuples for arch-specific files." ,
28
+ },
29
+ )
30
+
31
+ def _codeql_pkg_filegroup_impl (ctx ):
32
+ if ctx .target_platform_has_constraint (ctx .attr ._windows [platform_common .ConstraintValueInfo ]):
33
+ plat = "windows64"
34
+ elif ctx .target_platform_has_constraint (ctx .attr ._macos [platform_common .ConstraintValueInfo ]):
35
+ plat = "osx64"
36
+ else :
37
+ plat = "linux64"
38
+ generic_prefix = ctx .attr .prefix
39
+ if generic_prefix :
40
+ generic_prefix += "/"
41
+ arch_prefix = generic_prefix + plat + "/"
42
+
43
+ def transform_pfi_lbl (pfi_lbl , prefix ):
44
+ pfi , lbl = pfi_lbl
45
+ return (PackageFilesInfo (
46
+ attributes = pfi .attributes ,
47
+ dest_src_map = {prefix + d : s for d , s in pfi .dest_src_map .items ()},
48
+ ), lbl )
49
+
50
+ generic = []
51
+ arch = []
52
+ for dest , prefix , srcs in (
53
+ (generic , generic_prefix , ctx .attr .srcs ),
54
+ (arch , arch_prefix , ctx .attr .arch_srcs ),
55
+ ):
56
+ for src in srcs :
57
+ if PackageFilesInfo in src :
58
+ dest .append (transform_pfi_lbl ((src [PackageFilesInfo ], src .label ), prefix ))
59
+ elif PackageFilegroupInfo in src :
60
+ pfgi = src [PackageFilegroupInfo ]
61
+ if pfgi .pkg_dirs or pfgi .pkg_symlinks :
62
+ fail ("while assembling %s found %s which contains `pkg_dirs` or `pkg_symlinks` targets" %
63
+ (ctx .label , src .label ))
64
+ dest += [transform_pfi_lbl (item , prefix ) for item in pfgi .pkg_files ]
65
+ else :
66
+ cfi = src [CodeqlFilesInfo ]
67
+ generic += [transform_pfi_lbl (item , generic_prefix ) for item in cfi .generic ]
68
+
69
+ # arch-specific prefix was already applied
70
+ arch += [transform_pfi_lbl (item , generic_prefix ) for item in cfi .arch ]
71
+
72
+ srcs = ctx .attr .srcs + ctx .attr .arch_srcs
73
+ return [
74
+ CodeqlFilesInfo (
75
+ generic = generic ,
76
+ arch = arch ,
77
+ ),
78
+ DefaultInfo (
79
+ files = depset (transitive = [src [DefaultInfo ].files for src in srcs ]),
80
+ ),
81
+ ]
82
+
83
+ codeql_pkg_filegroup = rule (
84
+ implementation = _codeql_pkg_filegroup_impl ,
85
+ doc = """CodeQL specific packaging mapping. No `pkg_mkdirs` or `pkg_symlink` rules are supported, either directly
86
+ or transitively. Only `pkg_files` and `pkg_filegroup` thereof are allowed.""" ,
87
+ attrs = {
88
+ "srcs" : attr .label_list (
89
+ doc = "List of arch-agnostic `pkg_files`, `pkg_filegroup` or `codeql_pkg_filegroup` targets" ,
90
+ providers = [DefaultInfo ],
91
+ default = [],
92
+ ),
93
+ "arch_srcs" : attr .label_list (
94
+ doc = "List of arch-specific `pkg_files` or `pkg_filegroup` targets" ,
95
+ providers = [DefaultInfo ],
96
+ default = [],
97
+ ),
98
+ "prefix" : attr .string (doc = "Prefix to add to the files" ),
99
+ "_windows" : attr .label (default = "@platforms//os:windows" ),
100
+ "_macos" : attr .label (default = "@platforms//os:macos" ),
101
+ },
102
+ )
103
+
23
104
def codeql_pkg_files (
24
105
* ,
25
106
name ,
26
- arch_specific = False ,
27
107
srcs = None ,
28
108
exes = None ,
29
- renames = None ,
30
109
prefix = None ,
31
110
visibility = None ,
32
111
** kwargs ):
33
112
"""
34
113
Wrapper around `pkg_files`. Added functionality:
35
- * `exes` get their file attributes set to be executable. This is important only for POSIX files, there's no need
36
- to mark windows executables as such
37
- * `arch_specific` auto-adds the codeql platform specific directory (linux64, osx64 or windows64), and will be
38
- consumed by a downstream `codeql_pack` to create the arch specific zip.
39
- This should be consumed by `codeql_pkg_filegroup` and `codeql_pack` only.
114
+ * `exes` will get their file attributes set to be executable. This is important only for POSIX files, there's no
115
+ need to mark windows executables as such
116
+ If `exes` and `srcs` are both used, the resulting rule is a `pkg_filegroup` one.
40
117
"""
41
118
internal = _make_internal (name )
42
- main_rule = internal ("generic" )
43
- empty_rule = internal ("arch" )
44
- if arch_specific :
45
- main_rule , empty_rule = empty_rule , main_rule
46
- prefix = (prefix + "/" if prefix else "" ) + codeql_platform
47
- pkg_files (
48
- name = empty_rule ,
49
- srcs = [],
50
- visibility = visibility ,
51
- )
52
- if not srcs and not exes :
53
- fail ("either srcs or exes should be specified for %s" % name )
119
+ if "attributes" in kwargs :
120
+ fail ("codeql_pkg_files does not support `attributes`. Use `exes` to mark executable files." )
121
+ internal_srcs = []
54
122
if srcs and exes :
55
- if renames :
56
- src_renames = {k : v for k , v in renames .items () if k in srcs }
57
- exe_renames = {k : v for k , v in renames .items () if k in exes }
58
- else :
59
- src_renames = None
60
- exe_renames = None
61
123
pkg_files (
62
124
name = internal ("srcs" ),
63
125
srcs = srcs ,
64
- renames = src_renames ,
65
- prefix = prefix ,
66
126
visibility = ["//visibility:private" ],
67
127
** kwargs
68
128
)
69
129
pkg_files (
70
130
name = internal ("exes" ),
71
131
srcs = exes ,
72
- renames = exe_renames ,
73
- prefix = prefix ,
74
132
visibility = ["//visibility:private" ],
75
- attributes = pkg_attributes (mode = "0755 " ),
133
+ attributes = pkg_attributes (mode = "755 " ),
76
134
** kwargs
77
135
)
78
136
pkg_filegroup (
79
- name = main_rule ,
137
+ name = name ,
80
138
srcs = [internal ("srcs" ), internal ("exes" )],
139
+ prefix = prefix ,
81
140
visibility = visibility ,
82
141
)
83
142
else :
84
143
pkg_files (
85
- name = main_rule ,
144
+ name = name ,
86
145
srcs = srcs or exes ,
87
- attributes = pkg_attributes (mode = "0755" ) if exes else None ,
88
- prefix = prefix ,
89
146
visibility = visibility ,
147
+ prefix = prefix ,
148
+ attributes = pkg_attributes (mode = "755" ) if exes else None ,
90
149
** kwargs
91
150
)
92
- native .filegroup (
93
- name = name ,
94
- srcs = [main_rule ],
95
- visibility = visibility ,
96
- )
97
151
98
- def codeql_pkg_wrap (* , name , srcs , arch_specific = False , prefix = None , visibility = None , ** kwargs ):
99
- """
100
- Wrap a native `rules_pkg` rule, providing the `arch_specific` functionality and making it consumable by
101
- `codeql_pkg_filegroup` and `codeql_pack`.
102
- """
103
- internal = _make_internal (name )
104
- main_rule = internal ("generic" )
105
- empty_rule = internal ("arch" )
106
- if arch_specific :
107
- main_rule , empty_rule = empty_rule , main_rule
108
- prefix = (prefix + "/" if prefix else "" ) + codeql_platform
109
- pkg_filegroup (
110
- name = main_rule ,
111
- srcs = srcs ,
112
- prefix = prefix ,
113
- visibility = visibility ,
114
- ** kwargs
115
- )
116
- pkg_files (
117
- name = empty_rule ,
118
- srcs = [],
119
- visibility = visibility ,
120
- )
121
- native .filegroup (
122
- name = name ,
123
- srcs = [main_rule ],
124
- visibility = visibility ,
125
- )
152
+ def _extract_pkg_filegroup_impl (ctx ):
153
+ src = ctx .attr .src [CodeqlFilesInfo ]
154
+ pfi_lbl_list = src .arch if ctx .attr .arch_specific else src .generic
155
+ files = []
156
+ for pfi , lbl in pfi_lbl_list :
157
+ files .append (depset (pfi .dest_src_map .values ()))
158
+ return [
159
+ PackageFilegroupInfo (pkg_files = pfi_lbl_list , pkg_dirs = [], pkg_symlinks = []),
160
+ DefaultInfo (files = depset (transitive = files )),
161
+ ]
126
162
127
- def codeql_pkg_filegroup (
163
+ _extrac_pkg_filegroup = rule (
164
+ implementation = _extract_pkg_filegroup_impl ,
165
+ attrs = {
166
+ "src" : attr .label (providers = [CodeqlFilesInfo , DefaultInfo ]),
167
+ "arch_specific" : attr .bool (),
168
+ },
169
+ )
170
+
171
+ def codeql_pack (
128
172
* ,
129
173
name ,
130
- srcs ,
131
- srcs_select = None ,
174
+ srcs = None ,
175
+ arch_srcs = None ,
176
+ zip_prefix = None ,
177
+ zip_filename = "extractor" ,
132
178
visibility = None ,
179
+ install_dest = "extractor-pack" ,
133
180
** kwargs ):
134
181
"""
135
- Combine `codeql_pkg_files` and other `codeql_pkg_filegroup` rules, similar to what `pkg_filegroup` does.
136
- `srcs` is not selectable, but `srcs_select` accepts the same dictionary that a select would accept.
137
- """
138
- internal = _make_internal (name )
139
-
140
- def transform (srcs , suffix ):
141
- return [_get_subrule (src , suffix ) for src in srcs ]
142
-
143
- pkg_filegroup (
144
- name = internal ("generic" ),
145
- srcs = transform (srcs , "generic" ) + (select (
146
- {k : transform (v , "generic" ) for k , v in srcs_select .items ()},
147
- ) if srcs_select else []),
148
- visibility = visibility ,
149
- ** kwargs
150
- )
151
- pkg_filegroup (
152
- name = internal ("arch" ),
153
- srcs = transform (srcs , "arch" ) + (select (
154
- {k : transform (v , "arch" ) for k , v in srcs_select .items ()},
155
- ) if srcs_select else []),
156
- visibility = visibility ,
157
- ** kwargs
158
- )
159
- native .filegroup (
160
- name = name ,
161
- srcs = [internal ("generic" ), internal ("arch" )],
162
- visibility = visibility ,
163
- )
164
-
165
- def codeql_pack (* , name , srcs , zip_prefix = None , zip_filename = "extractor" , visibility = visibility , install_dest = "extractor-pack" , ** kwargs ):
166
- """
167
- Define a codeql pack. This accepts the same arguments as `codeql_pkg_filegroup`, and additionally:
182
+ Define a codeql pack. This accepts `pkg_files`, `pkg_filegroup` or their `codeql_*` counterparts as `srcs`.
168
183
* defines a `<name>-generic-zip` target creating a `<zip_filename>-generic.zip` archive with the generic bits,
169
184
prefixed with `zip_prefix` (`name` by default)
170
185
* defines a `<name>-arch-zip` target creating a `<zip_filename>-<codeql_platform>.zip` archive with the
@@ -179,27 +194,34 @@ def codeql_pack(*, name, srcs, zip_prefix = None, zip_filename = "extractor", vi
179
194
codeql_pkg_filegroup (
180
195
name = name ,
181
196
srcs = srcs ,
197
+ arch_srcs = arch_srcs ,
182
198
visibility = visibility ,
183
199
** kwargs
184
200
)
185
- codeql_pkg_filegroup (
186
- name = internal ("zip-contents " ),
187
- srcs = [ name ] ,
188
- prefix = zip_prefix ,
201
+ _extrac_pkg_filegroup (
202
+ name = internal ("generic " ),
203
+ src = name ,
204
+ arch_specific = False ,
189
205
visibility = ["//visibility:private" ],
190
206
)
191
- pkg_zip (
192
- name = internal ("generic-zip" ),
193
- srcs = [internal ("zip-contents-generic" )],
194
- package_file_name = zip_filename + "-generic.zip" ,
195
- visibility = visibility ,
196
- )
197
- pkg_zip (
198
- name = internal ("arch-zip" ),
199
- srcs = [internal ("zip-contents-arch" )],
200
- package_file_name = zip_filename + "-" + codeql_platform + ".zip" ,
201
- visibility = visibility ,
207
+ _extrac_pkg_filegroup (
208
+ name = internal ("arch" ),
209
+ src = name ,
210
+ arch_specific = True ,
211
+ visibility = ["//visibility:private" ],
202
212
)
213
+ for kind in ("generic" , "arch" ):
214
+ pkg_filegroup (
215
+ name = internal (kind + "-zip-contents" ),
216
+ srcs = [internal (kind )],
217
+ visibility = ["//visibility:private" ],
218
+ )
219
+ pkg_zip (
220
+ name = internal (kind + "-zip" ),
221
+ srcs = [internal (kind + "-zip-contents" )],
222
+ package_file_name = "%s-%s.zip" % (zip_filename , kind ),
223
+ visibility = visibility ,
224
+ )
203
225
pkg_install (
204
226
name = internal ("script" ),
205
227
srcs = [internal ("generic" ), internal ("arch" )],
0 commit comments