Intro #
The simple structure we used for the packaged repo is convenient for basic scenarios. However, we usually want to separate the externally available rule definitions from their implementation. A conventional way to achieve this is to create a file that will only contain the rule names:
load(
"//example/packaged:rules.bzl",
_foo_rule = "foo_rule",
_bar_rule = "bar_rule",
...
)
foo_rule = _foo_rule
bar_rule = _bar_rule
...
Implmentation #
The first step towards this goal is to restructure the demo_repo
:
demo_repo/
├── internal/
│ ├── BUILD.bazel
│ └── rules.bzl
├── BUILD.bazel
├── defs.bzl
└── WORKSPACE.bazel
As we can see, the rules are in the internal
folder now.
The name only communicates our intent as Bazel does not prevent
users from loading rules directly. We also need to mark the folder as
a package with an empty BUILD.bazel
file.
The core of the pattern is the defs.bzl
file where we load and expose
the rules:
load(
"//internal:rules.bzl",
_demo_rule = "demo_rule",
)
demo_rule = _demo_rule
The users can then load them normally:
load("@demo_repo//:defs.bzl", "demo_rule")
demo_rule(
name = "file",
out = "hello.txt",
)
The code for the example is in this repo.