theoremlp / rules_multitool

Bazel rules for ergonomic tool definitions
Apache License 2.0
24 stars 6 forks source link

Refactor to properly support bzlmod #9

Closed mark-thm closed 9 months ago

mark-thm commented 9 months ago

In MODULE.bazel the main interface is something called a module extension, which provides a declarative set of dataclasses in lieu of WORKSPACE's macros. It's not possible to call register_toolchains inside a module extension or inside a repository rule, and we historically relied on calling register_toolchains in the main multitool macro for developer ergonomics. However, modules do provide an ergonomic approach: register_toolchains can take an :all selector to register toolchains from a dynamically retrieved list of target, and as long as rules_multitool's module calls register_toolchains we can maintain the current ergonomics. As a result, we need to change the repositories we create, though.

Before this PR

Any series of http_file, http_archive or similar repository rules download and produce executable file artifacts to be consumed by multitool. multitool creates a repository per call that depends on the executable files.

In this setup, we end up with repositories like:

Since we end up with a repository per multitool there's no way to query all toolchains easily.

After this PR

We create a hub repo, @multitool, laid out as follows:

Then, we can register @multitool//toolchains:all in rules_multitool so that users don't need to worry about things.

Additionally, we dropped the need for http_archive or http_file repo rules, and instead take care of downloading artifacts based on a JSON lockfile that locks URLs, sha256 checksums, and other details about the tools. In a subsequent PR, we'll add tooling to convert between a sparser file and this lockfile so that it's easier to update tools.

Last, it should be noted that we coerce everything into a single hub repository. It should be possible to support multiple hubs with some additional effort later on, but for now this seems like a reasonable trade given our typical usage of this ruleset.

A good place to start reviewing this changeset would be multitool/private/multitool.bzl. A pretty rich example is now available in examples/module.