Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4d93e8a

Browse files
committed
Bazel: move codeql packaging rules away from some macros
1 parent 60cf77b commit 4d93e8a

3 files changed

Lines changed: 187 additions & 166 deletions

File tree

misc/bazel/pkg.bzl

Lines changed: 148 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ Wrappers and helpers around `rules_pkg` to build codeql packs.
55
load("@rules_pkg//pkg:install.bzl", "pkg_install")
66
load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files", _strip_prefix = "strip_prefix")
77
load("@rules_pkg//pkg:pkg.bzl", "pkg_zip")
8+
load("@rules_pkg//pkg:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo")
89
load("@rules_python//python:defs.bzl", "py_binary")
910
load("//:defs.bzl", "codeql_platform")
1011

1112
def _make_internal(name):
12-
def internal(suffix):
13+
def internal(suffix = "internal"):
1314
return "%s-%s" % (name, suffix)
1415

1516
return internal
@@ -20,151 +21,173 @@ def _get_subrule(label, suffix):
2021
path, _, pkg = label.rpartition("/")
2122
return "%s/%s:%s-%s" % (path, pkg, pkg, suffix)
2223

24+
_PackageFileWrapperInfo = provider(fields = {"pfi": "", "src": "", "arch_specific": ""})
25+
26+
CodeqlFilesInfo = provider(
27+
doc = """Wrapper around `rules_pkg` `PackageFilesInfo` carrying information about generic and arch-specific files.""",
28+
fields = {
29+
"files": "list of `_PackageFileWrapperInfo`.",
30+
},
31+
)
32+
33+
def _codeql_pkg_filegroup_impl(ctx):
34+
prefix = ctx.attr.prefix
35+
if prefix:
36+
prefix += "/"
37+
generic_prefix = prefix
38+
if ctx.attr.arch_specific:
39+
if ctx.target_platform_has_constraint(ctx.attr._windows[platform_common.ConstraintValueInfo]):
40+
plat = "windows64"
41+
elif ctx.target_platform_has_constraint(ctx.attr._macos[platform_common.ConstraintValueInfo]):
42+
plat = "osx64"
43+
else:
44+
plat = "linux64"
45+
prefix = prefix + plat + "/"
46+
47+
def transform_pfi(pfi, src, prefix = prefix, arch_specific = ctx.attr.arch_specific):
48+
return _PackageFileWrapperInfo(
49+
pfi = PackageFilesInfo(
50+
attributes = pfi.attributes,
51+
dest_src_map = {prefix + d: s for d, s in pfi.dest_src_map.items()},
52+
),
53+
src = src,
54+
arch_specific = arch_specific,
55+
)
56+
57+
files = []
58+
59+
for src in ctx.attr.srcs:
60+
if PackageFilesInfo in src:
61+
pfi = src[PackageFilesInfo]
62+
files.append(transform_pfi(pfi, src.label))
63+
elif PackageFilegroupInfo in src:
64+
pfgi = src[PackageFilegroupInfo]
65+
if pfgi.pkg_dirs or pfgi.pkg_symlinks:
66+
fail("while assembling %s found %s which contains `pkg_dirs` or `pkg_symlinks` targets" %
67+
(ctx.label, src.label) + ", which is not currently supported")
68+
files += [transform_pfi(pfi, src) for pfi, src in pfgi.pkg_files]
69+
else:
70+
cfi = src[CodeqlFilesInfo]
71+
files += [
72+
transform_pfi(
73+
pfwi.pfi,
74+
pfwi.src,
75+
# if it was already arch specific the plat prefix was already added
76+
generic_prefix if pfwi.arch_specific else prefix,
77+
pfwi.arch_specific or ctx.attr.arch_specific,
78+
)
79+
for pfwi in cfi.files
80+
]
81+
82+
return [
83+
CodeqlFilesInfo(
84+
files = files,
85+
),
86+
DefaultInfo(
87+
files = depset(transitive = [src[DefaultInfo].files for src in ctx.attr.srcs]),
88+
),
89+
]
90+
91+
codeql_pkg_filegroup = rule(
92+
implementation = _codeql_pkg_filegroup_impl,
93+
doc = """CodeQL specific packaging mapping. No `pkg_mkdirs` or `pkg_symlink` rules are supported, either directly
94+
or transitively. Only `pkg_files` and `pkg_filegroup` thereof are allowed.""",
95+
attrs = {
96+
"srcs": attr.label_list(
97+
doc = "List of arch-agnostic `pkg_files`, `pkg_filegroup` or `codeql_pkg_filegroup` targets",
98+
providers = [
99+
[PackageFilesInfo, DefaultInfo],
100+
[PackageFilegroupInfo, DefaultInfo],
101+
[CodeqlFilesInfo, DefaultInfo],
102+
],
103+
default = [],
104+
),
105+
"prefix": attr.string(doc = "Prefix to add to the files", default = ""),
106+
"arch_specific": attr.bool(doc = "Whether the included files should be treated as arch-specific"),
107+
"_windows": attr.label(default = "@platforms//os:windows"),
108+
"_macos": attr.label(default = "@platforms//os:macos"),
109+
},
110+
)
111+
23112
def codeql_pkg_files(
24113
*,
25114
name,
26-
arch_specific = False,
27115
srcs = None,
28116
exes = None,
29-
renames = None,
117+
arch_specific = False,
30118
prefix = None,
31119
visibility = None,
32120
**kwargs):
33121
"""
34122
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.
123+
* `exes` will get their file attributes set to be executable. This is important only for POSIX files, there's no
124+
need to mark windows executables as such
125+
If `exes` and `srcs` are both used, the resulting rule is a `pkg_filegroup` one.
40126
"""
41127
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)
128+
if "attributes" in kwargs:
129+
fail("codeql_pkg_files does not support `attributes`. Use `exes` to mark executable files.")
130+
internal_srcs = []
54131
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
61132
pkg_files(
62133
name = internal("srcs"),
63134
srcs = srcs,
64-
renames = src_renames,
65-
prefix = prefix,
66135
visibility = ["//visibility:private"],
67136
**kwargs
68137
)
69138
pkg_files(
70139
name = internal("exes"),
71140
srcs = exes,
72-
renames = exe_renames,
73-
prefix = prefix,
74141
visibility = ["//visibility:private"],
75-
attributes = pkg_attributes(mode = "0755"),
142+
attributes = pkg_attributes(mode = "755"),
76143
**kwargs
77144
)
78-
pkg_filegroup(
79-
name = main_rule,
80-
srcs = [internal("srcs"), internal("exes")],
81-
visibility = visibility,
82-
)
145+
internal_srcs = [internal("srcs"), internal("exes")]
83146
else:
84147
pkg_files(
85-
name = main_rule,
148+
name = internal(),
86149
srcs = srcs or exes,
87-
attributes = pkg_attributes(mode = "0755") if exes else None,
88-
prefix = prefix,
89150
visibility = visibility,
151+
attributes = pkg_attributes(mode = "755") if exes else None,
90152
**kwargs
91153
)
92-
native.filegroup(
154+
internal_srcs = [internal()]
155+
codeql_pkg_filegroup(
93156
name = name,
94-
srcs = [main_rule],
95-
visibility = visibility,
96-
)
97-
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,
157+
srcs = internal_srcs,
158+
arch_specific = arch_specific,
112159
prefix = prefix,
113160
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,
125161
)
126162

127-
def codeql_pkg_filegroup(
163+
def _extract_pkg_filegroup_impl(ctx):
164+
src = ctx.attr.src[CodeqlFilesInfo]
165+
pfi_lbls = [(pfwi.pfi, pfwi.src) for pfwi in src.files if pfwi.arch_specific == ctx.attr.arch_specific]
166+
files = [depset(pfi.dest_src_map.values()) for pfi, _ in pfi_lbls]
167+
return [
168+
PackageFilegroupInfo(pkg_files = pfi_lbls, pkg_dirs = [], pkg_symlinks = []),
169+
DefaultInfo(files = depset(transitive = files)),
170+
]
171+
172+
_extrac_pkg_filegroup = rule(
173+
implementation = _extract_pkg_filegroup_impl,
174+
attrs = {
175+
"src": attr.label(providers = [CodeqlFilesInfo, DefaultInfo]),
176+
"arch_specific": attr.bool(),
177+
},
178+
)
179+
180+
def codeql_pack(
128181
*,
129182
name,
130-
srcs,
131-
srcs_select = None,
183+
srcs = None,
184+
zip_prefix = None,
185+
zip_filename = "extractor",
132186
visibility = None,
187+
install_dest = "extractor-pack",
133188
**kwargs):
134189
"""
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:
190+
Define a codeql pack. This accepts `pkg_files`, `pkg_filegroup` or their `codeql_*` counterparts as `srcs`.
168191
* defines a `<name>-generic-zip` target creating a `<zip_filename>-generic.zip` archive with the generic bits,
169192
prefixed with `zip_prefix` (`name` by default)
170193
* defines a `<name>-arch-zip` target creating a `<zip_filename>-<codeql_platform>.zip` archive with the
@@ -182,31 +205,32 @@ def codeql_pack(*, name, srcs, zip_prefix = None, zip_filename = "extractor", vi
182205
visibility = visibility,
183206
**kwargs
184207
)
185-
codeql_pkg_filegroup(
186-
name = internal("zip-contents"),
187-
srcs = [name],
188-
prefix = zip_prefix,
189-
visibility = ["//visibility:private"],
190-
)
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,
202-
)
208+
for kind in ("generic", "arch"):
209+
_extrac_pkg_filegroup(
210+
name = internal(kind),
211+
src = name,
212+
arch_specific = kind == "arch",
213+
visibility = ["//visibility:private"],
214+
)
215+
pkg_filegroup(
216+
name = internal(kind + "-zip-contents"),
217+
srcs = [internal(kind)],
218+
prefix = zip_prefix,
219+
visibility = ["//visibility:private"],
220+
)
221+
pkg_zip(
222+
name = internal(kind + "-zip"),
223+
srcs = [internal(kind + "-zip-contents")],
224+
package_file_name = zip_filename + "-" + (codeql_platform if kind == "arch" else kind) + ".zip",
225+
visibility = visibility,
226+
)
203227
pkg_install(
204228
name = internal("script"),
205229
srcs = [internal("generic"), internal("arch")],
206230
visibility = ["//visibility:private"],
207231
)
208232
native.filegroup(
209-
# used to locate current source directory
233+
# used to locate current src directory
210234
name = internal("build-file"),
211235
srcs = ["BUILD.bazel"],
212236
visibility = ["//visibility:private"],

0 commit comments

Comments
 (0)