mirror of
https://github.com/tw93/Mole.git
synced 2026-02-08 06:14:20 +00:00
Simplify the debug code
This commit is contained in:
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -26,7 +26,7 @@ Please run the command with `--debug` flag and paste the output here:
|
||||
|
||||
```bash
|
||||
mo <command> --debug
|
||||
# Example: mo clean --debug or mo clean --dry-run --debug
|
||||
# Example: mo clean --debug
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
@@ -65,7 +65,7 @@ mo --version # Show installed version
|
||||
- Use `mo clean --whitelist` to manage protected caches.
|
||||
- Use `mo touchid` to approve sudo with Touch ID instead of typing your password.
|
||||
- Prefer Vim-style navigation? All menus understand `h/j/k/l` in addition to the arrow keys.
|
||||
- Run into issues? Enable debug mode with `--debug` flag for detailed logs: `mo clean --debug` or `mo clean --dry-run --debug`.
|
||||
- Run into issues? Use `--debug` flag to see detailed operation logs: `mo clean --debug`
|
||||
|
||||
## Features in Detail
|
||||
|
||||
@@ -194,7 +194,7 @@ For Raycast, reload by running `Reload Script Directories` or restarting Raycast
|
||||
|
||||
- If Mole freed storage for you, consider starring the repo or sharing it with friends needing a cleaner Mac.
|
||||
- Have ideas or fixes? Open an issue or PR and help shape Mole's future together with the community.
|
||||
- Report bugs with debug logs by running `mo clean --debug` or `mo <command> --debug` and sharing the output in your issue.
|
||||
- Report bugs by running commands with `--debug` flag and sharing the output: `mo clean --debug`
|
||||
- Love cats? Treat Tangyuan and Cola to canned food via <a href="https://miaoyan.app/cats.html?name=Mole" target="_blank">this link</a> and keep the mascots purring.
|
||||
|
||||
## License
|
||||
|
||||
19
bin/clean.sh
19
bin/clean.sh
@@ -177,7 +177,6 @@ start_section() {
|
||||
TRACK_SECTION=1
|
||||
SECTION_ACTIVITY=0
|
||||
CURRENT_SECTION="$1"
|
||||
debug_log "Starting section: $1"
|
||||
echo ""
|
||||
echo -e "${PURPLE_BOLD}${ICON_ARROW} $1${NC}"
|
||||
|
||||
@@ -191,9 +190,6 @@ start_section() {
|
||||
end_section() {
|
||||
if [[ $TRACK_SECTION -eq 1 && $SECTION_ACTIVITY -eq 0 ]]; then
|
||||
echo -e " ${GREEN}${ICON_SUCCESS}${NC} Nothing to clean"
|
||||
debug_log "End section: ${CURRENT_SECTION:-unknown} (no activity)"
|
||||
else
|
||||
debug_log "End section: ${CURRENT_SECTION:-unknown} (had activity: $SECTION_ACTIVITY)"
|
||||
fi
|
||||
TRACK_SECTION=0
|
||||
}
|
||||
@@ -216,8 +212,6 @@ safe_clean() {
|
||||
targets=("${@:1:$#-1}")
|
||||
fi
|
||||
|
||||
debug_log "safe_clean: description='$description', target_count=${#targets[@]}"
|
||||
|
||||
local removed_any=0
|
||||
local total_size_bytes=0
|
||||
local total_count=0
|
||||
@@ -254,6 +248,8 @@ safe_clean() {
|
||||
[[ -e "$path" ]] && existing_paths+=("$path")
|
||||
done
|
||||
|
||||
debug_log "Cleaning: $description (${#existing_paths[@]} items)"
|
||||
|
||||
# Update global whitelist skip counter
|
||||
if [[ $skipped_count -gt 0 ]]; then
|
||||
((whitelist_skipped_count += skipped_count))
|
||||
@@ -452,9 +448,6 @@ start_cleanup() {
|
||||
echo -e "${PURPLE_BOLD}Clean Your Mac${NC}"
|
||||
echo ""
|
||||
|
||||
debug_log "Starting cleanup process"
|
||||
debug_log "DRY_RUN=$DRY_RUN, SYSTEM_CLEAN=$SYSTEM_CLEAN"
|
||||
|
||||
if [[ "$DRY_RUN" != "true" && -t 0 ]]; then
|
||||
echo -e "${YELLOW}☻${NC} First time? Run ${GRAY}mo clean --dry-run${NC} first to preview changes"
|
||||
fi
|
||||
@@ -463,7 +456,6 @@ start_cleanup() {
|
||||
echo -e "${YELLOW}Dry Run Mode${NC} - Preview only, no deletions"
|
||||
echo ""
|
||||
SYSTEM_CLEAN=false
|
||||
debug_log "Dry run mode enabled"
|
||||
|
||||
# Initialize export list file
|
||||
mkdir -p "$(dirname "$EXPORT_LIST_FILE")"
|
||||
@@ -531,13 +523,6 @@ EOF
|
||||
perform_cleanup() {
|
||||
echo -e "${BLUE}${ICON_ADMIN}${NC} $(detect_architecture) | Free space: $(get_free_space)"
|
||||
|
||||
debug_log "Whitelist patterns loaded: ${#WHITELIST_PATTERNS[@]}"
|
||||
if [[ "${MO_DEBUG:-}" == "1" && ${#WHITELIST_PATTERNS[@]} -gt 0 ]]; then
|
||||
for pattern in "${WHITELIST_PATTERNS[@]}"; do
|
||||
debug_log " Whitelist: $pattern"
|
||||
done
|
||||
fi
|
||||
|
||||
# Pre-check TCC permissions upfront (delegated to clean_caches module)
|
||||
check_tcc_permissions
|
||||
|
||||
|
||||
@@ -384,10 +384,6 @@ main() {
|
||||
echo ""
|
||||
log_error "Invalid system health data format"
|
||||
echo -e "${YELLOW}Tip:${NC} Check if jq, awk, sysctl, and df commands are available"
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
debug_log "Generated JSON:"
|
||||
debug_log "$health_json"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -398,24 +394,15 @@ main() {
|
||||
# Show system health
|
||||
show_system_health "$health_json"
|
||||
|
||||
debug_log "System health displayed"
|
||||
|
||||
# Parse and display optimizations
|
||||
local -a safe_items=()
|
||||
local -a confirm_items=()
|
||||
|
||||
debug_log "Parsing optimizations..."
|
||||
|
||||
# Use temp file instead of process substitution to avoid hanging
|
||||
local opts_file
|
||||
opts_file=$(mktemp_file)
|
||||
parse_optimizations "$health_json" > "$opts_file"
|
||||
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
local opt_count=$(wc -l < "$opts_file" | tr -d ' ')
|
||||
debug_log "Found $opt_count optimizations"
|
||||
fi
|
||||
|
||||
while IFS= read -r opt_json; do
|
||||
[[ -z "$opt_json" ]] && continue
|
||||
|
||||
@@ -434,17 +421,11 @@ main() {
|
||||
fi
|
||||
done < "$opts_file"
|
||||
|
||||
debug_log "Parsing complete. Safe: ${#safe_items[@]}, Confirm: ${#confirm_items[@]}"
|
||||
|
||||
# Execute all optimizations
|
||||
local first_heading=true
|
||||
|
||||
debug_log "About to request sudo. Safe items: ${#safe_items[@]}, Confirm items: ${#confirm_items[@]}"
|
||||
|
||||
ensure_sudo_session "System optimization requires admin access" || true
|
||||
|
||||
debug_log "Sudo session established or skipped"
|
||||
|
||||
# Run safe optimizations
|
||||
if [[ ${#safe_items[@]} -gt 0 ]]; then
|
||||
for item in "${safe_items[@]}"; do
|
||||
|
||||
@@ -69,7 +69,6 @@ format_last_used_summary() {
|
||||
|
||||
# Scan applications and collect information
|
||||
scan_applications() {
|
||||
debug_log "scan_applications: Starting application scan"
|
||||
# Simplified cache: only check timestamp (24h TTL)
|
||||
local cache_dir="$HOME/.cache/mole"
|
||||
local cache_file="$cache_dir/app_scan_cache"
|
||||
@@ -83,13 +82,9 @@ scan_applications() {
|
||||
[[ $cache_age -eq $(date +%s) ]] && cache_age=86401 # Handle missing file
|
||||
if [[ $cache_age -lt $cache_ttl ]]; then
|
||||
# Cache hit - return immediately
|
||||
debug_log "scan_applications: Using cached app list (age: ${cache_age}s)"
|
||||
echo "$cache_file"
|
||||
return 0
|
||||
fi
|
||||
debug_log "scan_applications: Cache expired (age: ${cache_age}s > ${cache_ttl}s)"
|
||||
else
|
||||
debug_log "scan_applications: No cache found, performing fresh scan"
|
||||
fi
|
||||
|
||||
# Cache miss - show scanning feedback below
|
||||
|
||||
@@ -179,6 +179,8 @@ safe_remove() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
debug_log "Removing: $path"
|
||||
|
||||
# Perform the deletion (log only on error)
|
||||
if rm -rf "$path" 2> /dev/null; then
|
||||
return 0
|
||||
@@ -210,6 +212,8 @@ safe_sudo_remove() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
debug_log "Removing (sudo): $path"
|
||||
|
||||
# Perform the deletion (log only on error)
|
||||
if sudo rm -rf "$path" 2> /dev/null; then
|
||||
return 0
|
||||
@@ -245,6 +249,8 @@ safe_find_delete() {
|
||||
fi
|
||||
|
||||
# Execute find with safety limits
|
||||
debug_log "Finding in $base_dir: $pattern (age: ${age_days}d, type: $type_filter)"
|
||||
|
||||
command find "$base_dir" \
|
||||
-maxdepth 3 \
|
||||
-name "$pattern" \
|
||||
@@ -281,6 +287,8 @@ safe_sudo_find_delete() {
|
||||
fi
|
||||
|
||||
# Execute find with safety limits
|
||||
debug_log "Finding (sudo) in $base_dir: $pattern (age: ${age_days}d, type: $type_filter)"
|
||||
|
||||
sudo command find "$base_dir" \
|
||||
-maxdepth 3 \
|
||||
-name "$pattern" \
|
||||
@@ -332,7 +340,7 @@ log_error() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >> "$LOG_FILE" 2> /dev/null || true
|
||||
}
|
||||
|
||||
# Debug logging - only shown when MO_DEBUG=1
|
||||
# Debug logging - shown when MO_DEBUG=1
|
||||
debug_log() {
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
echo -e "${GRAY}[DEBUG]${NC} $*" >&2
|
||||
@@ -548,11 +556,7 @@ run_with_timeout() {
|
||||
local duration="${1:-0}"
|
||||
shift || true
|
||||
|
||||
if [[ ! "$duration" =~ ^[0-9]+$ ]]; then
|
||||
duration=0
|
||||
fi
|
||||
|
||||
if [[ "$duration" -le 0 ]]; then
|
||||
if [[ ! "$duration" =~ ^[0-9]+$ ]] || [[ "$duration" -le 0 ]]; then
|
||||
"$@"
|
||||
return $?
|
||||
fi
|
||||
@@ -565,40 +569,18 @@ run_with_timeout() {
|
||||
"$@" &
|
||||
local cmd_pid=$!
|
||||
|
||||
# Create temp marker to track timeout
|
||||
local timeout_marker
|
||||
timeout_marker=$(mktemp 2> /dev/null || echo "/tmp/mole-timeout-$$")
|
||||
|
||||
# Killer: sleep then kill command if still running
|
||||
(
|
||||
sleep "$duration"
|
||||
if kill -0 "$cmd_pid" 2> /dev/null; then
|
||||
echo "1" > "$timeout_marker" 2> /dev/null || true
|
||||
kill -TERM "$cmd_pid" 2> /dev/null || true
|
||||
sleep 0.5
|
||||
kill -KILL "$cmd_pid" 2> /dev/null || true
|
||||
fi
|
||||
) &
|
||||
(sleep "$duration"; kill -TERM "$cmd_pid" 2> /dev/null || true) &
|
||||
local killer_pid=$!
|
||||
|
||||
# Wait for command to finish (disable errexit temporarily to prevent exit on wait failure)
|
||||
local exit_code
|
||||
set +e
|
||||
wait "$cmd_pid" 2> /dev/null
|
||||
exit_code=$?
|
||||
set -e
|
||||
|
||||
# Kill the killer if command finished early
|
||||
kill "$killer_pid" 2> /dev/null || true
|
||||
wait "$killer_pid" 2> /dev/null || true
|
||||
|
||||
# Check if timeout occurred
|
||||
if [[ -f "$timeout_marker" ]] && [[ "$(cat "$timeout_marker" 2> /dev/null)" == "1" ]]; then
|
||||
rm -f "$timeout_marker" 2> /dev/null || true
|
||||
return 124
|
||||
fi
|
||||
|
||||
rm -f "$timeout_marker" 2> /dev/null || true
|
||||
return "$exit_code"
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ MOLE_SUDO_ESTABLISHED="false"
|
||||
# Start sudo keepalive background process
|
||||
# Returns: PID of keepalive process
|
||||
_start_sudo_keepalive() {
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: _start_sudo_keepalive: starting background process..." >&2
|
||||
|
||||
# Start background keepalive process with all outputs redirected
|
||||
# This is critical: command substitution waits for all file descriptors to close
|
||||
(
|
||||
@@ -37,7 +35,6 @@ _start_sudo_keepalive() {
|
||||
) > /dev/null 2>&1 &
|
||||
|
||||
local pid=$!
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: _start_sudo_keepalive: background PID = $pid" >&2
|
||||
echo $pid
|
||||
}
|
||||
|
||||
@@ -61,21 +58,14 @@ has_sudo_session() {
|
||||
request_sudo() {
|
||||
local prompt_msg="${1:-Admin access required}"
|
||||
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: request_sudo: checking existing session..."
|
||||
|
||||
if has_sudo_session; then
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: request_sudo: session already exists"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: request_sudo: calling request_sudo_access from common.sh..."
|
||||
|
||||
# Use the robust implementation from common.sh
|
||||
if request_sudo_access "$prompt_msg"; then
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: request_sudo: request_sudo_access succeeded"
|
||||
return 0
|
||||
else
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: request_sudo: request_sudo_access failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -85,39 +75,26 @@ request_sudo() {
|
||||
ensure_sudo_session() {
|
||||
local prompt="${1:-Admin access required}"
|
||||
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: ensure_sudo_session called"
|
||||
|
||||
# Check if already established
|
||||
if has_sudo_session && [[ "$MOLE_SUDO_ESTABLISHED" == "true" ]]; then
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: Sudo session already active"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: Checking for old keepalive..."
|
||||
|
||||
# Stop old keepalive if exists
|
||||
if [[ -n "$MOLE_SUDO_KEEPALIVE_PID" ]]; then
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: Stopping old keepalive PID $MOLE_SUDO_KEEPALIVE_PID"
|
||||
_stop_sudo_keepalive "$MOLE_SUDO_KEEPALIVE_PID"
|
||||
MOLE_SUDO_KEEPALIVE_PID=""
|
||||
fi
|
||||
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: Calling request_sudo..."
|
||||
|
||||
# Request sudo access
|
||||
if ! request_sudo "$prompt"; then
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: request_sudo failed"
|
||||
MOLE_SUDO_ESTABLISHED="false"
|
||||
return 1
|
||||
fi
|
||||
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: request_sudo succeeded, starting keepalive..."
|
||||
|
||||
# Start keepalive
|
||||
MOLE_SUDO_KEEPALIVE_PID=$(_start_sudo_keepalive)
|
||||
|
||||
[[ "${MO_DEBUG:-}" == "1" ]] && echo "DEBUG: Keepalive started with PID $MOLE_SUDO_KEEPALIVE_PID"
|
||||
|
||||
MOLE_SUDO_ESTABLISHED="true"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ decode_file_list() {
|
||||
# Args: $1 = bundle_id, $2 = has_system_files (true/false)
|
||||
stop_launch_services() {
|
||||
local bundle_id="$1"
|
||||
debug_log "stop_launch_services: Stopping services for $bundle_id"
|
||||
local has_system_files="${2:-false}"
|
||||
|
||||
# User-level Launch Agents
|
||||
|
||||
15
mole
15
mole
@@ -59,14 +59,12 @@ is_homebrew_install() {
|
||||
# Check for updates (non-blocking, always check in background)
|
||||
check_for_updates() {
|
||||
local msg_cache="$HOME/.cache/mole/update_message"
|
||||
local debug_log="$HOME/.cache/mole/update_check_debug"
|
||||
mkdir -p "$(dirname "$msg_cache")" 2> /dev/null
|
||||
|
||||
# Background version check (save to file, don't output)
|
||||
# Always check in background, display result from previous check
|
||||
(
|
||||
local latest
|
||||
local check_method="github"
|
||||
|
||||
# Use GitHub API for version check (works for both Homebrew and manual installs)
|
||||
# Try API first (faster and more reliable)
|
||||
@@ -74,16 +72,12 @@ check_for_updates() {
|
||||
if [[ -z "$latest" ]]; then
|
||||
# Fallback to parsing mole script from raw GitHub
|
||||
latest=$(get_latest_version)
|
||||
check_method="github-raw"
|
||||
fi
|
||||
[[ -n "${MO_UPDATE_DEBUG:-}" ]] && echo "$(date): Checking via $check_method, got: $latest" >> "$debug_log"
|
||||
|
||||
if [[ -n "$latest" && "$VERSION" != "$latest" && "$(printf '%s\n' "$VERSION" "$latest" | sort -V | head -1)" == "$VERSION" ]]; then
|
||||
printf "\nUpdate available: %s → %s, run %smo update%s\n\n" "$VERSION" "$latest" "$GREEN" "$NC" > "$msg_cache"
|
||||
[[ -n "${MO_UPDATE_DEBUG:-}" ]] && echo "$(date): Update available ($check_method): $VERSION → $latest" >> "$debug_log"
|
||||
else
|
||||
echo -n > "$msg_cache"
|
||||
[[ -n "${MO_UPDATE_DEBUG:-}" ]] && echo "$(date): No update needed ($check_method): $VERSION == $latest" >> "$debug_log"
|
||||
fi
|
||||
) &
|
||||
disown 2> /dev/null || true
|
||||
@@ -175,7 +169,7 @@ show_help() {
|
||||
printf " %s%-28s%s %s\n" "$GREEN" "mo --help" "$NC" "Show help"
|
||||
echo
|
||||
printf "%s%s%s\n" "$BLUE" "OPTIONS" "$NC"
|
||||
printf " %s%-28s%s %s\n" "$GREEN" "--debug" "$NC" "Show detailed debug logs"
|
||||
printf " %s%-28s%s %s\n" "$GREEN" "--debug" "$NC" "Show detailed operation logs"
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -675,7 +669,7 @@ interactive_main_menu() {
|
||||
}
|
||||
|
||||
main() {
|
||||
# Parse global flags from any position in arguments
|
||||
# Parse global flags
|
||||
local -a args=()
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
@@ -688,11 +682,6 @@ main() {
|
||||
esac
|
||||
done
|
||||
|
||||
# Show debug indicator if enabled
|
||||
if [[ "${MO_DEBUG:-}" == "1" && -t 2 ]]; then
|
||||
echo -e "${GRAY}[DEBUG MODE ENABLED]${NC}" >&2
|
||||
fi
|
||||
|
||||
case "${args[0]:-""}" in
|
||||
"optimize")
|
||||
exec "$SCRIPT_DIR/bin/optimize.sh" "${args[@]:1}"
|
||||
|
||||
Reference in New Issue
Block a user