Skip to content

release/v1.4.1: fix broken fzf install + add shadow detection#20

Merged
YASoftwareDev merged 4 commits intomasterfrom
release/v1.4.1
May 3, 2026
Merged

release/v1.4.1: fix broken fzf install + add shadow detection#20
YASoftwareDev merged 4 commits intomasterfrom
release/v1.4.1

Conversation

@YASoftwareDev
Copy link
Copy Markdown
Owner

Summary

  • Fix: _install_fzf short-circuited before creating ~/.local/bin/fzf whenever ~/.fzf was already present from a previous install. With the symlink missing, an older unmanaged /usr/local/bin/fzf (pre-0.48) won PATH lookup, and modern ~/.fzf.zsh (source <(fzf --zsh)) errored with unknown option: --zsh on every shell startup. Now reconciles the symlink unconditionally.
  • Add: verify_managed_binaries helper in lib/utils.sh, invoked from install.sh and update.sh. Simulates the interactive zsh PATH (~/.local/bin ahead of system dirs as .zshrc sets it) and warns when any managed ~/.local/bin/<tool> is shadowed by an unmanaged binary. Covers fzf, rg, fd, jq, zoxide, delta, eza. Complements the existing _check_path_shadows which only targets /usr/local/bin/{nvim,xcape}.
  • Test: strict ~/.local/bin/fzf resolution check in test.sh so the regression class can never re-ship from a fresh install.

Background

Reproduced on a real host (magog, Ubuntu 24.04): ~/.fzf/bin/fzf was 0.67.0, /usr/local/bin/fzf was an old manual install pre-0.48, ~/.local/bin/fzf symlink was absent because the install was a re-run over an existing ~/.fzf. PATH order made the old binary win, breaking shell startup.

Test plan

  • Bash syntax + shellcheck on all touched scripts
  • bash test.sh workstation — new fzf strict-resolution check passes on clean dev box
  • verify_managed_binaries smoke test — silent on clean system, fires correctly when an unmanaged shadow is simulated
  • CI matrix (15 combos) — should pass; the new test.sh check is conditional on ~/.fzf existing
  • Manual: re-run curl ... | bash -s -- workstation on magog after merge → unknown option: --zsh should be gone

Release

Bumps VERSION 1.4.0 → 1.4.1, CHANGELOG entry under [1.4.1] - 2026-05-03.

After merge, tag v1.4.1 on master and create the GitHub release.

Wojciech Pędzimąż added 4 commits May 3, 2026 12:26
Fixes a class of broken installation where _install_fzf short-circuited
before creating ~/.local/bin/fzf whenever ~/.fzf was already present from
a previous install. With the symlink missing, an unmanaged
/usr/local/bin/fzf (older than 0.48) won PATH lookup, and modern fzf
shell integration (`source <(fzf --zsh)` in ~/.fzf.zsh) errored with
"unknown option: --zsh" on every shell startup.

Changes:
- modules/base.sh: _install_fzf now reconciles the ~/.local/bin/fzf
  symlink unconditionally — clone-skip no longer skips symlink creation.
- lib/utils.sh: new verify_managed_binaries helper that simulates the
  user's interactive zsh PATH and warns when an unmanaged binary
  shadows a managed ~/.local/bin tool. Quiet on a clean system.
- install.sh + update.sh: invoke the verifier as a final read-only step.
  Complements _check_path_shadows (which only covered /usr/local/bin
  tools nvim/xcape) by catching the inverse failure mode for
  ~/.local/bin tools.
- test.sh: strict resolution check for fzf — verifies symlink target
  and that command -v fzf resolves to a managed location. Catches this
  regression class before it ships.
- _install_fzf: drop skip_clone bool and conditional readlink check —
  ln -sf is already idempotent over both missing and stale targets.
- verify_managed_binaries: tool list moved into the function (single
  source of truth); replace _any_checked/_any_issue flag pair + PATH
  save/restore with a single inline PATH= prefix on `command -v`;
  collapse multi-line warnings to one. ~50 lines → ~15.
- install.sh / update.sh: callers become single-line invocations.
- test.sh: regression guard now a single conditional fail (success
  case is silent — the existing fzf-section checks already cover it).
- CHANGELOG: trim to essentials.
Self-test on real install scenarios revealed false-positive flooding:
the function assumed every tool in its hardcoded list lives at
~/.local/bin/<tool>, which is only true in nosudo mode. In sudo mode
(the common case), rg/fd/jq/zoxide/delta/eza are apt-installed at
/usr/bin and the function would warn "an unmanaged binary will run
instead" — falsely, since the apt binary IS the managed install.

The actual bug class is fzf-specific: modern ~/.fzf.zsh integration
(`source <(fzf --zsh)`) requires PATH to resolve to fzf >= 0.48.
Other tools tolerate stale shadows without breaking shell startup.

Reverting to minimal correct design:
- _install_fzf already self-heals on every install (idempotent symlink).
- update.sh fzf section now also self-heals — fixes existing broken
  installs from older dotfiles versions on next ./update.sh run.
- test.sh regression guard remains as the CI-time backstop.
@YASoftwareDev YASoftwareDev merged commit 142d262 into master May 3, 2026
15 checks passed
YASoftwareDev added a commit that referenced this pull request May 6, 2026
release/v1.4.1: fix broken fzf install + add shadow detection
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