Historically, it has been tedious to apply transitions to rules we don’t control. You either had to maintain a fork, apply a patch, or wrap the rule — which is particularly annoying because you then have to manually forward the providers of the underlying rule.
Enter Rule Extensions
Bazel 8 introduced rule extensions, which allow you to augment an existing rule — somewhat similar to subclassing in object-oriented languages. Instead of copying or wrapping a rule manually, you can define a new rule that delegates to a parent rule while modifying selected behavior.
A Simple Transition
Let’s first create a transition that forces opt as the compilation mode:
def _opt_transition_impl(_settings, _attr):
return {"//command_line_option:compilation_mode": "opt"}
opt_transition = transition(
implementation = _opt_transition_impl,
inputs = [],
outputs = ["//command_line_option:compilation_mode"],
)
Nothing fancy — this transition forces the rule it’s applied to to always build in opt, regardless of the --compilation_mode specified on the command line.
Applying the Transition
Here I’m demonstrating this with swift_library, but the concept is the same regardless of the rule:
opt_swift_library = rule(
implementation = lambda ctx: ctx.super(),
parent = swift_library,
cfg = opt_transition,
)
That’s it. The new opt_swift_library behaves exactly like swift_library, except it always builds in opt mode.
For the sake of completeness, here is the entire .bzl file:
load("@rules_swift//swift:swift_library.bzl", "swift_library")
def _opt_transition_impl(_settings, _attr):
return {"//command_line_option:compilation_mode": "opt"}
opt_transition = transition(
implementation = _opt_transition_impl,
inputs = [],
outputs = ["//command_line_option:compilation_mode"],
)
opt_swift_library = rule(
implementation = lambda ctx: ctx.super(),
parent = swift_library,
cfg = opt_transition,
)
Wrapping Up
There’s much more you can do with rule extensions, but being able to easily apply transitions to third-party rules is already a huge win.
To learn more about what’s possible, check out Keith’s excellent article on this topic.