Skip to content

feat: install bash and zsh completions for gt#30

Open
sumanthratna wants to merge 1 commit into
withgraphite:masterfrom
sumanthratna:feat/install-shell-completions
Open

feat: install bash and zsh completions for gt#30
sumanthratna wants to merge 1 commit into
withgraphite:masterfrom
sumanthratna:feat/install-shell-completions

Conversation

@sumanthratna

Copy link
Copy Markdown

Install bash and zsh completions for gt

brew install withgraphite/tap/graphite currently installs no shell completions, even though the CLI ships a gt completion command. This PR generates and installs them at install time using Homebrew's standard generate_completions_from_executable helper.

Staleness isn't a concern with this approach: the script yargs emits is a thin shim that invokes gt --get-yargs-completions <words> live on every Tab press, so the installed file never goes out of date as gt's commands evolve — it only needs to be installed once.

Supersedes #3

Credit to @jalaziz for the original attempt in #3. Investigating why that diff "didn't work as expected", I found two root causes, both fixed here:

  1. feat: Generate shell completions on install #3 requested :fish, which yargs cannot emit. gt is built on yargs, whose completion command only generates bash or zsh scripts, selected via the SHELL environment variable (which generate_completions_from_executable sets per shell). Under SHELL=fish, yargs falls back to emitting a bash script, which Homebrew then installed into fish's completions directory — a broken fish "completion" that fails the moment it's exercised. This PR explicitly passes shells: [:bash, :zsh] (the helper's default list includes fish, so it must be overridden).

  2. The yargs zsh script only registers the completer. It ends with compdef _gt_yargs_completions gt and never invokes the function (Generate zsh autoload completion function file yargs/yargs#2402; the #compdef gt header came in Zsh completion is now installable system-wide yargs/yargs#1856). When zsh autoloads _gt from fpath on the first Tab of a session, the file runs, registers the completer, and returns — completing nothing on that first press. This PR appends a _gt_yargs_completions "$@" invocation to the installed _gt so the first Tab works.

What the diff does

  • Adds an install_shell_completions helper, called from each of the three def install blocks, in the template (formula-templates/graphite.rb) and both rendered formulas (Formula/graphite.rb, Formula/graphite-beta.rb) so the release pipeline won't clobber the change on the next version bump.
  • shell_parameter_format: :none — yargs keys on the SHELL env var the helper sets; it would reject gt completion bash.
  • chmod 0555, bin/"gt" before generating — the downloaded release artifact carries no exec bit, and Homebrew normalizes permissions only after install returns, so without it the helper fails with brew: exec failed (EACCES) (reproduced during testing).
  • Appends the zsh invocation line described above.

Per the discussion in #4, the diff is intentionally minimal — no unrelated audit cleanups, no changes to version/test.

Testing (macOS arm64, gt 1.8.6)

Installed the patched formula via a local tap (current Homebrew rejects brew install --formula <path>); install succeeds and Homebrew reports the completions:

==> Reinstalling sumanthratna/completions-test/graphite
🍺  /opt/homebrew/Cellar/graphite/1.8.6: 5 files, 86.8MB, built in 1 second
==> Caveats
zsh completions have been installed to:
  /opt/homebrew/share/zsh/site-functions

Generated zsh script is the registration shim plus the appended invocation:

$ head -1 /opt/homebrew/share/zsh/site-functions/_gt
#compdef gt
$ tail -1 /opt/homebrew/share/zsh/site-functions/_gt
_gt_yargs_completions "$@"

Bash variant landed in bash's dir (and is actually bash, not zsh):

$ grep "complete -o" /opt/homebrew/etc/bash_completion.d/gt
complete -o bashdefault -o default -F _gt_yargs_completions gt

No file was written into share/fish/vendor_completions.d/ (fish correctly excluded).

A clean zsh registers the completer:

$ zsh -fc 'fpath=("$(brew --prefix)/share/zsh/site-functions" $fpath); autoload -Uz compinit && compinit -D; print -r -- ${_comps[gt]}'
_gt

The live query the shim performs on each Tab returns the subcommand list:

$ gt --get-yargs-completions gt ""
completion:Set up `bash` or `zsh` tab completion.
abort:Aborts the current Graphite command halted by a rebase conflict.
absorb:Amend staged changes to the relevant commits in the current stack.
add:git add passthrough
...

And interactively, gt <Tab> completes on the first press of a fresh shell session (the failure mode from root cause 2).

brew style reports no offenses for the added lines (the one pre-existing ComponentsOrder warning is untouched, keeping this PR minimal).

Question for maintainers

This repo's src/index.ts renders the template into Formula/graphite-beta.rb only, and stable promotion appears to happen via a separate mechanism. If that pipeline renders Formula/graphite.rb from a template copy living outside this repo, that copy needs the same change or the next stable release will revert it — happy to adjust whatever is needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant