retch-cli 0.18.0

A fast, feature-rich system information fetcher written in Rust (similar to fastfetch or neofetch)
Documentation
# SPDX-FileCopyrightText: 2026 Ken Tobias
# SPDX-License-Identifier: GPL-3.0-or-later
#
# Homebrew formula for retch.
#
# THIS IS A TEMPLATE, NOT A PUBLISHABLE FORMULA.
# ----------------------------------------------
# `@VERSION@` and `@SHA256@` are filled in by `scripts/render_packaging.py` at publish
# time, from the tag being released and the sha256 of the tarball that was actually
# downloaded. `just brew-publish <version>` renders it and pushes the *rendered* file to
# the tap at github.com/l1a/homebrew-retch. Nothing is hand-edited in the tap.
#
# It records no version, because recording one is what went wrong elsewhere: `packaging/
# aur/PKGBUILD` was an inert "reference copy" that nothing rendered, published or checked,
# and it reached **eleven releases** of drift (0.6.12 in-repo while the AUR served 0.6.23)
# while every CI run stayed green. v0.7.1 answered that with a guard and v0.17.2 gave this
# formula one on day one -- but a guard only ever detects a disagreement between two
# recordings of the same fact. Writing the fact down once, at publish time, removes the
# disagreement instead. See scripts/render_packaging.py.
#
# WHY A TAP RATHER THAN homebrew-core
# ------------------------------------
# homebrew-core has notability requirements comparable to the tldr-pages submission that
# was already declined for this project (NOTES.md §3). A tap needs no approval and is the
# realistic first step; moving to core later is a separate decision, not a prerequisite.
#
# WHY A SOURCE BUILD AND NOT A BOTTLE
# ------------------------------------
# A bottle is a prebuilt binary that CI must build, sign and upload per macOS version and
# architecture. This formula builds from source and needs only Rust, which Homebrew can
# supply as a build-time dependency. The trade is a slower first install against no new CI
# secrets and no release-asset plumbing. Revisit when install time is an actual complaint.
#
# `url` and `sha256` carry sentinels rather than a release, so there is no "trailing
# Cargo.toml" state to reason about and no bump to forget. `scripts/brew_check.py` asserts
# the sentinels are still there; `scripts/render_packaging.py` refuses to write a file that
# still contains one.
class Retch < Formula
  desc "Fast, feature-rich system information fetcher"
  homepage "https://github.com/l1a/retch"
  url "https://github.com/l1a/retch/archive/refs/tags/v@VERSION@.tar.gz"
  sha256 "@SHA256@"
  license "GPL-3.0-or-later"
  head "https://github.com/l1a/retch.git", branch: "main"

  depends_on "rust" => :build

  def install
    # `std_cargo_args` ALREADY passes `--locked` (along with `--root` and `--path`), so it
    # must not be repeated: cargo rejects a duplicate outright with
    # "the argument '--locked' cannot be used multiple times". Found by the `brew` CI job;
    # the formula parsed and the guard passed, and only a real install surfaced it.
    #
    # `--locked` is load-bearing here for the same reason the COPR spec says never to drop
    # it: Homebrew builds with network access and no vendored dependencies, so Cargo.lock
    # is the only thing pinning resolution to what CI actually tested. That is why
    # brew_check.py asserts `std_cargo_args` is still used rather than merely looking for
    # the flag — dropping it would silently unpin resolution.
    system "cargo", "install", *std_cargo_args

    # Install the COMMITTED man page rather than regenerating it. The AUR PKGBUILD
    # regenerated its own with mandown and shipped a page footed `$DATE` / `retch $pkgver`
    # for months (fixed in v0.7.0); the tarball already carries a correct page, so there is
    # nothing to gain and a whole failure mode to avoid.
    man1.install "docs/retch.1"

    # Generated by the binary that was just built, so completions cannot disagree with the
    # CLI they describe. `--completions=<shell>` is the flag's `=`-joined form, which is
    # what `shell_parameter_format` produces here.
    #
    # `shells:` is deliberately omitted: bash/zsh/fish is the default, and passing it
    # explicitly is flagged by `brew audit --strict` as redundant. The `brew` CI job
    # asserts all three completion files are installed and non-empty, so relying on the
    # default is checked rather than assumed.
    generate_completions_from_executable(bin/"retch", shell_parameter_format: "--completions=")
  end

  test do
    # `--version` proves the binary runs and is the version the formula claims.
    assert_match version.to_s, shell_output("#{bin}/retch --version")

    # `--fields os` proves it can actually probe the machine — the thing that would break
    # under a missing framework link — while touching nothing but local system calls.
    # (It is also 3.4 ms against `--short`'s 31 ms, and reaches no network at all.)
    #
    # **THE OUTPUT IS ANSI-STRIPPED BEFORE MATCHING.** Up to 0.17.x retch colourised even
    # when piped, so the label and its colon were separated by escapes and a literal
    # `/OS:/` never matched:
    #   "\e[38;2;0;255;255mOS\e[39m\e[38;2;128;128;128m:\e[39m \e[...mmacOS 26.6.2"
    # Two earlier versions of this test failed on exactly that. Since 0.18.0 piped output
    # is plain by default (`--color auto`), but the strip stays: it costs nothing, and it
    # keeps this assertion independent of how retch decides whether to colour.
    #
    # The pattern matches the whole `ESC [ ... <final byte>` form rather than SGR (`m`)
    # only: chafa opens a run with `\e[?25l`, and an SGR-only strip leaves six characters
    # behind — the measurement bug recorded in v0.9.2 and re-recorded in v0.11.5.
    plain = shell_output("#{bin}/retch --fields os --no-logo").gsub(/\e\[[0-9;?]*[a-zA-Z]/, "")
    assert_match(/OS:/, plain)

    # The man page must be installed and carry a real version footer — the `$DATE` /
    # `$pkgver` defect the AUR package shipped for months would pass a mere existence check.
    assert_path_exists man1/"retch.1"
    assert_match "retch #{version}", (man1/"retch.1").read
  end
end