Created
July 20, 2022 17:29
-
-
Save DeCarabas/8b1cf5875577342631cb5312cce3f3db to your computer and use it in GitHub Desktop.
These are our current rules for integrating bazel and Tilt
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
# -*- mode: bazel-build -*- | |
def require_tool(tool): | |
tool = shlex.quote(tool) | |
local('command -v {tool} >/dev/null 2>&1 || {{ echo >&2 "{tool} is required but was not found in PATH"; exit 1; }}'.format(tool = tool)) | |
require_tool("bazelisk") | |
BAZEL_RUN_CMD = "bazelisk run" | |
BAZEL_SOURCES_QUERY = 'kind("source file", deps(set(%s)))' | |
BAZEL_BUILDFILES_QUERY = "buildfiles(deps(set(%s)))" | |
def workspace_files(): | |
workspace_root = str(local("bazelisk info workspace")).strip() | |
return [ | |
os.path.join(workspace_root, "WORKSPACE"), | |
os.path.join(workspace_root, "WORKSPACE.bazel"), | |
] | |
def xml_output_to_files(output): | |
files = {} | |
for line in str(output).splitlines(): | |
LOCATION_SLUG = 'location="' | |
start_index = line.find(LOCATION_SLUG) | |
if start_index < 0: | |
continue | |
end_index = line.find('"', start_index + len(LOCATION_SLUG)) | |
path = line[start_index + len(LOCATION_SLUG):end_index] | |
# These indices sometimes end with :1:1 and | |
if path.endswith(":1:1"): | |
path = path[:-4] | |
# This file is problematic; it gets regenerated every build sometimes | |
# and tilt gets locked into a loop. | |
if path.endswith("local_config_cc/BUILD"): | |
continue | |
files[path] = None | |
return sorted(files.keys()) | |
def bazel_query(query): | |
query_cmd = "bazelisk query '%s' --order_output=No --output=xml" % query | |
# this XML output is so noisy, so we set it to quiet and only print the | |
# output files | |
xml = local(query_cmd, quiet = True) | |
files = xml_output_to_files(xml) | |
for file in files: | |
print(" → " + file) | |
print(" (Output parsed from XML)") | |
return files | |
def bazel_build(image, target): | |
# Compute the build deps. We watch them here because we want to re-run | |
# this function when the set of dependencies changes, and these are the | |
# files that generate the set of dependencies. | |
build_deps = workspace_files() + bazel_query(BAZEL_BUILDFILES_QUERY % target) | |
for dep in build_deps: | |
watch_file(dep) | |
# Ask bazel for the source files that go into this target. | |
deps = bazel_query(BAZEL_SOURCES_QUERY % target) | |
# The build files *also* impact the way the compilation goes, so we need | |
# to fold them into the direct dependency set too, along with the actual | |
# source files. | |
deps = deps + build_deps | |
# Bazel puts the image at bazel/{dirname}, so transform | |
# //snack:image -> bazel/snack:image | |
dest = target.replace("//", "bazel/") | |
command = "{run_cmd} {target} -- --norun && docker tag {dest} $EXPECTED_REF".format( | |
dest = dest, | |
run_cmd = BAZEL_RUN_CMD, | |
target = target, | |
) | |
custom_build( | |
image, | |
command = command, | |
deps = deps, | |
) | |
def bazel_helm_path(target): | |
for file in workspace_files(): | |
watch_file(file) | |
for file in bazel_query(BAZEL_BUILDFILES_QUERY % target): | |
watch_file(file) | |
files = bazel_query(BAZEL_SOURCES_QUERY % target) | |
return os.path.dirname(files[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment