axodotdev / axodotdev/cargo-dist

Homebrew: no way to add a `head` stanza to the generated formula

Open
#2,457 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2.1k
Forks
149
Avg merge
1d 11h
Merged PRs (30d)
32

Description

I use dist to publish a Rust CLI through my own tap, and I wanted a development channel next to the
stable formula — `brew install --HEAD` to build the tip of `main`. As far as I can tell there's no
way to get a [`head` stanza](https://docs.brew.sh/Formula-Cookbook#unstable-versions-head) into the
formula dist generates.

The Homebrew installer config is `tap` / `formula` / `bin-aliases`, and none of those reach it.
There's no template or hook, and the formula is rewritten on every release, so hand-editing it
doesn't survive. The docs also mention that building a formula from source isn't supported, which
is what `head` needs — there's no artifact to checksum.

What I ended up with is a second formula in the same tap, hand-written, carrying only a `head`
spec:

```ruby
class BirchDev < Formula
desc "Modern interactive file tree for the terminal (development build)"
homepage "https://github.com/slukyano/birch"
license "MIT"
head "https://github.com/slukyano/birch.git", branch: "main"

depends_on "rust" => :build
conflicts_with "birch", because: "both install a birch binary"

def install
system "cargo", "install", *std_cargo_args(path: "crates/birch")
pkgshare.install "contrib/birch-cmux", "contrib/birch-tmux", "contrib/birch-herdr"
end
end
```

Then `brew install --HEAD slukyano/tap/birch-dev`, and `brew upgrade --fetch-HEAD birch-dev` to
pick up new commits. It works, and dist leaves it alone since it only regenerates the formula it
owns. The annoying parts are that the build recipe now lives in a second place by hand and will
drift as the project changes, that both formulae install the same binary so only one can be linked
at a time, and that a head-only formula can't be installed without passing `--HEAD` explicitly.

Two directions seem plausible to me, and they're not exclusive:

- An escape hatch — a file whose contents get injected into the generated class body, the way
`github-build-setup` and the custom `*-jobs` files work for CI. That needs no per-language
knowledge, and it would cover `caveats`, `service`, `livecheck`, `post_install` and a real
`test do` too.
- An opt-in `head` feature — `homebrew-head = true` or similar, with dist emitting the stanza and a
source-build install path. Nicer to use, though the install differs per project type.

Contributor guide

Open the contributing guide

Research direction

Start at the Homebrew generator handling tap, formula, and bin-aliases, then compare the existing github-build-setup and custom *-jobs extension points. Define whether the change supports injected formula content or an opt-in head source build; done should preserve generated formulas across releases and cover the selected installation path.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby, rust
Domain
build-system, release
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.