buck2
buck2 copied to clipboard
Excluding rules from certain platforms
Hello,
I'm working through a use case where we have certain rules that we want to run locally, but exclude from running on CI systems. I found this example: https://github.com/facebook/buck2/blob/8a7f7c7fca54af4be1a6b32b2d100aa0f4bca5d2/examples/with_prelude/go/hello/BUCK which uses host_info()
to exclude rules, but I'm not sure if it's possible to extend this logic with a custom boolean value, for example, is_ci
.
I've also attempted to access context data to determine which platform is being invoked and use that to skip the rule, but I'm not finding a way to do that either. Reading the docs, it seems like constraints added to our platform should work, but I'm unclear on how to implement that. For this use case, what is the best approach to take?
Try this:
In your .buckconfig
file:
[gsoyka]
is_ci = false
In a BUCK
file somewhere:
build_go_binary = not read_config("gsoyka", "is_ci", false)
go_binary(
name = "hello",
srcs = glob(["*.go"]),
deps = [
"//go/hello/greeting:greeting",
],
) if build_go_binary else None
Thanks, that's helpful, and I think that can be made to work for my use case. If I have a rule defined, eg. my_rule()
, is it possible to generalize that logic to apply to all my_rule
instances within a project when the config value is set to true
?
You could make a macro. From a bzl file somewhere:
build_go_binary = not read_config("gsoyka", "is_ci", false)
def my_rule_macro(name, srcs, deps):
go_binary(
name = "hello",
srcs = glob(["*.go"]),
deps = [
"//go/hello/greeting:greeting",
],
) if build_go_binary else None
and have people call your macro instead of your rule.
That makes sense to me, when I tried the example I'm seeing the behavior I want, but am getting an error about a missing symbol. Is there something the macro can return that isn't None
that still does nothing?
Try:
if build_go_binary: go_binary(…)
hard to say without seeing your error
Reading the docs, it seems like constraints added to our platform should work
Yeah, marking it target incompatible will cause it to be skipped without error when resolved in a pattern like //...
or //foo:
(but error when used explicitly like //foo:xyz
).
You could actually still use the config value to set things up if you wanted, somethign like this could work:
constraint_setting(
name = "none",
)
my_rule(
...
target_compatible_with = [] if read_config("foo", "is_ci", False) else [":none"]
)