mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-14 22:31:00 +01:00
Split disk_cleanup_check.sh: extract the helpers and the output blocks
329 -> 230 + 124. The colour constants, human_readable, dir_size_kb, report, confirm and try_clean move to lib/disk_cleanup_common.sh, along with the report-only loop and the summary block as print_report_only and print_summary. The seam passes state -- report accumulates into TOTAL_RECLAIMABLE and confirm reads CLEAN -- so both are set before the source line, and the verification is a trace diff rather than a static check: identical exit status, identical ordered du calls, identical stdout and stderr against a detached worktree at the pre-split commit. Also ran it for real from /tmp (not its own directory) to confirm SCRIPT_DIR resolves the lib from any cwd: 303.7 GB reported reclaimable, nothing deleted. The one shellcheck finding (SC2034 on RED) was fixed by moving the function that uses it, not suppressed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
This commit is contained in:
parent
eef14d7bce
commit
5b6973e11d
@ -0,0 +1,43 @@
|
||||
{
|
||||
"intent": "Bring meta/scripts/disk_cleanup_check.sh (329 lines) under the 250-line cap by moving its formatting, sizing, confirmation and output helpers into a sourced lib.",
|
||||
"scope": [
|
||||
"meta/scripts/disk_cleanup_check.sh",
|
||||
"meta/scripts/lib/disk_cleanup_common.sh (new)",
|
||||
"Non-goal: no change to which directories are checked, what is reported, or what --clean deletes"
|
||||
],
|
||||
"changes": [
|
||||
"Move the six colour constants and human_readable/dir_size_kb/report/confirm/try_clean into lib/disk_cleanup_common.sh.",
|
||||
"Move the report-only loop and the summary block into print_report_only and print_summary in the same lib; the entry script now ends with two calls.",
|
||||
"Add SCRIPT_DIR resolved from BASH_SOURCE so the source line works from any cwd, and set CLEAN/TOTAL_RECLAIMABLE before sourcing, since confirm reads CLEAN and report accumulates into TOTAL_RECLAIMABLE."
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "meta/scripts/trace_shell_split.sh <script> --stub du --out before.txt (detached worktree at the pre-split commit), then again after the split, then diff",
|
||||
"result": "pass",
|
||||
"evidence": "TRACE IDENTICAL -- exit status, the ordered list of stubbed `du -sk` calls, stdout and stderr all byte-identical. This is the check that matters here: the seam passes state (report mutates TOTAL_RECLAIMABLE, confirm reads CLEAN), so a static check could not have caught a break."
|
||||
},
|
||||
{
|
||||
"command": "bash ~/testsAndMisc/meta/scripts/disk_cleanup_check.sh (run for real from /tmp, not from the script's own directory)",
|
||||
"result": "pass",
|
||||
"evidence": "exit 0, full report against real data: 303.7 GB auto-reclaimable, current usage 1445.6 GB / 3665.4 GB (42%). Running from a different cwd confirms SCRIPT_DIR resolves the lib correctly -- a known failure mode for split scripts. Dry-run default, nothing deleted."
|
||||
},
|
||||
{
|
||||
"command": "bash -n + shellcheck -x on the entry, shellcheck on the lib, shfmt -d on both",
|
||||
"result": "pass",
|
||||
"evidence": "All exit 0 with no output. An initial SC2034 (RED appears unused) was resolved by moving print_report_only -- which uses RED -- into the lib, rather than by adding a suppression."
|
||||
},
|
||||
{
|
||||
"command": "bash ~/utils/scripts/check_file_length.sh on both files",
|
||||
"result": "pass",
|
||||
"evidence": "329 -> 230 (entry) + 124 (lib), both under the 250 cap."
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"The lib depends on CLEAN and TOTAL_RECLAIMABLE being set by the caller before it is sourced. That is documented in its header comment; sourcing it standalone would leave confirm reading an unset CLEAN.",
|
||||
"`bc` was briefly stubbed during the first baseline attempt, which produced 'printf: invalid number' noise -- bc is a calculator, not a mutator. The recorded baseline uses real bc and has empty stderr."
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit; the helpers return inline and lib/disk_cleanup_common.sh disappears.",
|
||||
"Re-run the script from any directory and confirm it prints the analysis table and a non-zero total."
|
||||
]
|
||||
}
|
||||
@ -7,13 +7,10 @@
|
||||
#
|
||||
# Safe by default: nothing is deleted without --clean AND user confirmation.
|
||||
|
||||
RED=$'\033[0;31m'
|
||||
GREEN=$'\033[0;32m'
|
||||
YELLOW=$'\033[1;33m'
|
||||
CYAN=$'\033[0;36m'
|
||||
BOLD=$'\033[1m'
|
||||
RESET=$'\033[0m'
|
||||
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
|
||||
@ -21,65 +18,8 @@ fi
|
||||
|
||||
TOTAL_RECLAIMABLE=0
|
||||
|
||||
# ───────────────────── helpers ─────────────────────
|
||||
|
||||
human_readable() {
|
||||
local kb=$1
|
||||
if ((kb >= 1048576)); then
|
||||
printf "%.1f GB" "$(echo "scale=1; $kb / 1048576" | bc)"
|
||||
elif ((kb >= 1024)); then
|
||||
printf "%.1f MB" "$(echo "scale=1; $kb / 1024" | bc)"
|
||||
else
|
||||
printf "%d KB" "$kb"
|
||||
fi
|
||||
}
|
||||
|
||||
dir_size_kb() {
|
||||
local dir="$1"
|
||||
if [[ -d "$dir" ]]; then
|
||||
du -sk "$dir" 2>/dev/null | awk '{print $1}'
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
report() {
|
||||
local label="$1" size_kb="$2" detail="${3:-}"
|
||||
if ((size_kb > 0)); then
|
||||
local hr
|
||||
hr=$(human_readable "$size_kb")
|
||||
printf "${YELLOW}%-40s${RESET} %10s" "$label" "$hr"
|
||||
if [[ -n "$detail" ]]; then
|
||||
printf " ${CYAN}(%s)${RESET}" "$detail"
|
||||
fi
|
||||
printf "\n"
|
||||
TOTAL_RECLAIMABLE=$((TOTAL_RECLAIMABLE + size_kb))
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if user confirms, 1 otherwise. Always 1 in dry-run.
|
||||
confirm() {
|
||||
local prompt="$1"
|
||||
if $CLEAN; then
|
||||
printf "${BOLD} → %s [y/N]: ${RESET}" "$prompt"
|
||||
read -r ans
|
||||
if [[ "$ans" =~ ^[Yy]$ ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Safe wrapper: confirm + action, never fails under errexit
|
||||
try_clean() {
|
||||
local prompt="$1"
|
||||
shift
|
||||
if confirm "$prompt"; then
|
||||
"$@"
|
||||
printf "%s ✓ Done%s\n" "${GREEN}" "${RESET}"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
# shellcheck source=./lib/disk_cleanup_common.sh
|
||||
source "$SCRIPT_DIR/lib/disk_cleanup_common.sh"
|
||||
|
||||
# ───────────────────── checks ─────────────────────
|
||||
|
||||
@ -286,44 +226,5 @@ if [[ -d "$aur_dir" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# ───────────────────── report-only items ─────────────────────
|
||||
|
||||
printf "\n%s--- Report-only (manual review needed) ---%s\n" "${BOLD}" "${RESET}"
|
||||
for manual_entry in \
|
||||
"$HOME/Downloads/too_big:~/Downloads/too_big" \
|
||||
"$HOME/Downloads:~/Downloads total" \
|
||||
"$HOME/inne:~/inne" \
|
||||
"/Games:/Games — still playing?"; do
|
||||
dir="${manual_entry%%:*}"
|
||||
label="${manual_entry#*:}"
|
||||
size=$(dir_size_kb "$dir")
|
||||
if ((size > 0)); then
|
||||
hr=$(human_readable "$size")
|
||||
printf "${RED}%-40s %10s${RESET} ${CYAN}(review manually)${RESET}\n" \
|
||||
"$label" "$hr"
|
||||
fi
|
||||
done
|
||||
|
||||
# ───────────────────── summary ─────────────────────
|
||||
|
||||
printf "\n%s\n" "$(printf '%.0s─' {1..60})"
|
||||
total_hr=$(human_readable "$TOTAL_RECLAIMABLE")
|
||||
printf "${BOLD}Total auto-reclaimable: ${GREEN}%s${RESET}\n" "$total_hr"
|
||||
|
||||
read -r used_kb total_kb used_pct <<<"$(df -k / | awk 'NR==2{print $3, $2, $5}')"
|
||||
used_pct="${used_pct%\%}"
|
||||
printf "${BOLD}Current usage: %s / %s (%s%%)${RESET}\n" \
|
||||
"$(human_readable "$used_kb")" "$(human_readable "$total_kb")" "$used_pct"
|
||||
|
||||
if ((TOTAL_RECLAIMABLE > 0)); then
|
||||
new_used=$((used_kb - TOTAL_RECLAIMABLE))
|
||||
if ((new_used < 0)); then new_used=0; fi
|
||||
new_pct=$((new_used * 100 / total_kb))
|
||||
printf "${BOLD}After cleanup: %s / %s (%d%%)${RESET}\n" \
|
||||
"$(human_readable "$new_used")" "$(human_readable "$total_kb")" "$new_pct"
|
||||
fi
|
||||
|
||||
if ! $CLEAN; then
|
||||
printf "\n%sRun with --clean to interactively clean each category.%s\n" "${CYAN}" "${RESET}"
|
||||
fi
|
||||
printf "\n"
|
||||
print_report_only
|
||||
print_summary
|
||||
|
||||
124
meta/scripts/lib/disk_cleanup_common.sh
Executable file
124
meta/scripts/lib/disk_cleanup_common.sh
Executable file
@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
# Formatting, sizing and confirmation helpers for disk_cleanup_check.sh.
|
||||
#
|
||||
# Split out to keep the entry script under the 250-line cap. The seam carries
|
||||
# state deliberately: `report` accumulates into TOTAL_RECLAIMABLE and `confirm`
|
||||
# reads CLEAN, both owned by the caller. Sourcing this file does not define
|
||||
# either -- the caller must set them first, which is what keeps the dry-run
|
||||
# default safe.
|
||||
#
|
||||
# shellcheck shell=bash
|
||||
|
||||
RED=$'\033[0;31m'
|
||||
GREEN=$'\033[0;32m'
|
||||
YELLOW=$'\033[1;33m'
|
||||
CYAN=$'\033[0;36m'
|
||||
BOLD=$'\033[1m'
|
||||
RESET=$'\033[0m'
|
||||
|
||||
human_readable() {
|
||||
local kb=$1
|
||||
if ((kb >= 1048576)); then
|
||||
printf "%.1f GB" "$(echo "scale=1; $kb / 1048576" | bc)"
|
||||
elif ((kb >= 1024)); then
|
||||
printf "%.1f MB" "$(echo "scale=1; $kb / 1024" | bc)"
|
||||
else
|
||||
printf "%d KB" "$kb"
|
||||
fi
|
||||
}
|
||||
|
||||
dir_size_kb() {
|
||||
local dir="$1"
|
||||
if [[ -d "$dir" ]]; then
|
||||
du -sk "$dir" 2>/dev/null | awk '{print $1}'
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Prints a row and adds to the caller's TOTAL_RECLAIMABLE. Silent for size 0.
|
||||
report() {
|
||||
local label="$1" size_kb="$2" detail="${3:-}"
|
||||
if ((size_kb > 0)); then
|
||||
local hr
|
||||
hr=$(human_readable "$size_kb")
|
||||
printf "${YELLOW}%-40s${RESET} %10s" "$label" "$hr"
|
||||
if [[ -n "$detail" ]]; then
|
||||
printf " ${CYAN}(%s)${RESET}" "$detail"
|
||||
fi
|
||||
printf "\n"
|
||||
TOTAL_RECLAIMABLE=$((TOTAL_RECLAIMABLE + size_kb))
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns 0 if user confirms, 1 otherwise. Always 1 in dry-run.
|
||||
confirm() {
|
||||
local prompt="$1"
|
||||
if $CLEAN; then
|
||||
printf "${BOLD} → %s [y/N]: ${RESET}" "$prompt"
|
||||
read -r ans
|
||||
if [[ "$ans" =~ ^[Yy]$ ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Safe wrapper: confirm + action, never fails under errexit
|
||||
try_clean() {
|
||||
local prompt="$1"
|
||||
shift
|
||||
if confirm "$prompt"; then
|
||||
"$@"
|
||||
printf "%s ✓ Done%s\n" "${GREEN}" "${RESET}"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Directories that are never auto-cleaned: too personal to guess at, so they
|
||||
# are listed with sizes and left alone.
|
||||
print_report_only() {
|
||||
printf "\n%s--- Report-only (manual review needed) ---%s\n" "${BOLD}" "${RESET}"
|
||||
local manual_entry dir label size hr
|
||||
for manual_entry in \
|
||||
"$HOME/Downloads/too_big:~/Downloads/too_big" \
|
||||
"$HOME/Downloads:~/Downloads total" \
|
||||
"$HOME/inne:~/inne" \
|
||||
"/Games:/Games — still playing?"; do
|
||||
dir="${manual_entry%%:*}"
|
||||
label="${manual_entry#*:}"
|
||||
size=$(dir_size_kb "$dir")
|
||||
if ((size > 0)); then
|
||||
hr=$(human_readable "$size")
|
||||
printf "${RED}%-40s %10s${RESET} ${CYAN}(review manually)${RESET}\n" \
|
||||
"$label" "$hr"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Totals plus a before/after projection against the real filesystem.
|
||||
print_summary() {
|
||||
printf "\n%s\n" "$(printf '%.0s─' {1..60})"
|
||||
local total_hr used_kb total_kb used_pct new_used new_pct
|
||||
total_hr=$(human_readable "$TOTAL_RECLAIMABLE")
|
||||
printf "${BOLD}Total auto-reclaimable: ${GREEN}%s${RESET}\n" "$total_hr"
|
||||
|
||||
read -r used_kb total_kb used_pct <<<"$(df -k / | awk 'NR==2{print $3, $2, $5}')"
|
||||
used_pct="${used_pct%\%}"
|
||||
printf "${BOLD}Current usage: %s / %s (%s%%)${RESET}\n" \
|
||||
"$(human_readable "$used_kb")" "$(human_readable "$total_kb")" "$used_pct"
|
||||
|
||||
if ((TOTAL_RECLAIMABLE > 0)); then
|
||||
new_used=$((used_kb - TOTAL_RECLAIMABLE))
|
||||
if ((new_used < 0)); then new_used=0; fi
|
||||
new_pct=$((new_used * 100 / total_kb))
|
||||
printf "${BOLD}After cleanup: %s / %s (%d%%)${RESET}\n" \
|
||||
"$(human_readable "$new_used")" "$(human_readable "$total_kb")" "$new_pct"
|
||||
fi
|
||||
|
||||
if ! $CLEAN; then
|
||||
printf "\n%sRun with --clean to interactively clean each category.%s\n" \
|
||||
"${CYAN}" "${RESET}"
|
||||
fi
|
||||
printf "\n"
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user