Skip to content

rivethealth/rivet-bazel-util

Repository files navigation

Bazel Util

Bazel utilities

Overview

  • bazel-mrun: Build and run multiple targets in parallel.
  • bazel-watchrun: Build and run multiple targets, restarting them after changes.

Install

Bazel repositority

Add this project as a Bazel repository to the workspace:

WORKSPACE.bazel
# Rivet Bazel Util

RIVET_BAZEL_UTIL_VERSION = "..." # commit

http_archive(
    name = "rivet_bazel_util",
    # sha256 = "...", # digest
    strip_prefix = "rivet-bazel-util-%s" % RIVET_BAZEL_UTIL_VERSION,
    url = "https://github.com/rivethealth/rivet-bazel-util/archive/%s.tar.gz" % RIVET_BAZEL_UTIL_VERSION,
)

The targets can be invoked:

bazel run @rivet_bazel_util//mrun:bin -- target1 target2
bazel run @rivet_bazel_util//watchrun:bin -- target1 target2

Linux

Or it can be installed natively, by building and installing a tarball.

Installation
bazel build bazel:tar

rm -fr /opt/rivet-bazel-util mkdir /opt/rivet-bazel-util tar xf
bazel-bin/bazel/tar.tar -C /opt/rivet-bazel-util

printf '#!/bin/sh -e\nexec /opt/rivet-bazel-util/mrun "$@"\n' > /usr/local/bin/bazel-mrun
chmod +x /usr/local/bin/bazel-mrun
printf '#!/bin/sh -e\nexec /opt/rivet-bazel-util/watchrun "$@"\n' > /usr/local/bin/bazel-watchrun
chmod +x /usr/local/bin/bazel-watchrun

Note that bazel-watchrun relies on an aspect, and therefore still requires adding the rivet_bazel_util repository to the workspace.

Features

bazel-mrun

Build and run multiple targets in parallel. Like bazel run, but for multiple targets.

Usage

Usage
usage: bazel-mrun [-h] [--alias TARGET=ALIAS] [--bazel-arg BAZEL_ARG]
                  [--parallelism PARALLELISM] [--width WIDTH]
                  [target [target ...]]

Build and run Bazel executables.

positional arguments:
  target                Targets to run

optional arguments:
  -h, --help            show this help message and exit
  --alias TARGET=ALIAS  aliases
  --bazel-arg BAZEL_ARG
                        bazel argument
  --parallelism PARALLELISM
                        maximum concurrent processes
  --width WIDTH

Implementation

Implementation
  1. Query Bazel for the excutable outputs.
  2. Builds the targets in parallel using bazel build.
  3. Run each executable in parallel.
  4. Prefix stdout and stderr with the target's name.

bazel-watchrun

Build and run multiple targets, restarting them after changes. Like ibazel run, but for multiple targets.

Usage

Usage
usage: bazel-watchrun [-h] [--alias TARGET=NAME] [--bazel-arg BAZEL_ARG]
                      [--ibazel-arg IBAZEL_ARG] [--width WIDTH]
                      [target [target ...]]

Build and run Bazel executables.

positional arguments: target Targets to run

optional arguments: -h, --help show this help message and exit --alias
TARGET=NAME --bazel-arg BAZEL_ARG bazel argument --ibazel-arg IBAZEL_ARG ibazel
argument --width WIDTH

Controlling restarts

A target can control when it restarts by providing a digest output group consisting of a single file. The executable is restarted when the contents of that file change. Bazel-watchrun will also send the executable ibazel-like events on stdin.

For example, consider a webpack server. Changes to Node.js files (weback config, npm dependencies) should trigger a restart, but changes to browser sources should be quickly rebundled without a full process restart. To accomplish this, the target provides a digest output group for the Node.js sources, and the executable listens for build success notifications on stdin and checks for changed browser sources.

Implementation

Implementation
  1. Query Bazel for the excutable outputs.
  2. Watch and rebuild the targets in parallel using ibazel build, including the additional digest output group. If the target does not already provide the digest output group, an aspect generates it by hashing the executable and runfile tree.
  3. Read the profile events from ibazel. Each time a build is completed, check the digests, and restart any executable with a changed digest.
  4. If the target provided its own digest, pass write ibazel-like events to its stdin.
  5. Prefix stdout and stderr with the target's name.