diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9a8008f..e21a792 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -26,7 +26,7 @@ Please run the command with `--debug` flag and paste the output here: ```bash mo --debug -# Example: mo clean --debug or mo clean --dry-run --debug +# Example: mo clean --debug ```
diff --git a/README.md b/README.md index f3476e5..37adea8 100644 --- a/README.md +++ b/README.md @@ -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 --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 this link and keep the mascots purring. ## License diff --git a/bin/clean.sh b/bin/clean.sh index b6a8f4d..1840b79 100755 --- a/bin/clean.sh +++ b/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 diff --git a/bin/optimize.sh b/bin/optimize.sh index 0b813d4..b91292b 100755 --- a/bin/optimize.sh +++ b/bin/optimize.sh @@ -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 diff --git a/bin/uninstall.sh b/bin/uninstall.sh index 7620c13..fc599bf 100755 --- a/bin/uninstall.sh +++ b/bin/uninstall.sh @@ -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 diff --git a/lib/core/common.sh b/lib/core/common.sh index 4d99f7e..20a8c22 100755 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -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" } diff --git a/lib/core/sudo.sh b/lib/core/sudo.sh index d1fcbff..f2ab52c 100644 --- a/lib/core/sudo.sh +++ b/lib/core/sudo.sh @@ -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 } diff --git a/lib/uninstall/batch.sh b/lib/uninstall/batch.sh index be59459..368d530 100755 --- a/lib/uninstall/batch.sh +++ b/lib/uninstall/batch.sh @@ -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 diff --git a/mole b/mole index 60aa5f2..44c2608 100755 --- a/mole +++ b/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}"