Skip to content

fix(ujust): ship self-contained shell completions over common's broken loader - #1305

Open
kylerankin wants to merge 1 commit into
projectbluefin:testingfrom
kylerankin:fix/ujust-shell-autocomplete
Open

kylerankin wants to merge 1 commit into
projectbluefin:testingfrom
kylerankin:fix/ujust-shell-autocomplete

Conversation

@kylerankin

Copy link
Copy Markdown

Problem

ujust <Tab> completes nothing in bash or zsh (bluefin#1171).

projectbluefin/common generates the ujust completions with just --completions <shell> | sed, but just --completions emits a single self-referential line (eval "$(JUST_COMPLETE=bash just)") that the sed turns into eval "$(JUST_COMPLETE=bash ujust)". Sourcing that registers no completion binding — complete: ujust: no completion specification — so it never completes.

COPY --from=common /system_files/shared in the ctx stage of this Containerfile overwrites bluefin's static completions, so the broken shim ships instead of bluefin's self-contained bash/zsh completions.

Fix

  • Containerfile: preserve bluefin's static completions in __keep before common's overlay and restore them after, so they win over the broken generated shim. __keep lives only in the scratch-based ctx stage, which is mounted at /ctx/system_files in the image build, so it does not leak into the image.
  • build_files/base/20-tests.sh: assert the shipped completion registers a real binding (complete -F _ujust ujust / #compdef ujust) so a dead shim fails the build instead of shipping silently.
  • tests/unit/20-tests_test.bats: validate the shipped completion content and reject the broken dynamic loader.

Tested

  • bats tests/unit/ — all 254 tests pass (including the new "rejects a broken dynamic ujust completion loader" test).
  • Confirmed empirically that sourcing common's completion registers no binding while bluefin's registers complete -F _ujust ujust.
  • bash -n clean on build_files/base/20-tests.sh; no trailing whitespace; all edited files end with a newline.

Closes #1171

— hive: backend=pi model=lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K

@kylerankin
kylerankin requested a review from a team as a code owner September 18, 2026 04:05
…n loader

`common` generates ujust completions with `just --completions <shell> | sed`,
but `just --completions` emits a single self-referential line
(`eval "$(JUST_COMPLETE=bash just)"`) that the sed turns into
`eval "$(JUST_COMPLETE=bash ujust)"`. Sourcing that registers no completion
binding (`complete: ujust: no completion specification`), so `ujust <TAB>`
completes nothing.

`COPY --from=common /system_files/shared` in the `ctx` stage overwrites
bluefin's static completions, so the broken shim ships instead of bluefin's
self-contained bash/zsh completions, which do define a real binding
(`complete -F _ujust ujust` / `#compdef ujust`).

Preserve bluefin's completions in `__keep` before common's overlay and restore
them after, so they win. Add a 20-tests.sh guard that asserts the shipped
completion registers a real binding, so a dead shim fails the build instead of
shipping silently.

Closes projectbluefin#1171

Assisted-by: Pi <model:lemonade/Ornith-1.5-35B-A3B-GGUF-Q6_K>
Signed-off-by: kylerankin <kylerankin@users.noreply.github.com>
@kylerankin
kylerankin force-pushed the fix/ujust-shell-autocomplete branch from 33ec2ea to 9c5832b Compare September 18, 2026 04:17

@Danathar Danathar left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Containerfile change won't build as written.

The ctx stage is FROM scratch, and every COPY in it without --from reads from the build context, not from the stage's filesystem. So:

COPY system_files/.../ujust /__keep/ujust/bash-completion   # writes into the ctx stage
...
COPY /__keep/ujust/bash-completion /system_files/...        # reads from the build context — no such path

The second COPY fails with "file not found" because /__keep only exists inside the stage. The unit tests passed because they never build the image.

If you want a downstream stop-gap, the round trip is unnecessary — just copy the files from the context again after the common overlay:

COPY --from=common /system_files/shared /system_files/shared
COPY --from=common /system_files/bluefin /system_files/shared
COPY --from=brew /system_files /system_files/shared
COPY /system_files/shared/usr/share/bash-completion/completions/ujust /system_files/shared/usr/share/bash-completion/completions/ujust
COPY /system_files/shared/usr/share/zsh/site-functions/_ujust /system_files/shared/usr/share/zsh/site-functions/_ujust

But the real fix is projectbluefin/common#1129, which replaces the generated shim with hand-written bash/zsh/fish completions at the source. This is the fourth downstream attempt at the same thing (#1236, #1262, #1270). Unless common#1129 stalls, I'd rather land that and let the overlay carry the working files, so the bluefin Containerfile doesn't need a permanent carve-out.

The 20-tests.sh guard and the bats test are reasonable on their own and would be worth keeping regardless.

This branch has not been deployed

No deployments
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.

2 participants