Reputation: 2810
Let's say I have a rule:
blah = rule(
attrs = {
"foo": attr.string(default = "@HELP@"),
},
)
I want the default value of foo
to contain the name of the workspace that invokes the rule. How can I accomplish this?
(Note: An acceptable approach is to leave a placeholder in the value and replace it when the rule uses the attribute, but I can't figure out how to get the current workspace there either. The closest I can find is ctx.label.workspace_root
, but that is empty for the "main" workspace, and e.g. external/foo
for other things.)
ctx.workspace_name
does not give the correct answers. For example, if I print("'%s' -> '%s'", (ctx.label.workspace_root, ctx.workspace_name))
, I get results like:
'externals/foo' -> 'main'
'externals/bar' -> 'main'
...which is wrong; those should be 'foo' and 'bar', not 'main' ('main' being my main/root workspace). Note that labels from those contexts are e.g. '@foo//:foo', so Bazel does apparently know the correct workspace name.
Upvotes: 1
Views: 840
Reputation: 2810
As far as getting the workspace name, this seems sub-optimal, but also seems to work:
def _workspace(ctx):
"""Compute name of current workspace."""
# Check for meaningful workspace_root
workspace = ctx.label.workspace_root.split("/")[-1]
if len(workspace):
return workspace
# If workspace_root is empty, assume we are the root workspace
return ctx.workspace_name
Per Kristina's answer and comment in the original question, this can then be used to replace a placeholder in the parameter value.
Upvotes: 1
Reputation: 23601
You can use a placeholder attribute and then use ctx.workspace_name
in the implementation.
def _impl(ctx):
print("ws: %s" % ctx.workspace_name)
blah = rule(
implementation = _impl,
)
Upvotes: 1