buck2 icon indicating copy to clipboard operation
buck2 copied to clipboard

Excluding rules from certain platforms

Open gsoyka opened this issue 11 months ago • 6 comments

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?

gsoyka avatar Mar 12 '24 17:03 gsoyka

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

zjturner avatar Mar 13 '24 01:03 zjturner

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?

gsoyka avatar Mar 13 '24 22:03 gsoyka

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.

zjturner avatar Mar 13 '24 23:03 zjturner

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?

gsoyka avatar Mar 14 '24 22:03 gsoyka

Try:

if build_go_binary: go_binary(…)

hard to say without seeing your error

zjturner avatar Mar 16 '24 03:03 zjturner

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"]
)

cjhopman avatar Mar 29 '24 20:03 cjhopman