Add a replacement for genrules in macros
Often writing macros is considered less effort than writing proper rules. Therefore, a lot of macros exists; unfortunately, in the presence of external repositories, dependencies on local tools cannot simply be referred to by a string, as that would be resolved in the outermost context.
Therefore, add an alternative to genrule that allows an explict argv, and accepts labels in replacements of paths.
load("@bazel_skylib//:lib.bzl", "actions") def to_upper(name="", src=""): tool = Label("//macro:my_tool") data = Label("//macro:data.txt") input = actions.outer_name(src) output = actions.outer_name(name + ".txt") actions.generic_action( name = name, tools = [tool], srcs = [input, data], outs = [output], argv = [tool, input, "magic string", data, output] )
As discussed, this is https://bazel-review.googlesource.com/c/bazel/+/48030 adapted to be be a skylib module.
Unfortunately, I don't know how to add a test in this setting. The key property of this function is that, even if called from a remote repository, argv is generated in such a way that all the paths end up correctly. So any meaningful test would involve invoking bazel with various different WORKSPACE files.
I manually verified that the tests in https://bazel-review.googlesource.com/c/bazel/+/48030 still pass with the macro code to read as
macro_with_implicit_dependencies() {
# create, in the current working directory, a package called macro
# that has in implicit dependency on a target inthe same repository.
# To make demonstrate the intended use case, make the local tool
# also take one non-path argument.
mkdir -p macro
cat > macro/BUILD <<'EOF'
exports_files(["to_upper.sh", "data.txt"])
EOF
cat > macro/to_upper.sh <<'EOF'
#!/bin/sh
[ "$2" = "magic string" ] || exit 1
grep 'local' $3 || exit 1
cat $1 | tr 'a-z' 'A-Z' > $4
EOF
chmod u+x macro/to_upper.sh
echo 'local data' > macro/data.txt
cat > macro/to_upper.bzl <<'EOF'
load("@bazel_skylib//:lib.bzl", "actions")
def to_upper(name="", src=""):
tool = Label("//macro:to_upper.sh")
data = Label("//macro:data.txt")
input = actions.outer_name(src)
output = actions.outer_name(name + ".txt")
actions.generic_action(
name = name,
tools = [tool],
srcs = [input, data],
outs = [output],
argv = [tool, input, "magic string", data, output]
)
EOF
}
and @bazel_skylib in the respective test WORKSPACE files pointing to this
commit.