mirror of
https://github.com/tw93/Mole.git
synced 2026-02-17 13:15:26 +00:00
fix(clean): use sudo-safe cleanup for Xcode documentation cache
This commit is contained in:
@@ -216,9 +216,50 @@ clean_xcode_documentation_cache() {
|
|||||||
((idx++))
|
((idx++))
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ ${#stale_entries[@]} -gt 0 ]]; then
|
if [[ ${#stale_entries[@]} -eq 0 ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${DRY_RUN:-false}" == "true" ]]; then
|
||||||
safe_clean "${stale_entries[@]}" "Xcode documentation cache (old indexes)"
|
safe_clean "${stale_entries[@]}" "Xcode documentation cache (old indexes)"
|
||||||
note_activity
|
note_activity
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! has_sudo_session; then
|
||||||
|
if ! ensure_sudo_session "Cleaning Xcode documentation cache requires admin access"; then
|
||||||
|
echo -e " ${GRAY}${ICON_WARNING}${NC} Xcode documentation cache cleanup skipped (sudo denied)"
|
||||||
|
note_activity
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local removed_count=0
|
||||||
|
local skipped_count=0
|
||||||
|
local stale_entry
|
||||||
|
for stale_entry in "${stale_entries[@]}"; do
|
||||||
|
if should_protect_path "$stale_entry" || is_path_whitelisted "$stale_entry"; then
|
||||||
|
skipped_count=$((skipped_count + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if safe_sudo_remove "$stale_entry"; then
|
||||||
|
removed_count=$((removed_count + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $removed_count -gt 0 ]]; then
|
||||||
|
echo -e " ${GREEN}${ICON_SUCCESS}${NC} Xcode documentation cache · removed ${removed_count} old indexes"
|
||||||
|
if [[ $skipped_count -gt 0 ]]; then
|
||||||
|
echo -e " ${GRAY}${ICON_WARNING}${NC} Xcode documentation cache · skipped ${skipped_count} protected items"
|
||||||
|
fi
|
||||||
|
note_activity
|
||||||
|
elif [[ $skipped_count -gt 0 ]]; then
|
||||||
|
echo -e " ${GREEN}${ICON_SUCCESS}${NC} Xcode documentation cache · nothing to clean"
|
||||||
|
echo -e " ${GRAY}${ICON_WARNING}${NC} Xcode documentation cache · skipped ${skipped_count} protected items"
|
||||||
|
note_activity
|
||||||
|
else
|
||||||
|
echo -e " ${GRAY}${ICON_WARNING}${NC} Xcode documentation cache · no items removed"
|
||||||
|
note_activity
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1182,13 +1182,20 @@ get_diagnostic_report_paths_for_app() {
|
|||||||
[[ -z "$f" ]] && continue
|
[[ -z "$f" ]] && continue
|
||||||
local base
|
local base
|
||||||
base=$(basename "$f" 2> /dev/null)
|
base=$(basename "$f" 2> /dev/null)
|
||||||
[[ "$base" != "$prefix"* ]] && continue
|
case "$base" in
|
||||||
|
"$prefix".* | "$prefix"_* | "$prefix"-*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
case "$base" in
|
case "$base" in
|
||||||
*.ips | *.crash | *.spin) ;;
|
*.ips | *.crash | *.spin) ;;
|
||||||
*) continue ;;
|
*) continue ;;
|
||||||
esac
|
esac
|
||||||
printf '%s\n' "$f"
|
printf '%s\n' "$f"
|
||||||
done < <(find "$dir_abs" -maxdepth 1 -type f -name "${prefix}*" -print0 2> /dev/null || true)
|
done < <(
|
||||||
|
find "$dir_abs" -maxdepth 1 -type f \
|
||||||
|
\( -name "${prefix}.*" -o -name "${prefix}_*" -o -name "${prefix}-*" \) \
|
||||||
|
-print0 2> /dev/null || true
|
||||||
|
)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,10 +149,12 @@ set -euo pipefail
|
|||||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
source "$PROJECT_ROOT/lib/clean/dev.sh"
|
source "$PROJECT_ROOT/lib/clean/dev.sh"
|
||||||
note_activity() { :; }
|
note_activity() { :; }
|
||||||
safe_clean() {
|
has_sudo_session() { return 0; }
|
||||||
local description="${*: -1}"
|
is_path_whitelisted() { return 1; }
|
||||||
|
should_protect_path() { return 1; }
|
||||||
|
safe_sudo_remove() {
|
||||||
local target="$1"
|
local target="$1"
|
||||||
echo "CLEAN:$target:$description"
|
echo "CLEAN:$target:Xcode documentation cache (old indexes)"
|
||||||
}
|
}
|
||||||
clean_xcode_documentation_cache
|
clean_xcode_documentation_cache
|
||||||
EOF
|
EOF
|
||||||
@@ -174,13 +176,13 @@ source "$PROJECT_ROOT/lib/core/common.sh"
|
|||||||
source "$PROJECT_ROOT/lib/clean/dev.sh"
|
source "$PROJECT_ROOT/lib/clean/dev.sh"
|
||||||
note_activity() { :; }
|
note_activity() { :; }
|
||||||
pgrep() { return 0; }
|
pgrep() { return 0; }
|
||||||
safe_clean() { echo "UNEXPECTED_SAFE_CLEAN"; }
|
safe_sudo_remove() { echo "UNEXPECTED_SAFE_SUDO_REMOVE"; }
|
||||||
clean_xcode_documentation_cache
|
clean_xcode_documentation_cache
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[[ "$output" == *"skipping documentation cache cleanup"* ]]
|
[[ "$output" == *"skipping documentation cache cleanup"* ]]
|
||||||
[[ "$output" != *"UNEXPECTED_SAFE_CLEAN"* ]]
|
[[ "$output" != *"UNEXPECTED_SAFE_SUDO_REMOVE"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "check_rust_toolchains reports multiple toolchains" {
|
@test "check_rust_toolchains reports multiple toolchains" {
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ touch "$TMP_DIAG/MyApp_2025-02-10-120000_host.ips"
|
|||||||
touch "$TMP_DIAG/MyApp.crash"
|
touch "$TMP_DIAG/MyApp.crash"
|
||||||
touch "$TMP_DIAG/MyApp_2025-02-10-120001_host.spin"
|
touch "$TMP_DIAG/MyApp_2025-02-10-120001_host.spin"
|
||||||
touch "$TMP_DIAG/OtherApp_2025-02-10.ips"
|
touch "$TMP_DIAG/OtherApp_2025-02-10.ips"
|
||||||
|
touch "$TMP_DIAG/MyAppPro_2025-02-10-120002_host.ips"
|
||||||
|
touch "$TMP_DIAG/MyAppPro.crash"
|
||||||
touch "$TMP_DIAG/MyApp_log.txt"
|
touch "$TMP_DIAG/MyApp_log.txt"
|
||||||
|
|
||||||
out=$(get_diagnostic_report_paths_for_app "$TMP_APP" "My App" "$TMP_DIAG" 2> /dev/null || true)
|
out=$(get_diagnostic_report_paths_for_app "$TMP_APP" "My App" "$TMP_DIAG" 2> /dev/null || true)
|
||||||
@@ -92,6 +94,13 @@ else
|
|||||||
echo " OK does not return OtherApp"
|
echo " OK does not return OtherApp"
|
||||||
((PASSED++))
|
((PASSED++))
|
||||||
fi
|
fi
|
||||||
|
if [[ "$out" == *"MyAppPro"* ]]; then
|
||||||
|
echo " FAIL should not return MyAppPro (prefix collision)"
|
||||||
|
((FAILED++))
|
||||||
|
else
|
||||||
|
echo " OK does not return MyAppPro"
|
||||||
|
((PASSED++))
|
||||||
|
fi
|
||||||
if [[ "$out" == *"MyApp_log.txt"* ]]; then
|
if [[ "$out" == *"MyApp_log.txt"* ]]; then
|
||||||
echo " FAIL should not return non-diagnostic extension"
|
echo " FAIL should not return non-diagnostic extension"
|
||||||
((FAILED++))
|
((FAILED++))
|
||||||
|
|||||||
@@ -60,6 +60,41 @@ EOF
|
|||||||
[[ "$result" == *"LaunchAgents/com.example.TestApp.plist"* ]]
|
[[ "$result" == *"LaunchAgents/com.example.TestApp.plist"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "get_diagnostic_report_paths_for_app avoids executable prefix collisions" {
|
||||||
|
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc << 'EOF'
|
||||||
|
set -euo pipefail
|
||||||
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
|
|
||||||
|
diag_dir="$HOME/Library/Logs/DiagnosticReports"
|
||||||
|
app_dir="$HOME/Applications/Foo.app"
|
||||||
|
mkdir -p "$diag_dir" "$app_dir/Contents"
|
||||||
|
|
||||||
|
cat > "$app_dir/Contents/Info.plist" << 'PLIST'
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>Foo</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
PLIST
|
||||||
|
|
||||||
|
touch "$diag_dir/Foo.crash"
|
||||||
|
touch "$diag_dir/Foo_2026-01-01-120000_host.ips"
|
||||||
|
touch "$diag_dir/Foobar.crash"
|
||||||
|
touch "$diag_dir/Foobar_2026-01-01-120001_host.ips"
|
||||||
|
|
||||||
|
result=$(get_diagnostic_report_paths_for_app "$app_dir" "Foo" "$diag_dir")
|
||||||
|
[[ "$result" == *"Foo.crash"* ]] || exit 1
|
||||||
|
[[ "$result" == *"Foo_2026-01-01-120000_host.ips"* ]] || exit 1
|
||||||
|
[[ "$result" != *"Foobar.crash"* ]] || exit 1
|
||||||
|
[[ "$result" != *"Foobar_2026-01-01-120001_host.ips"* ]] || exit 1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
@test "calculate_total_size returns aggregate kilobytes" {
|
@test "calculate_total_size returns aggregate kilobytes" {
|
||||||
mkdir -p "$HOME/sized"
|
mkdir -p "$HOME/sized"
|
||||||
dd if=/dev/zero of="$HOME/sized/file1" bs=1024 count=1 > /dev/null 2>&1
|
dd if=/dev/zero of="$HOME/sized/file1" bs=1024 count=1 > /dev/null 2>&1
|
||||||
|
|||||||
Reference in New Issue
Block a user