diff --git a/bin/clean.sh b/bin/clean.sh index 292f5b5..90e3932 100755 --- a/bin/clean.sh +++ b/bin/clean.sh @@ -1069,6 +1069,7 @@ main() { ;; "--dry-run" | "-n") DRY_RUN=true + export MOLE_DRY_RUN=1 ;; "--whitelist") source "$SCRIPT_DIR/../lib/manage/whitelist.sh" diff --git a/lib/clean/system.sh b/lib/clean/system.sh index 071eb4a..f06dd0c 100644 --- a/lib/clean/system.sh +++ b/lib/clean/system.sh @@ -295,7 +295,7 @@ clean_local_snapshots() { [[ -z "$snapshot_list" ]] && return 0 local snapshot_count - snapshot_count=$(echo "$snapshot_list" | grep -Eo 'com\.apple\.TimeMachine\.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}' | wc -l | awk '{print $1}') + snapshot_count=$(echo "$snapshot_list" | { grep -Eo 'com\.apple\.TimeMachine\.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}' || true; } | wc -l | awk '{print $1}') if [[ "$snapshot_count" =~ ^[0-9]+$ && "$snapshot_count" -gt 0 ]]; then echo -e " ${YELLOW}${ICON_WARNING}${NC} Time Machine local snapshots: ${GREEN}${snapshot_count}${NC}${GRAY}, Review: tmutil listlocalsnapshots /${NC}" note_activity diff --git a/lib/clean/user.sh b/lib/clean/user.sh index 1248c0d..baf98ab 100644 --- a/lib/clean/user.sh +++ b/lib/clean/user.sh @@ -667,7 +667,7 @@ check_large_file_candidates() { local snapshot_list snapshot_count snapshot_list=$(run_with_timeout 3 tmutil listlocalsnapshots / 2> /dev/null || true) if [[ -n "$snapshot_list" ]]; then - snapshot_count=$(echo "$snapshot_list" | grep -Eo 'com\.apple\.TimeMachine\.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}' | wc -l | awk '{print $1}') + snapshot_count=$(echo "$snapshot_list" | { grep -Eo 'com\.apple\.TimeMachine\.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}' || true; } | wc -l | awk '{print $1}') if [[ "$snapshot_count" =~ ^[0-9]+$ && "$snapshot_count" -gt 0 ]]; then echo -e " ${YELLOW}${ICON_WARNING}${NC} Time Machine local snapshots: ${GREEN}${snapshot_count}${NC}${GRAY}, Review: tmutil listlocalsnapshots /${NC}" found_any=true diff --git a/tests/clean_apps.bats b/tests/clean_apps.bats index 7533315..8de3f71 100644 --- a/tests/clean_apps.bats +++ b/tests/clean_apps.bats @@ -115,3 +115,48 @@ EOF [[ "$output" == "ok" ]] } +@test "clean_orphaned_system_services respects dry-run" { + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_DRY_RUN=1 bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/clean/apps.sh" + +start_section_spinner() { :; } +stop_section_spinner() { :; } +note_activity() { :; } +debug_log() { :; } + +tmp_dir="$(mktemp -d)" +tmp_plist="$tmp_dir/com.sogou.test.plist" +touch "$tmp_plist" + +sudo() { + if [[ "$1" == "-n" && "$2" == "true" ]]; then + return 0 + fi + if [[ "$1" == "find" ]]; then + printf '%s\0' "$tmp_plist" + return 0 + fi + if [[ "$1" == "du" ]]; then + echo "4 $tmp_plist" + return 0 + fi + if [[ "$1" == "launchctl" ]]; then + echo "launchctl-called" + return 0 + fi + if [[ "$1" == "rm" ]]; then + echo "rm-called" + return 0 + fi + command "$@" +} + +clean_orphaned_system_services +EOF + + [ "$status" -eq 0 ] + [[ "$output" != *"rm-called"* ]] + [[ "$output" != *"launchctl-called"* ]] +} diff --git a/tests/clean_system_maintenance.bats b/tests/clean_system_maintenance.bats index 7be620b..97f2b5a 100644 --- a/tests/clean_system_maintenance.bats +++ b/tests/clean_system_maintenance.bats @@ -108,105 +108,47 @@ EOF [[ "$output" == *"No incomplete backups found"* ]] } -@test "clean_local_snapshots skips in non-interactive mode" { +@test "clean_local_snapshots reports snapshot count" { run bash --noprofile --norc <<'EOF' set -euo pipefail source "$PROJECT_ROOT/lib/core/common.sh" source "$PROJECT_ROOT/lib/clean/system.sh" -tmutil() { - if [[ "$1" == "listlocalsnapshots" ]]; then - printf '%s\n' \ - "com.apple.TimeMachine.2023-10-25-120000" \ - "com.apple.TimeMachine.2023-10-24-120000" - return 0 - fi - return 0 -} -start_section_spinner(){ :; } -stop_section_spinner(){ :; } -tm_is_running(){ return 1; } - -DRY_RUN="false" -clean_local_snapshots -EOF - - [ "$status" -eq 0 ] - [[ "$output" == *"skipping non-interactive mode"* ]] - [[ "$output" != *"Removed snapshot"* ]] -} - -@test "clean_local_snapshots keeps latest in dry-run" { - run bash --noprofile --norc <<'EOF' -set -euo pipefail -source "$PROJECT_ROOT/lib/core/common.sh" -source "$PROJECT_ROOT/lib/clean/system.sh" - -tmutil() { - if [[ "$1" == "listlocalsnapshots" ]]; then - printf '%s\n' \ - "com.apple.TimeMachine.2023-10-25-120000" \ - "com.apple.TimeMachine.2023-10-25-130000" \ - "com.apple.TimeMachine.2023-10-24-120000" - return 0 - fi - return 0 +run_with_timeout() { + printf '%s\n' \ + "com.apple.TimeMachine.2023-10-25-120000" \ + "com.apple.TimeMachine.2023-10-24-120000" } start_section_spinner(){ :; } stop_section_spinner(){ :; } note_activity(){ :; } tm_is_running(){ return 1; } -DRY_RUN="true" clean_local_snapshots EOF [ "$status" -eq 0 ] - [[ "$output" == *"Local snapshot: com.apple.TimeMachine.2023-10-25-120000"* ]] - [[ "$output" == *"Local snapshot: com.apple.TimeMachine.2023-10-24-120000"* ]] - [[ "$output" != *"Local snapshot: com.apple.TimeMachine.2023-10-25-130000"* ]] + [[ "$output" == *"Time Machine local snapshots:"* ]] + [[ "$output" == *"tmutil listlocalsnapshots /"* ]] } -@test "clean_local_snapshots uses read fallback when read_key missing" { - if ! command -v script > /dev/null 2>&1; then - skip "script not available" - fi - - local tmp_script="$BATS_TEST_TMPDIR/clean_local_snapshots_fallback.sh" - cat > "$tmp_script" <<'EOF' +@test "clean_local_snapshots is quiet when no snapshots" { + run bash --noprofile --norc <<'EOF' set -euo pipefail source "$PROJECT_ROOT/lib/core/common.sh" source "$PROJECT_ROOT/lib/clean/system.sh" -tmutil() { - if [[ "$1" == "listlocalsnapshots" ]]; then - printf '%s\n' \ - "com.apple.TimeMachine.2023-10-25-120000" \ - "com.apple.TimeMachine.2023-10-24-120000" - return 0 - fi - return 0 -} +run_with_timeout() { echo "Snapshots for disk /:"; } start_section_spinner(){ :; } stop_section_spinner(){ :; } note_activity(){ :; } tm_is_running(){ return 1; } -unset -f read_key - -CALL_LOG="$HOME/snapshot_calls.log" -> "$CALL_LOG" -sudo() { echo "sudo:$*" >> "$CALL_LOG"; return 0; } - -DRY_RUN="false" clean_local_snapshots -cat "$CALL_LOG" EOF - run bash --noprofile --norc -c "printf '\n' | script -q /dev/null bash \"$tmp_script\"" - [ "$status" -eq 0 ] - [[ "$output" == *"Skipped"* ]] + [[ "$output" != *"Time Machine local snapshots"* ]] }