Skip to content

fix(ujust): install fzf before choosing recipes - #862

Open
castrojo wants to merge 2 commits into
mainfrom
fix/ujust-install-fzf
Open

fix(ujust): install fzf before choosing recipes#862
castrojo wants to merge 2 commits into
mainfrom
fix/ujust-install-fzf

Conversation

@castrojo

@castrojo castrojo commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • install the Homebrew-managed fzf on demand when ujust --choose runs before brew-preinstall
  • preserve existing behavior for all other ujust commands
  • add Bats coverage for the on-demand install path

Fixes #861

Validation

  • bats tests/test_ujust.bats
  • just check
  • just test
  • shellcheck -S warning system_files/shared/usr/bin/ujust
  • actionlint workflow validation

pre-commit run --all-files is currently blocked by pre-existing untracked docs artifacts (docs/skills/INDEX.md front matter/index-link checks).

Summary by CodeRabbit

  • New Features

    • Automatically installs the fzf utility when using ujust --choose and it isn’t available.
    • Continues supporting standard ujust commands without installing unnecessary tools.
  • Tests

    • Added coverage verifying on-demand fzf installation and correct command execution.

Install the Homebrew-managed chooser on demand when --choose runs before brew-preinstall completes.

Assisted-by: GPT-5 via pi
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The ujust wrapper now installs missing fzf through Homebrew for --choose invocations before running just. New Bats tests verify installation, shell environment initialization, argument forwarding, and the non-installing --list path.

Changes

ujust fzf bootstrap

Layer / File(s) Summary
Conditional fzf bootstrap and dispatch
system_files/shared/usr/bin/ujust
Detects --choose with unavailable fzf, discovers Homebrew, installs and initializes fzf, then executes just with the fixed justfile and original arguments.
Bootstrap behavior validation
tests/test_ujust.bats
Mocks Homebrew and just, testing installation for --choose and bypass behavior for --list.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ujust
  participant Homebrew
  participant just
  User->>ujust: invoke --choose
  ujust->>Homebrew: install fzf
  Homebrew-->>ujust: provide shell environment
  ujust->>just: execute with fixed justfile and arguments
Loading

Possibly related issues

  • projectbluefin/dakota#938 — Addresses the ujust --choose failure by installing missing fzf.

Suggested labels: area/brew, size:M

Suggested reviewers: ahmedadan, inffy, renner0e

Poem

A rabbit found a chooser gone,
So brewed some fzf before the dawn.
“Choose!” it cried, “or simply list,”
While just received each argument kissed.
Hop, hop—commands now run bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the summary and validation, but it misses the template's required sections and exact issue-closing/AI-attribution details. Add the template sections: What does this change?, Why? with Closes #861, the PR pipeline block, checklist items, and AI attribution if applicable.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: installing fzf for ujust's chooser path.
Linked Issues check ✅ Passed The PR installs fzf on demand for ujust --choose and adds tests, matching the issue's reported crash and expected fix.
Out of Scope Changes check ✅ Passed The code and tests stay focused on the fzf-on-demand fix for ujust --choose without unrelated scope creep.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ujust-install-fzf

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🧹 Nitpick comments (2)
tests/test_ujust.bats (2)

12-23: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Make the mock prove that installed fzf is usable.

The fake installer only records the command, and fake just never checks for fzf. These tests therefore pass even if the installation or shellenv setup fails and the real chooser would still exit 127. Create a fake fzf in a separate Homebrew prefix during brew install fzf, add that prefix through shellenv, and make mock just fail when command -v fzf is unavailable. Also assert the logged order: install → shellenv → just.

Also applies to: 32-40

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_ujust.bats` around lines 12 - 23, Update the mock brew and just
scripts in the test setup so brew install fzf creates an executable fzf under a
separate Homebrew prefix and brew shellenv exposes that prefix in PATH; make
mock just verify command -v fzf succeeds and fail otherwise. Extend the test
assertions to require the call order install → shellenv → just.

32-50: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Cover the negative bootstrap branches.

Add cases for fzf already being present, Homebrew being absent, and brew install fzf failing. These branches have explicit production behavior but are currently untested.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_ujust.bats` around lines 32 - 50, Add tests in
tests/test_ujust.bats covering the --choose bootstrap branches: verify an
existing fzf skips installation, missing Homebrew follows the production
fallback/error behavior, and a failing brew install fzf is handled as expected.
Reuse the existing PATH, MOCK_BIN, CALLS, and assertions from the current ujust
tests while confirming no unintended command execution occurs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@system_files/shared/usr/bin/ujust`:
- Line 3: Update the argument check in the ujust bootstrap condition to iterate
over "$@" and match an argument exactly equal to --choose, rather than searching
the joined $* string. Preserve the existing fzf availability check and bootstrap
behavior when --choose is passed as its own argument.
- Around line 17-20: Update the brew shell initialization around eval
"${BREW_BIN}" shellenv to capture its output and propagate any shellenv failure
before dispatching just. After applying the environment, validate that command
-v fzf succeeds, and abort with a clear error if it is unavailable; only then
execute just with the existing arguments.

In `@tests/test_ujust.bats`:
- Around line 33-35: Update the test invocations using --choose in
tests/test_ujust.bats to set PATH exclusively to the mock directory, removing
/usr/bin:/bin from both affected run commands. Preserve the existing WORKDIR,
CALLS, MOCK_BIN, and absolute bash execution setup so the tests consistently
exercise bootstrap behavior.

---

Nitpick comments:
In `@tests/test_ujust.bats`:
- Around line 12-23: Update the mock brew and just scripts in the test setup so
brew install fzf creates an executable fzf under a separate Homebrew prefix and
brew shellenv exposes that prefix in PATH; make mock just verify command -v fzf
succeeds and fail otherwise. Extend the test assertions to require the call
order install → shellenv → just.
- Around line 32-50: Add tests in tests/test_ujust.bats covering the --choose
bootstrap branches: verify an existing fzf skips installation, missing Homebrew
follows the production fallback/error behavior, and a failing brew install fzf
is handled as expected. Reuse the existing PATH, MOCK_BIN, CALLS, and assertions
from the current ujust tests while confirming no unintended command execution
occurs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 81cc79c3-f551-4da4-a786-266f94fdd0e4

📥 Commits

Reviewing files that changed from the base of the PR and between e84aa32 and b33613c.

📒 Files selected for processing (2)
  • system_files/shared/usr/bin/ujust
  • tests/test_ujust.bats

Comment thread system_files/shared/usr/bin/ujust Outdated
#!/usr/bin/bash

just --justfile /usr/share/ublue-os/just/00-entry.just "${@}"
if [[ " ${*} " == *" --choose "* ]] && ! command -v fzf >/dev/null 2>&1; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Match --choose as an actual argument.

Joining arguments through $* means an argument such as "recipe --choose" also triggers the bootstrap, even though --choose was not passed as its own option. Iterate over "$@" and compare each argument exactly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@system_files/shared/usr/bin/ujust` at line 3, Update the argument check in
the ujust bootstrap condition to iterate over "$@" and match an argument exactly
equal to --choose, rather than searching the joined $* string. Preserve the
existing fzf availability check and bootstrap behavior when --choose is passed
as its own argument.

Comment thread system_files/shared/usr/bin/ujust Outdated
Comment on lines +17 to +20
eval "$("${BREW_BIN}" shellenv)"
fi

exec just --justfile /usr/share/ublue-os/just/00-entry.just "${@}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate brew shellenv failure before dispatch.

If shellenv fails, eval can receive an empty or partial command and still return successfully; just --choose then runs without usable fzf and can reproduce the original chooser failure. Capture and validate the environment initialization, then verify command -v fzf before executing just.

Proposed fix
-    eval "$("${BREW_BIN}" shellenv)"
+    if ! BREW_ENV="$("${BREW_BIN}" shellenv)"; then
+        echo "ujust: failed to initialize Homebrew environment" >&2
+        exit 1
+    fi
+    if ! eval "$BREW_ENV" || ! command -v fzf >/dev/null 2>&1; then
+        echo "ujust: fzf is still unavailable after Homebrew setup" >&2
+        exit 1
+    fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
eval "$("${BREW_BIN}" shellenv)"
fi
exec just --justfile /usr/share/ublue-os/just/00-entry.just "${@}"
if ! BREW_ENV="$("${BREW_BIN}" shellenv)"; then
echo "ujust: failed to initialize Homebrew environment" >&2
exit 1
fi
if ! eval "$BREW_ENV" || ! command -v fzf >/dev/null 2>&1; then
echo "ujust: fzf is still unavailable after Homebrew setup" >&2
exit 1
fi
fi
exec just --justfile /usr/share/ublue-os/just/00-entry.just "${@}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@system_files/shared/usr/bin/ujust` around lines 17 - 20, Update the brew
shell initialization around eval "${BREW_BIN}" shellenv to capture its output
and propagate any shellenv failure before dispatching just. After applying the
environment, validate that command -v fzf succeeds, and abort with a clear error
if it is unavailable; only then execute just with the existing arguments.

Comment thread tests/test_ujust.bats Outdated
Comment on lines +33 to +35
run env PATH="${WORKDIR}/bin:/usr/bin:/bin" \
CALLS="${WORKDIR}/calls.log" MOCK_BIN="${WORKDIR}/bin" \
bash "${UJUST}" --choose

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use an isolated PATH in the tests.

Appending /usr/bin:/bin makes the tests depend on the runner image. If either directory already contains fzf, the bootstrap is skipped and the first test exercises a different branch. Keep only the mock directories in PATH, with absolute /usr/bin/bash shebangs already making the scripts executable.

Also applies to: 44-46

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_ujust.bats` around lines 33 - 35, Update the test invocations
using --choose in tests/test_ujust.bats to set PATH exclusively to the mock
directory, removing /usr/bin:/bin from both affected run commands. Preserve the
existing WORKDIR, CALLS, MOCK_BIN, and absolute bash execution setup so the
tests consistently exercise bootstrap behavior.

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The on-demand path needs to fail closed before dispatching just. The current joined-argument search treats text containing --choose as the option, and a failed or ineffective brew shellenv can still fall through to just with fzf unavailable. Please match --choose as an exact argument, propagate shellenv failure, verify fzf is actually resolvable after applying the environment, and cover those failure paths with an isolated PATH in Bats.

- Match --choose as an exact argument instead of joined-string search
- Propagate brew shellenv failure before dispatching just
- Verify fzf is resolvable after shellenv and fail closed
- Strengthen test_ujust.bats with isolated PATH, fake fzf via shellenv,
  install→shellenv→just ordering, and negative paths

Assisted-by: Claude via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo
castrojo requested a review from hanthor July 28, 2026 01:42
@castrojo castrojo added 4-review A pull request is awaiting review. 3-clanker-queue Work admitted to the agent-maintained queue. and removed kind/bug 3-clanker-queue Work admitted to the agent-maintained queue. labels Jul 28, 2026

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approving. The ordering is correct and well-tested — install, then shellenv, then exec just, with each failure mode exiting distinctly (127 for missing brew / still-missing fzf, 1 for install or shellenv failure) and never falling through to just. Switching to exec is a nice incidental cleanup. The bats suite covers all five paths including the negative ones.

One behavioral note, not a blocker: ujust --choose now silently installs software into the user's Homebrew prefix as a side effect of a command that reads like "show me a menu." The installing missing fzf message goes to stderr, so it is at least visible. If you'd rather not have an implicit install, a read -p confirmation would be the alternative — but given --choose is unusable without fzf, auto-installing is defensible. Your call.


Generated by Claude Code

@castrojo
castrojo added this pull request to the merge queue Jul 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4-review A pull request is awaiting review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ujust --choose crashes on Bluefin because fzf isn't installed

2 participants