list: warn about broken Caskroom symlinks from the Bash fast path

94392d0307 added this warning to the Ruby command, but bare listings are
normally served by the Bash fast path, which returns before the Ruby
command loads - so the warning never fired for the plain brew list
--cask invocations it was written for. Emit the same warning from
list.sh, and point the Bash list test's HOMEBREW_LIBRARY at the
production-shaped Library directory so the fast path can source utils.sh
for opoo the way a real brew does.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Anthony Holland
2026-07-21 21:34:04 +12:00
co-authored by Claude Fable 5
parent 5d9bd4afd7
commit 8114bb85d3
3 changed files with 25 additions and 3 deletions
+2
View File
@@ -254,6 +254,8 @@ module Homebrew
# A broken symlink in the Caskroom (e.g. a dangling cask rename alias) lists
# like an installed cask but cannot load or uninstall, so flag it.
# Keep in sync with the broken-symlink warning in `homebrew-list` in
# Library/Homebrew/list.sh.
sig { void }
def warn_about_broken_caskroom_symlinks
broken_symlinks = Cask::Caskroom.path.glob("*").select { |child| child.symlink? && !child.exist? }
+17
View File
@@ -258,6 +258,23 @@ homebrew-list() {
echo "${cask_output}"
fi
# Keep in sync with Homebrew::Cmd::List#warn_about_broken_caskroom_symlinks
# in Library/Homebrew/cmd/list.rb.
local broken_cask_symlinks=()
local cask_path
for cask_path in "${HOMEBREW_CASKROOM}"/*
do
[[ -L "${cask_path}" && ! -e "${cask_path}" ]] || continue
broken_cask_symlinks+=("${cask_path##*/}")
done
if ((${#broken_cask_symlinks[@]} > 0))
then
source "${HOMEBREW_LIBRARY}/Homebrew/utils.sh"
local joined_broken_cask_symlinks
printf -v joined_broken_cask_symlinks '%s, ' "${broken_cask_symlinks[@]}"
opoo "Broken Caskroom symlinks (\`brew cleanup\` removes them): ${joined_broken_cask_symlinks%, }"
fi
return 0
fi
}
+6 -3
View File
@@ -38,7 +38,7 @@ RSpec.describe Homebrew::Cmd::List do
{
"HOMEBREW_CASKROOM" => Cask::Caskroom.path.to_s,
"HOMEBREW_CELLAR" => HOMEBREW_CELLAR.to_s,
"HOMEBREW_LIBRARY" => HOMEBREW_LIBRARY_PATH.to_s,
"HOMEBREW_LIBRARY" => HOMEBREW_LIBRARY_PATH.parent.to_s,
"HOMEBREW_PREFIX" => HOMEBREW_PREFIX.to_s,
}.merge(env),
"/bin/bash", "-c", <<~SH,
@@ -85,7 +85,7 @@ RSpec.describe Homebrew::Cmd::List do
homebrew-list list --versions --json
}
check "formulae and casks" 0 "${EXPECTED_PLAIN}" "" homebrew-list list
check "formulae and casks" 0 "${EXPECTED_PLAIN}" "${EXPECTED_PLAIN_STDERR}" homebrew-list list
check "formula and cask versions JSON" 0 "${EXPECTED_JSON}" "" homebrew-list list --versions --json
check "formula versions JSON" 0 "${EXPECTED_FORMULA_JSON}" "" \\
homebrew-list list --versions --json --formula
@@ -172,6 +172,7 @@ RSpec.describe Homebrew::Cmd::List do
(HOMEBREW_PREFIX/"var/homebrew/pinned_casks").mkpath
FileUtils.ln_s Cask::Caskroom.path/"local-caffeine/1.2.3",
HOMEBREW_PREFIX/"var/homebrew/pinned_casks/local-caffeine"
FileUtils.ln_s "missing-cask", Cask::Caskroom.path/"dangling-alias"
empty_cellar = mktmpdir
empty_caskroom = mktmpdir
@@ -194,7 +195,9 @@ RSpec.describe Homebrew::Cmd::List do
"EXPECTED_EMPTY_JSON" => list_versions_json,
"EXPECTED_FORMULA_JSON" => list_versions_json(formulae: formulae_json),
"EXPECTED_JSON" => list_versions_json(formulae: formulae_json, casks: casks_json),
"EXPECTED_PLAIN" => "testball\nlocal-caffeine\n",
"EXPECTED_PLAIN" => "testball\ndangling-alias\nlocal-caffeine\n",
"EXPECTED_PLAIN_STDERR" => "Warning: Broken Caskroom symlinks " \
"(`brew cleanup` removes them): dangling-alias\n",
"NO_JQ_CASKROOM" => no_jq_caskroom.to_s,
"NO_JQ_CELLAR" => no_jq_cellar.to_s,
"NO_JQ_PATH" => no_jq_root.to_s,