Quick Setup

Version 0.2.9 Updated Sep 24, 2026

Prerequisites

Install cargo-dylint and dylint-link:

cargo install cargo-dylint dylint-link

The published whitaker-installer crate requires Rust 1.85 or newer. This is the first stable compiler that supports the Rust 2024 edition used by the installer.

Published x86_64 GNU/Linux installer, dependency, and lint artefacts target the Ubuntu 22.04 GLIBC_2.35 baseline and do not require a newer glibc version. On an incompatible system, build Whitaker and its dependencies from source instead of using the published Linux artefacts.

Options:

  • --cranelift — Tell the installer to add the rustc-codegen-cranelift component via rustup component add. The rustc-codegen-cranelift component is not included in the standard nightly toolchain, so enable --cranelift when a project or CI pipeline requires the Cranelift back-end and would otherwise need an explicit rustc-codegen-cranelift component-add step before running the installer.
  • --skip-deps — Skip cargo-dylint/dylint-link installation check
  • --skip-wrapper — Skip wrapper script generation (prints DYLINT_LIBRARY_PATH instructions instead)
  • --no-update — Don't update existing repository clone
  • --suite-version REF (alias --suite-ref) — Build the lint suite from a given tag, branch or commit rather than from the default branch tip. See Pinning the lint suite
  • --no-source-fallback — Fail rather than build from source when a published artefact is absent. See Refusing a source build

Adding Whitaker to a project

Add the following to the workspace Cargo.toml:

[workspace.metadata.dylint]
libraries = [
  { git = "https://github.com/leynos/whitaker", pattern = "whitaker_suite" }
]

Then run the lints:

cargo dylint --all

Pinning the lint suite

The installer builds the suite from a Whitaker checkout. Without a pin it uses whatever is at the default branch tip, so a change to that branch alters lint results with no commit in the consuming repository: a gate can turn red on a branch that has not been touched. --suite-version names the reference to build from instead, so a suite change arrives as a reviewed bump.

whitaker-installer --suite-version v0.2.7

It accepts a tag, a branch or a commit, and the installer hands it to git to resolve.

Two consequences are worth knowing before pinning.

A pinned suite is built from source. Prebuilt lint libraries are published only for the branch tip, under the rolling tag, so a pin can never be served from them; the installer does not attempt the download at all when a pin is set, and compiles the suite locally instead. Pinning trades install time for reproducibility, and that is the whole of the trade: a pinned lane is slower on a cold cache and does not change what it produces.

The prebuilt path would not help a pin even if artefacts existed for every tag. A lint library must be built with the exact toolchain that will load it, and artefacts are named for the toolchain they were built with, so a pin held against a newer rust-toolchain.toml misses and builds from source anyway. The guarantee a pin buys is reproducibility, not speed.

With --no-update, an already-local --suite-version reference resolves without network access. A later unpinned update reattaches a detached managed clone to its default branch before pulling.

A pin cannot be applied from inside a Whitaker checkout. Checking out a reference there would move the working tree, so the installer refuses and says so. Run it from another directory, where it manages its own clone, or check out the reference directly.

Pinning the installer and pinning the suite are separate decisions. The installer's version selects the tool; --suite-version selects the lints it builds.

Version pinning through Cargo metadata

When Dylint is driven directly rather than through the installer, pin to a specific release tag or commit:

[workspace.metadata.dylint]
libraries = [
  { git = "https://github.com/leynos/whitaker", pattern = "whitaker_suite", tag = "v0.1.0" }
]

Or pin to a specific commit:

[workspace.metadata.dylint]
libraries = [
  { git = "https://github.com/leynos/whitaker", pattern = "whitaker_suite", rev = "abc123def456" }
]

Rolling release downloads

Whitaker publishes a rolling pre-release tag that is continuously updated and overwritten on every push to main. It is intended for early adopters who want the latest available build outputs before the next stable release is cut.

Rolling releases are best-effort builds. If some matrix legs fail, Whitaker still publishes the artefacts that were built successfully. For example, a target-specific cargo-dylint archive may be missing from one rolling release even though other target archives were updated successfully. Do not assume that every supported target is present in every rolling release.

This best-effort policy applies to ordinary pushes and unforced manual runs. A forced manual dependency-binary rebuild is a recovery operation: it republishes only after both five-target build matrices and all required lint, manifest, dependency, and checksum assets pass validation. If that check fails, the existing rolling release remains unchanged.

Stable releases differ from rolling: a stable tag is expected to contain the complete artefact set for the release. For production installs, pin to a stable release tag rather than consuming rolling.

Scripts or CI pipelines that consume rolling-release archives should verify that the required target archive exists before proceeding. Treat missing archives as an expected condition for rolling releases rather than assuming the artefact set is complete.

Refusing a source build

The installer prefers published binaries and falls back to building from source when one is missing: a prebuilt lint library becomes a local compilation, and a Dylint tool archive becomes cargo install. Both succeed, which is the difficulty. A run that took either reports success while having built something nobody pinned, and the only sign is a line in the log.

--no-source-fallback, or WHITAKER_NO_SOURCE_FALLBACK in the environment for callers that cannot easily add a flag, turns each fallback into an error naming the artefact and why it could not be fetched:

whitaker-installer --no-source-fallback

Any value other than an empty string, 0 or false enables the rule. The comparison ignores case and surrounding whitespace, so FALSE and false also turn it off. Exporting the variable at all expresses an intention, and reading an unrecognized value as off would quietly remove a protection; a value that is not valid text enables the rule for the same reason.

The flag is rejected alongside --build-only, --experimental and --suite-version. Each of those requires a source build, so combining them is a contradiction rather than a preference, and the installer says so instead of silently preferring one.

Each installation that selects a suite source prints the path it took on standard output. A dry run selects none, so it prints nothing:

whitaker-installer: suite-source=prebuilt

The value is prebuilt or source. It reports where the suite came from and adds to the existing checks rather than replacing them: install-whitaker still scans the installer's standard error for the fallback notice and fails an unapproved source build on what it finds there. Reading only the marker would let a source build the marker missed pass as prebuilt.

The streams are separate on purpose. The marker is the only thing on standard output, so it can be parsed; the fallback notice and every other diagnostic go to standard error.

The rolling release is the reason this exists. It is republished on every push to main, and a consumer whose install starts during a republish can miss an archive that is present moments later. In CI a source build is a defect rather than a degraded mode, so fail and retry rather than proceeding.

Selecting individual lints

To load specific lints instead of the full suite, specify each lint explicitly:

[workspace.metadata.dylint]
libraries = [
  { git = "https://github.com/leynos/whitaker", pattern = "crates/module_max_lines" },
  { git = "https://github.com/leynos/whitaker", pattern = "crates/no_expect_outside_tests" }
]

Standard vs Experimental Lints

Whitaker lints are divided into two categories:

  • Standard lints are stable, well-tested, and included in the default suite. They are recommended for general use and have predictable behaviour.
  • Experimental lints are newer or more aggressive checks that may produce false positives or undergo breaking changes between releases. They must be explicitly enabled.

The default whitaker_suite pattern includes only standard lints. Whitaker currently ships one experimental lint, rstest_helper_should_be_fixture, which is available only when experimental lints are enabled.

Enabling experimental lints

Via standalone installer

whitaker-installer --experimental

This enables experimental suite features when building whitaker_suite. To build experimental lints as individual libraries, combine it with --individual-lints. Explicit --lint requests for experimental lints also require --experimental; without that opt-in the installer rejects the request before building anything.