Skip to content

Instantly share code, notes, and snippets.

@rrbutani
Last active August 21, 2023 12:30
Show Gist options
  • Save rrbutani/bd633063adf44c12372e4b5aa90d24d8 to your computer and use it in GitHub Desktop.
Save rrbutani/bd633063adf44c12372e4b5aa90d24d8 to your computer and use it in GitHub Desktop.

First you need to run echo "test" > /tmp/foo.

Running bazel build @repo//... will print "running repo rule".

Touching test_file and then bazel build @repo//... will not do anything; the repo rule is not rerun and the artifacts in @repo are not rebuilt.

Modifying test_file will cause the workspace rule to be rerun.

  • if you make a change that yields a different BUILD.bazel file then artifacts will be rebuilt (i.e. changing the first line of test_file)
  • if you make a change that still yields the same BUILD.bazel file no actions will be run (i.e adding extra lines, whitespace to test_file)

Modifying this file (test.bzl) will cause the workspace rule to be re-run; same caveat around actions being re-run (only if the actions are different -- i.e. if the BUILD files are different).

Modifying /tmp/foo will not cause the workspace rule to be re-run; it is not tracked by bazel.


This is all consistent with these docs:

repositories are re-fetched only if one of the following things changes:

  • The parameters passed to the declaration of the repository in the WORKSPACE file.
  • The Starlark code comprising the implementation of the repository.
  • The value of any environment variable declared with the environ attribute of the repository_rule. The values of these environment variables can be hard-wired on the command line with the --action_env flag (but this flag will invalidate every action of the build).
  • The content of any file passed to the read(), execute() and similar methods of repository_ctx which is referred to by a label (for example, //mypkg:label.txt but not mypkg/label.txt)
  • When bazel sync is executed.
use nix -p bazel_6
.direnv
/bazel-*
def _mk_genrule(target_name):
return """
genrule(
name = "{tgt}",
srcs = [],
outs = ["yo_{tgt}"],
cmd = "echo 'ok' > \\"$@\\"",
)
""".format(tgt = target_name)
def _repo_rule(rctx):
# Modifications are not tracked!
tgt1 = rctx.read("/tmp/foo")
tgt1 = tgt1.splitlines()[0].strip("\n\t ")
# Modifcations to this file _will_ cause the repo rule to rerun
tgt2 = rctx.read(Label("@//:test_file"))
tgt2 = tgt2.splitlines()[0].strip("\n\t ")
# Note that this is consistent with the docs here:
# https://bazel.build/extending/repo
print("running repo rule")
rctx.file(
"BUILD.bazel",
content = _mk_genrule(tgt1) + "\n" + _mk_genrule(tgt2),
executable = False,
)
repo_rule = repository_rule(
implementation = _repo_rule,
)
foo_bar_baz_quzz
workspace(name = "repo-rule-file-read-dep-tracking")
load("test.bzl", "repo_rule")
repo_rule(name = "repo")
@rrbutani
Copy link
Author

Notes from another experiment:

# re: `rctx.symlink` vs `new_local_repository`: I think these are more or less
# equivalent; `new_local_repository` just goes and makes symlinks for the
# top-level contents of the path you give it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment