This repository has been archived by the owner on Sep 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bazel: add utility macro for wrapping single-file tools (#62930)
Currently, we provide single-file tools such as `ctags`, `gsutil` etc via an `sh_binary` wrapper, to have a single target to reference that automatically does platform selection of the underlying tool. Due to some [unfortunate reason](bazelbuild/bazel#11820), the underlying srcs (which is [a single file](https://bazel.build/reference/be/shell#sh_binary.srcs)) of an `sh_binary` are also exposed as outputs (rather than just as typical runfiles) alongside the script that wraps. This is _sometimes_ problematic when doing location expansion (e.g. `$(location ...)`) due to these only allowing a single output (dont ask why this works in some contexts but not others, I dont know). To address this, we create a wrapper macro + rule to replicate what we want from `sh_binary` (automatic platform selection + tool naming), while only exposing a singular file. See example of currently required approach to consuming a tool: [BUILD.bazel](https://github.com/sourcegraph/sourcegraph/pull/62801/files#diff-e2a562c2e13908933b2ee24f0ac596829b38a5325cc69a4aee05c383aaa2e494R8) & [main_test.go](https://github.com/sourcegraph/sourcegraph/pull/62801/files#diff-7a91cb5143064bfc8993ef97baf68b718ef49747ccc1d3c5e1150d4696b88305R66). With this change, `rlocationpath` (singular) can be used instead (or any of the other singular nouns in different contexts), as well as no `strings.Split/strings.Fields` being required ## Test plan `bazel cquery --output=files //dev/tools:dropdb` yields 1 vs 2 files. Also updated the rule behind `//internal/database:generate_schemas` due to the workaround in it for the fact that the underlying srcs was also exposed. The correctness is verified by running said target (locally + CI)
- Loading branch information
Showing
3 changed files
with
72 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
load("@aspect_bazel_lib//lib:output_files.bzl", "make_output_files") | ||
|
||
# Convenience wrapper for rules that provide a single executable (binary/script/etc) that | ||
# we want to rename. For example, files produced by http_file have the name `downloaded`, | ||
# we may want to rename them with sh_binary, however this has a weird quirk whereby both | ||
# the sh_binary wrapper "script" and the input binary/script itself are included in the outputs. | ||
# This results in some less ergonomic usage when trying to use them in e.g. go tests, having to | ||
# use $(rlocationpaths ...) and then filepath.Dir(runfiles.Rlocation(strings.Split(..., " ")[0])) in | ||
# order to get the path. | ||
# With this macro, its slightly simplified by being able to use $(rlocationpath ...) (singular) and | ||
# not having to strings.Split(..., " ") as a result. | ||
# See more: https://github.com/bazelbuild/bazel/issues/11820 | ||
def tool(name, src, visibility = ["//visibility:public"]): | ||
native.sh_binary( | ||
name = name + "_sh", | ||
srcs = src, | ||
) | ||
make_bin_and_deps_available( | ||
name = name, | ||
out = name, | ||
data = make_output_files( | ||
name = name + "_out", | ||
target = name + "_sh", | ||
paths = [native.package_name() + "/" + name + "_sh"], | ||
), | ||
visibility = visibility, | ||
) | ||
|
||
def _make_bin_and_deps_available_impl(ctx): | ||
symlink = ctx.actions.declare_file(ctx.attr.out) | ||
ctx.actions.symlink(output = symlink, target_file = ctx.file.data) | ||
return [ | ||
DefaultInfo( | ||
executable = symlink, | ||
files = depset(direct = [symlink]), | ||
runfiles = ctx.runfiles(files = ctx.files.data), | ||
), | ||
] | ||
|
||
make_bin_and_deps_available = rule( | ||
_make_bin_and_deps_available_impl, | ||
executable = True, | ||
attrs = { | ||
"out": attr.string(mandatory = True), | ||
"data": attr.label(mandatory = True, allow_single_file = True), | ||
}, | ||
) |