testsAndMisc/meta/scripts/disk_cleanup_check.sh
Krzysztof kuhy Rudnicki f15f00f3fe Re-point paths for the ~ reorganisation (home-tidy)
Also bumps the 16 meta/requirements pins the freshness gate flagged
(anthropic 1.5.0, numpy 2.5.3, pytest-randomly 5, flake8-bugbear 26.9.9,
ruff 0.16.7, pyright 1.1.414, selenium 4.49.0, hypothesis 6.168.0, lxml
6.1.3, pipdeptree 4.2.5, the two types-* stubs) and Flutter 3.47.3 in
meta/.fvmrc. One test still expected the pre-move ~/mcp-servers path.

The pre-commit hook fed .zsh files to shfmt and shellcheck, neither of
which parses zsh (SC2148/SC1071), so no zsh file could be committed since
the hook was tightened on 2026-08-22; those now get `zsh -n` instead. The
hook's own shfmt pass also staged its reformat of 8 shell files.

CI_GREEN_SKIP because main is red on exactly the dependency-freshness
finding this commit fixes, which is the documented use of that flag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwtowrowDXx6ccmWVPkCaF
2026-09-11 20:50:19 +02:00

231 lines
7.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# disk_cleanup_check.sh — Analyze disk usage and suggest (or perform) cleanup.
#
# Usage:
# ./disk_cleanup_check.sh # Dry-run: report only
# ./disk_cleanup_check.sh --clean # Interactive: prompt before each action
#
# Safe by default: nothing is deleted without --clean AND user confirmation.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# CLEAN and TOTAL_RECLAIMABLE must exist before the helpers are sourced:
# `confirm` reads CLEAN and `report` accumulates into TOTAL_RECLAIMABLE.
CLEAN=false
if [[ "${1:-}" == "--clean" ]]; then
CLEAN=true
fi
TOTAL_RECLAIMABLE=0
# shellcheck source=./lib/disk_cleanup_common.sh
source "$SCRIPT_DIR/lib/disk_cleanup_common.sh"
# ───────────────────── checks ─────────────────────
printf "\n%s=== Disk Cleanup Analysis ===%s\n\n" "${BOLD}" "${RESET}"
printf "${BOLD}%-40s %10s${RESET}\n" "Category" "Reclaimable"
printf '%s\n' "$(printf '%.0s─' {1..60})"
# 1. Trash
trash_dir="$HOME/.local/share/Trash"
size=$(dir_size_kb "$trash_dir")
report "Trash" "$size" "empty trash"
if ((size > 0)); then
try_clean "Empty trash?" \
rm -rf "${trash_dir}/files" "${trash_dir}/info" "${trash_dir}/expunged"
fi
# 2. Pacman cache
pacman_cache_size=$(dir_size_kb "/var/cache/pacman/pkg")
if ((pacman_cache_size > 0)); then
if command -v paccache &>/dev/null; then
pkg_count=$(find /var/cache/pacman/pkg/ -maxdepth 1 -type f -name '*.pkg.tar*' 2>/dev/null | wc -l)
report "Pacman cache ($pkg_count pkgs)" "$pacman_cache_size" \
"sudo paccache -rk2"
try_clean "Clean pacman cache (keep last 2 versions)?" \
sudo paccache -rk2
else
report "Pacman cache (install pacman-contrib)" "$pacman_cache_size" \
"pacman -S pacman-contrib && paccache -rk2"
fi
fi
# 3. Yay build cache
yay_cache="$HOME/.cache/yay"
size=$(dir_size_kb "$yay_cache")
report "Yay AUR build cache" "$size" "rm -rf ~/.cache/yay"
if ((size > 0)); then
try_clean "Clear yay build cache?" rm -rf "${yay_cache:?}"
fi
# 4. Pip cache
pip_cache="$HOME/.cache/pip"
size=$(dir_size_kb "$pip_cache")
report "Pip cache" "$size" "pip cache purge"
if ((size > 0)); then
try_clean "Clear pip cache?" rm -rf "${pip_cache:?}"
fi
# 5. uv cache
uv_cache="$HOME/.cache/uv"
size=$(dir_size_kb "$uv_cache")
report "uv cache" "$size" "uv cache clean"
if ((size > 0)); then
try_clean "Clear uv cache?" rm -rf "${uv_cache:?}"
fi
# 6. HuggingFace cache
hf_cache="$HOME/.cache/huggingface"
size=$(dir_size_kb "$hf_cache")
report "HuggingFace models" "$size" "manual review recommended"
# 7. Suno cache
suno_cache="$HOME/.cache/suno"
size=$(dir_size_kb "$suno_cache")
report "Suno AI cache" "$size" "manual review recommended"
# 8. Go build cache
go_cache="$HOME/.cache/go-build"
size=$(dir_size_kb "$go_cache")
report "Go build cache" "$size" "go clean -cache"
if ((size > 0)); then
try_clean "Clear Go build cache?" rm -rf "${go_cache:?}"
fi
# 9. Yarn cache
yarn_cache="$HOME/.cache/yarn"
size=$(dir_size_kb "$yarn_cache")
report "Yarn cache" "$size" "yarn cache clean"
if ((size > 0)); then
try_clean "Clear yarn cache?" rm -rf "${yarn_cache:?}"
fi
# 10. npm cache
npm_cache="$HOME/.npm/_cacache"
size=$(dir_size_kb "$npm_cache")
report "npm cache" "$size" "npm cache clean --force"
if ((size > 0)); then
try_clean "Clear npm cache?" rm -rf "${npm_cache:?}"
fi
# 11. Electron cache
electron_cache="$HOME/.cache/electron"
size=$(dir_size_kb "$electron_cache")
report "Electron cache" "$size"
if ((size > 0)); then
try_clean "Clear Electron cache?" rm -rf "${electron_cache:?}"
fi
# 12. Thumbnails
thumb_cache="$HOME/.cache/thumbnails"
size=$(dir_size_kb "$thumb_cache")
report "Thumbnails cache" "$size"
if ((size > 0)); then
try_clean "Clear thumbnails?" rm -rf "${thumb_cache:?}"
fi
# 13. vscode-cpptools cache
cpptools_cache="$HOME/.cache/vscode-cpptools"
size=$(dir_size_kb "$cpptools_cache")
if ((size > 102400)); then
report "VS Code cpptools cache" "$size"
try_clean "Clear cpptools cache?" rm -rf "${cpptools_cache:?}"
fi
# 14. Bazel cache
bazel_cache="$HOME/.cache/bazel"
size=$(dir_size_kb "$bazel_cache")
report "Bazel cache" "$size"
if ((size > 0)); then
try_clean "Clear bazel cache?" rm -rf "${bazel_cache:?}"
fi
# 15. Browser caches (report only)
for browser_cache in \
"$HOME/.cache/thorium" \
"$HOME/.cache/google-chrome" \
"$HOME/.cache/mozilla" \
"$HOME/.cache/BraveSoftware"; do
if [[ -d "$browser_cache" ]]; then
name=$(basename "$browser_cache")
size=$(dir_size_kb "$browser_cache")
if ((size > 102400)); then
report "Browser cache: $name" "$size" "close browser first"
fi
fi
done
# 16. Docker
if command -v docker &>/dev/null; then
docker_dir="/var/lib/docker"
size=$(dir_size_kb "$docker_dir" || echo 0)
if ((size > 1048576)); then
report "Docker (images+build cache)" "$size" "docker system prune -a"
try_clean "Docker system prune (removes all unused)?" \
docker system prune -af --volumes
fi
fi
# 17. Orphan packages
orphans=$(pacman -Qdtq 2>/dev/null || true)
orphan_count=0
if [[ -n "$orphans" ]]; then
orphan_count=$(echo "$orphans" | wc -l)
fi
if ((orphan_count > 0)); then
orphan_size=$(echo "$orphans" | xargs pacman -Qi 2>/dev/null |
awk '/Installed Size/{
size=$4; unit=$5;
if (unit ~ /GiB/) total += size*1048576;
else if (unit ~ /MiB/) total += size*1024;
else if (unit ~ /KiB/) total += size;
} END{printf "%d", total}' || echo 0)
report "Orphan packages ($orphan_count)" "$orphan_size" \
"sudo pacman -Rns \$(pacman -Qdtq)"
if confirm "Remove $orphan_count orphan packages?"; then
# shellcheck disable=SC2046
sudo pacman -Rns $(pacman -Qdtq) --noconfirm
printf "%s ✓ Orphans removed%s\n" "${GREEN}" "${RESET}"
fi
fi
# 18. Journal logs — vacuum to 200M
journal_line=$(journalctl --disk-usage 2>&1 || true)
journal_kb=0
if [[ "$journal_line" =~ ([0-9.]+)G ]]; then
journal_kb=$(echo "${BASH_REMATCH[1]} * 1048576 / 1" | bc)
elif [[ "$journal_line" =~ ([0-9.]+)M ]]; then
journal_kb=$(echo "${BASH_REMATCH[1]} * 1024 / 1" | bc)
fi
if ((journal_kb > 204800)); then
excess=$((journal_kb - 204800))
report "Journal logs (excess over 200M)" "$excess" "journalctl --vacuum-size=200M"
try_clean "Vacuum journal to 200M?" \
sudo journalctl --vacuum-size=200M
fi
# 19. AUR source dirs — old archives (>30 days)
aur_dir="$HOME/sdk/aur"
if [[ -d "$aur_dir" ]]; then
old_archives_kb=$(find "$aur_dir" \
\( -name "*.pkg.tar.zst" -o -name "*.tar.gz" -o -name "*.tar.xz" \
-o -name "*.zip" -o -name "*.tar.bz2" \) \
-mtime +30 -printf '%k\n' 2>/dev/null |
awk '{t+=$1} END{print t+0}')
if ((old_archives_kb > 0)); then
report "AUR old archives (>30d)" "$old_archives_kb" \
"find ~/sdk/aur '*.pkg.tar.zst' -mtime +30 -delete"
if confirm "Delete old AUR archives (>30 days)?"; then
find "$aur_dir" \
\( -name "*.pkg.tar.zst" -o -name "*.tar.gz" -o -name "*.tar.xz" \
-o -name "*.zip" -o -name "*.tar.bz2" \) \
-mtime +30 -delete
printf "%s ✓ Old AUR archives deleted%s\n" "${GREEN}" "${RESET}"
fi
fi
fi
print_report_only
print_summary