1
0
mirror of https://github.com/tw93/Mole.git synced 2026-03-22 20:15:07 +00:00

fix(clean): improve loading feedback and spinner output

This commit is contained in:
tw93
2026-02-26 16:36:06 +08:00
parent b3f023b5e6
commit aa1a436862
4 changed files with 69 additions and 5 deletions

View File

@@ -7,7 +7,17 @@ clean_tool_cache() {
local description="$1" local description="$1"
shift shift
if [[ "$DRY_RUN" != "true" ]]; then if [[ "$DRY_RUN" != "true" ]]; then
local command_succeeded=false
if [[ -t 1 ]]; then
start_section_spinner "Cleaning $description..."
fi
if "$@" > /dev/null 2>&1; then if "$@" > /dev/null 2>&1; then
command_succeeded=true
fi
if [[ -t 1 ]]; then
stop_section_spinner
fi
if [[ "$command_succeeded" == "true" ]]; then
echo -e " ${GREEN}${ICON_SUCCESS}${NC} $description" echo -e " ${GREEN}${ICON_SUCCESS}${NC} $description"
fi fi
else else

View File

@@ -5,6 +5,7 @@ set -euo pipefail
clean_deep_system() { clean_deep_system() {
stop_section_spinner stop_section_spinner
local cache_cleaned=0 local cache_cleaned=0
start_section_spinner "Cleaning system caches..."
# Optimized: Single pass for /Library/Caches (3 patterns in 1 scan) # Optimized: Single pass for /Library/Caches (3 patterns in 1 scan)
if sudo test -d "/Library/Caches" 2> /dev/null; then if sudo test -d "/Library/Caches" 2> /dev/null; then
while IFS= read -r -d '' file; do while IFS= read -r -d '' file; do
@@ -20,6 +21,7 @@ clean_deep_system() {
\( -name "*.log" -mtime "+$MOLE_LOG_AGE_DAYS" \) \ \( -name "*.log" -mtime "+$MOLE_LOG_AGE_DAYS" \) \
\) -print0 2> /dev/null || true) \) -print0 2> /dev/null || true)
fi fi
stop_section_spinner
[[ $cache_cleaned -eq 1 ]] && log_success "System caches" [[ $cache_cleaned -eq 1 ]] && log_success "System caches"
start_section_spinner "Cleaning system temporary files..." start_section_spinner "Cleaning system temporary files..."
local tmp_cleaned=0 local tmp_cleaned=0
@@ -147,7 +149,7 @@ clean_deep_system() {
done done
stop_section_spinner stop_section_spinner
[[ $installer_cleaned -gt 0 ]] && debug_log "Cleaned $installer_cleaned macOS installer(s)" [[ $installer_cleaned -gt 0 ]] && debug_log "Cleaned $installer_cleaned macOS installer(s)"
start_section_spinner "Scanning system caches..." start_section_spinner "Scanning browser code signature caches..."
local code_sign_cleaned=0 local code_sign_cleaned=0
while IFS= read -r -d '' cache_dir; do while IFS= read -r -d '' cache_dir; do
if safe_sudo_remove "$cache_dir"; then if safe_sudo_remove "$cache_dir"; then
@@ -158,11 +160,16 @@ clean_deep_system() {
[[ $code_sign_cleaned -gt 0 ]] && log_success "Browser code signature caches, $code_sign_cleaned items" [[ $code_sign_cleaned -gt 0 ]] && log_success "Browser code signature caches, $code_sign_cleaned items"
local diag_base="/private/var/db/diagnostics" local diag_base="/private/var/db/diagnostics"
start_section_spinner "Cleaning system diagnostic logs..."
safe_sudo_find_delete "$diag_base" "*" "$MOLE_LOG_AGE_DAYS" "f" || true safe_sudo_find_delete "$diag_base" "*" "$MOLE_LOG_AGE_DAYS" "f" || true
safe_sudo_find_delete "$diag_base" "*.tracev3" "30" "f" || true safe_sudo_find_delete "$diag_base" "*.tracev3" "30" "f" || true
safe_sudo_find_delete "/private/var/db/DiagnosticPipeline" "*" "$MOLE_LOG_AGE_DAYS" "f" || true safe_sudo_find_delete "/private/var/db/DiagnosticPipeline" "*" "$MOLE_LOG_AGE_DAYS" "f" || true
stop_section_spinner
log_success "System diagnostic logs" log_success "System diagnostic logs"
start_section_spinner "Cleaning power logs..."
safe_sudo_find_delete "/private/var/db/powerlog" "*" "$MOLE_LOG_AGE_DAYS" "f" || true safe_sudo_find_delete "/private/var/db/powerlog" "*" "$MOLE_LOG_AGE_DAYS" "f" || true
stop_section_spinner
log_success "Power logs" log_success "Power logs"
start_section_spinner "Cleaning memory exception reports..." start_section_spinner "Cleaning memory exception reports..."
local mem_reports_dir="/private/var/db/reportmemoryexception/MemoryLimitViolations" local mem_reports_dir="/private/var/db/reportmemoryexception/MemoryLimitViolations"

View File

@@ -76,8 +76,13 @@ _clean_mail_downloads() {
) )
local count=0 local count=0
local cleaned_kb=0 local cleaned_kb=0
local spinner_active=false
for target_path in "${mail_dirs[@]}"; do for target_path in "${mail_dirs[@]}"; do
if [[ -d "$target_path" ]]; then if [[ -d "$target_path" ]]; then
if [[ "$spinner_active" == "false" && -t 1 ]]; then
start_section_spinner "Cleaning old Mail attachments..."
spinner_active=true
fi
local dir_size_kb=0 local dir_size_kb=0
dir_size_kb=$(get_path_size_kb "$target_path") dir_size_kb=$(get_path_size_kb "$target_path")
if ! [[ "$dir_size_kb" =~ ^[0-9]+$ ]]; then if ! [[ "$dir_size_kb" =~ ^[0-9]+$ ]]; then
@@ -102,6 +107,9 @@ _clean_mail_downloads() {
done < <(command find "$target_path" -type f -mtime +"$mail_age_days" -print0 2> /dev/null || true) done < <(command find "$target_path" -type f -mtime +"$mail_age_days" -print0 2> /dev/null || true)
fi fi
done done
if [[ "$spinner_active" == "true" ]]; then
stop_section_spinner
fi
if [[ $count -gt 0 ]]; then if [[ $count -gt 0 ]]; then
local cleaned_mb local cleaned_mb
cleaned_mb=$(echo "$cleaned_kb" | awk '{printf "%.1f", $1/1024}' || echo "0.0") cleaned_mb=$(echo "$cleaned_kb" | awk '{printf "%.1f", $1/1024}' || echo "0.0")
@@ -832,8 +840,12 @@ clean_application_support_logs() {
local current_time local current_time
current_time=$(get_epoch_seconds) current_time=$(get_epoch_seconds)
if [[ "$current_time" =~ ^[0-9]+$ ]] && ((current_time - last_progress_update >= 1)); then if [[ "$current_time" =~ ^[0-9]+$ ]] && ((current_time - last_progress_update >= 1)); then
local app_label="$app_name"
if [[ ${#app_label} -gt 24 ]]; then
app_label="${app_label:0:21}..."
fi
stop_section_spinner stop_section_spinner
start_section_spinner "Scanning Application Support... $app_count/$total_apps ($app_name: $candidate_item_count items)" start_section_spinner "Scanning Application Support... $app_count/$total_apps [$app_label, $candidate_item_count items]"
last_progress_update=$current_time last_progress_update=$current_time
fi fi
fi fi
@@ -883,8 +895,12 @@ clean_application_support_logs() {
local current_time local current_time
current_time=$(get_epoch_seconds) current_time=$(get_epoch_seconds)
if [[ "$current_time" =~ ^[0-9]+$ ]] && ((current_time - last_progress_update >= 1)); then if [[ "$current_time" =~ ^[0-9]+$ ]] && ((current_time - last_progress_update >= 1)); then
local container_label="$container"
if [[ ${#container_label} -gt 24 ]]; then
container_label="${container_label:0:21}..."
fi
stop_section_spinner stop_section_spinner
start_section_spinner "Scanning Application Support... group container ($container: $candidate_item_count items)" start_section_spinner "Scanning Application Support... group [$container_label, $candidate_item_count items]"
last_progress_update=$current_time last_progress_update=$current_time
fi fi
fi fi

View File

@@ -287,9 +287,40 @@ show_menu_option() {
INLINE_SPINNER_PID="" INLINE_SPINNER_PID=""
INLINE_SPINNER_STOP_FILE="" INLINE_SPINNER_STOP_FILE=""
# Keep spinner message on one line and avoid wrapping/noisy output on narrow terminals.
format_spinner_message() {
local message="$1"
message="${message//$'\r'/ }"
message="${message//$'\n'/ }"
local cols=80
if command -v tput > /dev/null 2>&1; then
cols=$(tput cols 2> /dev/null || echo "80")
fi
[[ "$cols" =~ ^[0-9]+$ ]] || cols=80
# Reserve space for prefix + spinner char + spacing.
local available=$((cols - 8))
if [[ $available -lt 20 ]]; then
available=20
fi
if [[ ${#message} -gt $available ]]; then
if [[ $available -gt 3 ]]; then
message="${message:0:$((available - 3))}..."
else
message="${message:0:$available}"
fi
fi
printf "%s" "$message"
}
start_inline_spinner() { start_inline_spinner() {
stop_inline_spinner 2> /dev/null || true stop_inline_spinner 2> /dev/null || true
local message="$1" local message="$1"
local display_message
display_message=$(format_spinner_message "$message")
if [[ -t 1 ]]; then if [[ -t 1 ]]; then
# Create unique stop flag file for this spinner instance # Create unique stop flag file for this spinner instance
@@ -309,7 +340,7 @@ start_inline_spinner() {
while [[ ! -f "$stop_file" ]]; do while [[ ! -f "$stop_file" ]]; do
local c="${chars:$((i % ${#chars})):1}" local c="${chars:$((i % ${#chars})):1}"
# Output to stderr to avoid interfering with stdout # Output to stderr to avoid interfering with stdout
printf "\r${MOLE_SPINNER_PREFIX:-}${BLUE}%s${NC} %s" "$c" "$message" >&2 || break printf "\r${MOLE_SPINNER_PREFIX:-}${BLUE}%s${NC} %s" "$c" "$display_message" >&2 || break
((i++)) ((i++))
sleep 0.05 sleep 0.05
done done
@@ -321,7 +352,7 @@ start_inline_spinner() {
INLINE_SPINNER_PID=$! INLINE_SPINNER_PID=$!
disown "$INLINE_SPINNER_PID" 2> /dev/null || true disown "$INLINE_SPINNER_PID" 2> /dev/null || true
else else
echo -n " ${BLUE}|${NC} $message" >&2 || true echo -n " ${BLUE}|${NC} $display_message" >&2 || true
fi fi
} }