axodotdev / axodotdev/cargo-dist
Homebrew installer: install man pages and shell completions (man1.install / generate_completions_from_executable)
- Dominant language
- Rust
- Stars
- 2.1k
- Forks
- 149
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 32
Description
## Summary
The generated Homebrew formula installs the binary and auto-docs (README/LICENSE/CHANGELOG), then dumps every other file into `pkgshare` via `pkgshare.install(*leftover_contents)`, which is off the manpath and is not a completions directory. As a result, **`man ` does not work for Homebrew users**, and shell completions aren't picked up, even when the project ships them.
See the current template behavior: [`templates/installer/homebrew.rb.j2#L76-L106`](https://github.com/axodotdev/cargo-dist/blob/v0.32.0/cargo-dist/templates/installer/homebrew.rb.j2#L76-L106). This is the per-installer behavior already documented in #543 (*"everything else goes into the 'share' directory"*).
## Proposal
When the binary can emit its own man page / completions, have the generated Homebrew formula install them into the standard locations, mirroring the idiomatic homebrew-core pattern (e.g. ripgrep's formula):
```ruby
generate_completions_from_executable(bin/"", "--generate", shell_parameter_format: "complete-")
(man1/".1").write Utils.safe_popen_read(bin/"", "--generate", "man")
```
Concretely, gated behind opt-in config (the command/subcommand that prints the page/completions varies per project), e.g.:
```toml
[dist]
# whatever shape fits dist's config
man-page = " man" # command whose stdout is the roff man page
completions = " completions" # or via generate_completions_from_executable
```
Ideally the same opt-in would drive the **shell/powershell installers** too (placing pages/completions under an FHS-style layout). This overlaps with #1233, though that issue currently scopes layouts to the script installers and excludes Homebrew.
## Why this matters / use case
[`git-id`](https://github.com/jmarette/git-id) ships via dist with `installers = ["shell", "powershell", "homebrew"]`. Because the formula drops its man page into `pkgshare`, `man git-id` (and `git id --help`, which Git rewrites to `man git-id`) is broken for Homebrew users. The current workaround is to make the binary install its own man page at first run (`git id init`); it works, but it's a hack a packager should ideally handle. The binary already prints its page via `git-id man` (clap_mangen), so the formula just needs to write it to `man1`.
## Prior art / related
- #27: shell completions ("out of scope for MVP", still open)
- #543: per-installer includes/structure (documents the current `pkgshare` dump)
- #1233: more install layouts (FHS), currently scoped to shell/powershell installers, explicitly excluding Homebrew
- #1748: extra files in releases (completions), punted to the includes-consistency problem
- homebrew-core ripgrep formula: the reference for `generate_completions_from_executable` + `(man1/...).write`
Contributor guide
Research direction
Start with templates/installer/homebrew.rb.j2#L76-L106 and read the linked issues #27, #543, #1233, and #1748 to understand existing installer and layout constraints. Trace how installer configuration is represented, then define the opt-in behavior so generated Homebrew formulas place man pages and shell completions in standard locations, with corresponding behavior for the shell and PowerShell installers if supported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby, rust
- Domain
- release
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100