mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 18:30:08 +00:00
fix(check): use softwareupdate output for macOS update detection
Replace LastRecommendedUpdatesAvailable defaults check with unified softwareupdate -l --no-scan parsing. Add caching layer and teach the parser to distinguish macOS updates, Background Security Improvements, Rapid Security Responses, and non-macOS entries so each gets an accurate title in the output. Fix reset_softwareupdate_cache() to also reset the in-memory SOFTWARE_UPDATE_LIST_LOADED flag, and add a regression test. Closes #585
This commit is contained in:
145
lib/check/all.sh
145
lib/check/all.sh
@@ -212,6 +212,7 @@ reset_brew_cache() {
|
|||||||
reset_softwareupdate_cache() {
|
reset_softwareupdate_cache() {
|
||||||
clear_cache_file "$CACHE_DIR/softwareupdate_list"
|
clear_cache_file "$CACHE_DIR/softwareupdate_list"
|
||||||
SOFTWARE_UPDATE_LIST=""
|
SOFTWARE_UPDATE_LIST=""
|
||||||
|
SOFTWARE_UPDATE_LIST_LOADED="false"
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_mole_cache() {
|
reset_mole_cache() {
|
||||||
@@ -233,19 +234,89 @@ is_cache_valid() {
|
|||||||
|
|
||||||
# Cache software update list to avoid calling softwareupdate twice
|
# Cache software update list to avoid calling softwareupdate twice
|
||||||
SOFTWARE_UPDATE_LIST=""
|
SOFTWARE_UPDATE_LIST=""
|
||||||
|
SOFTWARE_UPDATE_LIST_LOADED="false"
|
||||||
|
|
||||||
|
software_update_has_entries() {
|
||||||
|
printf '%s\n' "$1" | grep -qE '^[[:space:]]*\* Label:'
|
||||||
|
}
|
||||||
|
|
||||||
|
is_macos_software_update_text() {
|
||||||
|
local text
|
||||||
|
text=$(printf '%s' "$1" | LC_ALL=C tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
case "$text" in
|
||||||
|
*macos* | *background\ security\ improvement* | *rapid\ security\ response* | *security\ response*)
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get_first_macos_software_update_summary() {
|
||||||
|
printf '%s\n' "$1" | awk '
|
||||||
|
/^\* Label:/ {
|
||||||
|
label=$0
|
||||||
|
sub(/^[[:space:]]*\* Label: */, "", label)
|
||||||
|
next
|
||||||
|
}
|
||||||
|
/^[[:space:]]*Title:/ {
|
||||||
|
title=$0
|
||||||
|
sub(/^[[:space:]]*Title: */, "", title)
|
||||||
|
sub(/, Size:.*/, "", title)
|
||||||
|
combined=tolower(label " " title)
|
||||||
|
if (combined ~ /macos|background security improvement|rapid security response|security response/) {
|
||||||
|
print title
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'
|
||||||
|
}
|
||||||
|
|
||||||
get_software_updates() {
|
get_software_updates() {
|
||||||
local cache_file="$CACHE_DIR/softwareupdate_list"
|
local cache_file="$CACHE_DIR/softwareupdate_list"
|
||||||
|
if [[ "${SOFTWARE_UPDATE_LIST_LOADED:-false}" == "true" ]]; then
|
||||||
# Optimized: Use defaults to check if updates are pending (much faster)
|
printf '%s\n' "$SOFTWARE_UPDATE_LIST"
|
||||||
local pending_updates
|
return 0
|
||||||
pending_updates=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate LastRecommendedUpdatesAvailable 2> /dev/null || echo "0")
|
|
||||||
|
|
||||||
if [[ "$pending_updates" -gt 0 ]]; then
|
|
||||||
echo "Updates Available"
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if is_cache_valid "$cache_file"; then
|
||||||
|
SOFTWARE_UPDATE_LIST=$(cat "$cache_file" 2> /dev/null || true)
|
||||||
|
SOFTWARE_UPDATE_LIST_LOADED="true"
|
||||||
|
printf '%s\n' "$SOFTWARE_UPDATE_LIST"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local spinner_started=false
|
||||||
|
if [[ -t 1 && -z "${SOFTWAREUPDATE_SPINNER_SHOWN:-}" ]]; then
|
||||||
|
MOLE_SPINNER_PREFIX=" " start_inline_spinner "Checking system updates..."
|
||||||
|
spinner_started=true
|
||||||
|
export SOFTWAREUPDATE_SPINNER_SHOWN=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local output=""
|
||||||
|
local sw_status=0
|
||||||
|
if output=$(run_with_timeout 10 softwareupdate -l --no-scan 2> /dev/null); then
|
||||||
|
SOFTWARE_UPDATE_LIST="$output"
|
||||||
|
ensure_user_file "$cache_file"
|
||||||
|
printf '%s' "$SOFTWARE_UPDATE_LIST" > "$cache_file" 2> /dev/null || true
|
||||||
|
else
|
||||||
|
sw_status=$?
|
||||||
|
SOFTWARE_UPDATE_LIST=""
|
||||||
|
if [[ -f "$cache_file" ]]; then
|
||||||
|
SOFTWARE_UPDATE_LIST=$(cat "$cache_file" 2> /dev/null || true)
|
||||||
|
fi
|
||||||
|
if [[ -n "${MO_DEBUG:-}" ]]; then
|
||||||
|
echo "[DEBUG] softwareupdate preload exit status: $sw_status" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$spinner_started" == "true" ]]; then
|
||||||
|
stop_inline_spinner
|
||||||
|
fi
|
||||||
|
|
||||||
|
SOFTWARE_UPDATE_LIST_LOADED="true"
|
||||||
|
printf '%s\n' "$SOFTWARE_UPDATE_LIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
check_homebrew_updates() {
|
check_homebrew_updates() {
|
||||||
@@ -351,52 +422,30 @@ check_macos_update() {
|
|||||||
# Check whitelist
|
# Check whitelist
|
||||||
if command -v is_whitelisted > /dev/null && is_whitelisted "check_macos_updates"; then return; fi
|
if command -v is_whitelisted > /dev/null && is_whitelisted "check_macos_updates"; then return; fi
|
||||||
|
|
||||||
# Fast check using system preferences
|
|
||||||
local updates_available="false"
|
local updates_available="false"
|
||||||
if [[ $(get_software_updates) == "Updates Available" ]]; then
|
local macos_update_summary=""
|
||||||
updates_available="true"
|
local sw_output=""
|
||||||
|
sw_output=$(get_software_updates)
|
||||||
|
|
||||||
# Verify with softwareupdate using --no-scan to avoid triggering a fresh scan
|
if [[ -n "${MO_DEBUG:-}" ]]; then
|
||||||
# which can timeout. We prioritize avoiding false negatives (missing actual updates)
|
echo "[DEBUG] softwareupdate cached output lines: $(printf '%s\n' "$sw_output" | wc -l | tr -d ' ')" >&2
|
||||||
# over false positives, so we only clear the update flag when softwareupdate
|
fi
|
||||||
# explicitly reports "No new software available"
|
|
||||||
local sw_output=""
|
|
||||||
local sw_status=0
|
|
||||||
local spinner_started=false
|
|
||||||
if [[ -t 1 ]]; then
|
|
||||||
MOLE_SPINNER_PREFIX=" " start_inline_spinner "Checking macOS updates..."
|
|
||||||
spinner_started=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
local softwareupdate_timeout=10
|
if software_update_has_entries "$sw_output"; then
|
||||||
if sw_output=$(run_with_timeout "$softwareupdate_timeout" softwareupdate -l --no-scan 2> /dev/null); then
|
macos_update_summary=$(get_first_macos_software_update_summary "$sw_output")
|
||||||
:
|
if [[ -n "$macos_update_summary" ]] || is_macos_software_update_text "$sw_output"; then
|
||||||
else
|
updates_available="true"
|
||||||
sw_status=$?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$spinner_started" == "true" ]]; then
|
|
||||||
stop_inline_spinner
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Debug logging for troubleshooting
|
|
||||||
if [[ -n "${MO_DEBUG:-}" ]]; then
|
|
||||||
echo "[DEBUG] softwareupdate exit status: $sw_status, output lines: $(echo "$sw_output" | wc -l | tr -d ' ')" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Prefer avoiding false negatives: if the system indicates updates are pending,
|
|
||||||
# only clear the flag when softwareupdate returns a list without any update entries.
|
|
||||||
if [[ $sw_status -eq 0 && -n "$sw_output" ]]; then
|
|
||||||
if ! echo "$sw_output" | grep -qE '^[[:space:]]*\*'; then
|
|
||||||
updates_available="false"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export MACOS_UPDATE_AVAILABLE="$updates_available"
|
export MACOS_UPDATE_AVAILABLE="$updates_available"
|
||||||
|
|
||||||
if [[ "$updates_available" == "true" ]]; then
|
if [[ "$updates_available" == "true" ]]; then
|
||||||
printf " ${GRAY}%s${NC} %-12s ${YELLOW}%s${NC}\n" "$ICON_WARNING" "macOS" "Update available"
|
if [[ -n "$macos_update_summary" ]]; then
|
||||||
|
printf " ${GRAY}%s${NC} %-12s ${YELLOW}%s${NC}\n" "$ICON_WARNING" "macOS" "$macos_update_summary"
|
||||||
|
else
|
||||||
|
printf " ${GRAY}%s${NC} %-12s ${YELLOW}%s${NC}\n" "$ICON_WARNING" "macOS" "Update available"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
printf " ${GREEN}✓${NC} %-12s %s\n" "macOS" "System up to date"
|
printf " ${GREEN}✓${NC} %-12s %s\n" "macOS" "System up to date"
|
||||||
fi
|
fi
|
||||||
@@ -495,7 +544,7 @@ get_appstore_update_labels() {
|
|||||||
sub(/^[[:space:]]*\* Label: */, "", label)
|
sub(/^[[:space:]]*\* Label: */, "", label)
|
||||||
sub(/,.*/, "", label)
|
sub(/,.*/, "", label)
|
||||||
lower=tolower(label)
|
lower=tolower(label)
|
||||||
if (index(lower, "macos") == 0) {
|
if (lower !~ /macos|background security improvement|rapid security response|security response/) {
|
||||||
print label
|
print label
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -509,7 +558,7 @@ get_macos_update_labels() {
|
|||||||
sub(/^[[:space:]]*\* Label: */, "", label)
|
sub(/^[[:space:]]*\* Label: */, "", label)
|
||||||
sub(/,.*/, "", label)
|
sub(/,.*/, "", label)
|
||||||
lower=tolower(label)
|
lower=tolower(label)
|
||||||
if (index(lower, "macos") != 0) {
|
if (lower ~ /macos|background security improvement|rapid security response|security response/) {
|
||||||
print label
|
print label
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -498,14 +498,12 @@ EOF
|
|||||||
[[ "$output" == *"COUNTS=0:0:0"* ]]
|
[[ "$output" == *"COUNTS=0:0:0"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "check_macos_update avoids slow softwareupdate scans" {
|
@test "check_macos_update reports background security improvements as macOS updates" {
|
||||||
run bash --noprofile --norc << 'EOF'
|
run bash --noprofile --norc << 'EOF'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
source "$PROJECT_ROOT/lib/check/all.sh"
|
source "$PROJECT_ROOT/lib/check/all.sh"
|
||||||
|
|
||||||
defaults() { echo "1"; }
|
|
||||||
|
|
||||||
run_with_timeout() {
|
run_with_timeout() {
|
||||||
local timeout="${1:-}"
|
local timeout="${1:-}"
|
||||||
shift
|
shift
|
||||||
@@ -518,7 +516,8 @@ run_with_timeout() {
|
|||||||
Software Update Tool
|
Software Update Tool
|
||||||
|
|
||||||
Software Update found the following new or updated software:
|
Software Update found the following new or updated software:
|
||||||
* Label: macOS 99
|
* Label: macOS Background Security Improvement (a)-25D771280a
|
||||||
|
Title: macOS Background Security Improvement (a), Version: 26.3.1 (a), Size: 208896KiB, Recommended: YES, Action: restart,
|
||||||
OUT
|
OUT
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -533,7 +532,7 @@ echo "MACOS_UPDATE_AVAILABLE=$MACOS_UPDATE_AVAILABLE"
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[[ "$output" == *"Update available"* ]]
|
[[ "$output" == *"Background Security Improvement"* ]]
|
||||||
[[ "$output" == *"MACOS_UPDATE_AVAILABLE=true"* ]]
|
[[ "$output" == *"MACOS_UPDATE_AVAILABLE=true"* ]]
|
||||||
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
||||||
}
|
}
|
||||||
@@ -544,8 +543,6 @@ set -euo pipefail
|
|||||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
source "$PROJECT_ROOT/lib/check/all.sh"
|
source "$PROJECT_ROOT/lib/check/all.sh"
|
||||||
|
|
||||||
defaults() { echo "1"; }
|
|
||||||
|
|
||||||
run_with_timeout() {
|
run_with_timeout() {
|
||||||
local timeout="${1:-}"
|
local timeout="${1:-}"
|
||||||
shift
|
shift
|
||||||
@@ -578,14 +575,12 @@ EOF
|
|||||||
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "check_macos_update keeps update flag when softwareupdate times out" {
|
@test "check_macos_update ignores non-macOS softwareupdate entries" {
|
||||||
run bash --noprofile --norc << 'EOF'
|
run bash --noprofile --norc << 'EOF'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
source "$PROJECT_ROOT/lib/check/all.sh"
|
source "$PROJECT_ROOT/lib/check/all.sh"
|
||||||
|
|
||||||
defaults() { echo "1"; }
|
|
||||||
|
|
||||||
run_with_timeout() {
|
run_with_timeout() {
|
||||||
local timeout="${1:-}"
|
local timeout="${1:-}"
|
||||||
shift
|
shift
|
||||||
@@ -594,40 +589,13 @@ run_with_timeout() {
|
|||||||
return 124
|
return 124
|
||||||
fi
|
fi
|
||||||
if [[ "${1:-}" == "softwareupdate" && "${2:-}" == "-l" && "${3:-}" == "--no-scan" ]]; then
|
if [[ "${1:-}" == "softwareupdate" && "${2:-}" == "-l" && "${3:-}" == "--no-scan" ]]; then
|
||||||
return 124
|
cat <<'OUT'
|
||||||
fi
|
Software Update Tool
|
||||||
return 124
|
|
||||||
}
|
|
||||||
|
|
||||||
start_inline_spinner(){ :; }
|
Software Update found the following new or updated software:
|
||||||
stop_inline_spinner(){ :; }
|
* Label: Numbers-14.4
|
||||||
|
Title: Numbers, Version: 14.4, Size: 51200KiB, Recommended: YES, Action: none,
|
||||||
check_macos_update
|
OUT
|
||||||
echo "MACOS_UPDATE_AVAILABLE=$MACOS_UPDATE_AVAILABLE"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
[[ "$output" == *"Update available"* ]]
|
|
||||||
[[ "$output" == *"MACOS_UPDATE_AVAILABLE=true"* ]]
|
|
||||||
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "check_macos_update keeps update flag when softwareupdate returns empty output" {
|
|
||||||
run bash --noprofile --norc << 'EOF'
|
|
||||||
set -euo pipefail
|
|
||||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
|
||||||
source "$PROJECT_ROOT/lib/check/all.sh"
|
|
||||||
|
|
||||||
defaults() { echo "1"; }
|
|
||||||
|
|
||||||
run_with_timeout() {
|
|
||||||
local timeout="${1:-}"
|
|
||||||
shift
|
|
||||||
if [[ "$timeout" != "10" ]]; then
|
|
||||||
echo "BAD_TIMEOUT:$timeout"
|
|
||||||
return 124
|
|
||||||
fi
|
|
||||||
if [[ "${1:-}" == "softwareupdate" && "${2:-}" == "-l" && "${3:-}" == "--no-scan" ]]; then
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
return 124
|
return 124
|
||||||
@@ -641,22 +609,69 @@ echo "MACOS_UPDATE_AVAILABLE=$MACOS_UPDATE_AVAILABLE"
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[[ "$output" == *"Update available"* ]]
|
[[ "$output" == *"System up to date"* ]]
|
||||||
[[ "$output" == *"MACOS_UPDATE_AVAILABLE=true"* ]]
|
[[ "$output" == *"MACOS_UPDATE_AVAILABLE=false"* ]]
|
||||||
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "check_macos_update skips softwareupdate when defaults shows no updates" {
|
@test "get_software_updates caches softwareupdate output in memory" {
|
||||||
run bash --noprofile --norc << 'EOF'
|
run bash --noprofile --norc << 'EOF'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
source "$PROJECT_ROOT/lib/check/all.sh"
|
source "$PROJECT_ROOT/lib/check/all.sh"
|
||||||
|
|
||||||
defaults() { echo "0"; }
|
calls=0
|
||||||
|
|
||||||
|
run_with_timeout() {
|
||||||
|
local timeout="${1:-}"
|
||||||
|
shift
|
||||||
|
if [[ "$timeout" != "10" ]]; then
|
||||||
|
echo "BAD_TIMEOUT:$timeout"
|
||||||
|
return 124
|
||||||
|
fi
|
||||||
|
if [[ "${1:-}" == "softwareupdate" && "${2:-}" == "-l" && "${3:-}" == "--no-scan" ]]; then
|
||||||
|
calls=$((calls + 1))
|
||||||
|
cat <<'OUT'
|
||||||
|
Software Update Tool
|
||||||
|
|
||||||
|
No new software available.
|
||||||
|
OUT
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 124
|
||||||
|
}
|
||||||
|
|
||||||
|
first="$(get_software_updates)"
|
||||||
|
second="$(get_software_updates)"
|
||||||
|
printf 'CALLS=%s\n' "$calls"
|
||||||
|
printf 'FIRST=%s\n' "$first"
|
||||||
|
printf 'SECOND=%s\n' "$second"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" == *"CALLS=1"* ]]
|
||||||
|
[[ "$output" == *"FIRST=Software Update Tool"* ]]
|
||||||
|
[[ "$output" == *"SECOND=Software Update Tool"* ]]
|
||||||
|
[[ "$output" != *"BAD_TIMEOUT:"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "check_macos_update uses cached softwareupdate output when available" {
|
||||||
|
run bash --noprofile --norc << 'EOF'
|
||||||
|
set -euo pipefail
|
||||||
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
|
source "$PROJECT_ROOT/lib/check/all.sh"
|
||||||
|
mkdir -p "$HOME/.cache/mole"
|
||||||
|
cat > "$HOME/.cache/mole/softwareupdate_list" <<'OUT'
|
||||||
|
Software Update Tool
|
||||||
|
|
||||||
|
Software Update found the following new or updated software:
|
||||||
|
* Label: macOS 99
|
||||||
|
Title: macOS 99, Version: 99.1, Size: 1024KiB, Recommended: YES, Action: restart,
|
||||||
|
OUT
|
||||||
|
|
||||||
run_with_timeout() {
|
run_with_timeout() {
|
||||||
echo "SHOULD_NOT_CALL_SOFTWAREUPDATE"
|
echo "SHOULD_NOT_CALL_SOFTWAREUPDATE"
|
||||||
return 0
|
return 124
|
||||||
}
|
}
|
||||||
|
|
||||||
check_macos_update
|
check_macos_update
|
||||||
@@ -664,19 +679,64 @@ echo "MACOS_UPDATE_AVAILABLE=$MACOS_UPDATE_AVAILABLE"
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[[ "$output" == *"System up to date"* ]]
|
[[ "$output" == *"macOS 99, Version: 99.1"* ]]
|
||||||
[[ "$output" == *"MACOS_UPDATE_AVAILABLE=false"* ]]
|
[[ "$output" == *"MACOS_UPDATE_AVAILABLE=true"* ]]
|
||||||
[[ "$output" != *"SHOULD_NOT_CALL_SOFTWAREUPDATE"* ]]
|
[[ "$output" != *"SHOULD_NOT_CALL_SOFTWAREUPDATE"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "reset_softwareupdate_cache clears in-memory softwareupdate state" {
|
||||||
|
run bash --noprofile --norc << 'EOF'
|
||||||
|
set -euo pipefail
|
||||||
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
|
source "$PROJECT_ROOT/lib/check/all.sh"
|
||||||
|
|
||||||
|
calls_file="$HOME/softwareupdate_calls"
|
||||||
|
printf '0\n' > "$calls_file"
|
||||||
|
first_file="$HOME/first_updates.txt"
|
||||||
|
second_file="$HOME/second_updates.txt"
|
||||||
|
rm -f "$HOME/.cache/mole/softwareupdate_list"
|
||||||
|
SOFTWARE_UPDATE_LIST=""
|
||||||
|
SOFTWARE_UPDATE_LIST_LOADED="false"
|
||||||
|
run_with_timeout() {
|
||||||
|
local timeout="${1:-}"
|
||||||
|
shift
|
||||||
|
if [[ "${1:-}" == "softwareupdate" && "${2:-}" == "-l" && "${3:-}" == "--no-scan" ]]; then
|
||||||
|
local calls
|
||||||
|
calls=$(cat "$calls_file")
|
||||||
|
calls=$((calls + 1))
|
||||||
|
printf '%s\n' "$calls" > "$calls_file"
|
||||||
|
cat <<OUT
|
||||||
|
Software Update Tool
|
||||||
|
|
||||||
|
* Label: macOS $calls
|
||||||
|
Title: macOS $calls, Version: $calls.0, Size: 1024KiB, Recommended: YES, Action: restart,
|
||||||
|
OUT
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 124
|
||||||
|
}
|
||||||
|
|
||||||
|
get_software_updates > "$first_file"
|
||||||
|
reset_softwareupdate_cache
|
||||||
|
get_software_updates > "$second_file"
|
||||||
|
printf 'CALLS=%s\n' "$(cat "$calls_file")"
|
||||||
|
printf 'FIRST=%s\n' "$(cat "$first_file")"
|
||||||
|
printf 'SECOND=%s\n' "$(cat "$second_file")"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" == *"CALLS=2"* ]]
|
||||||
|
[[ "$output" == *"FIRST=Software Update Tool"* ]]
|
||||||
|
[[ "$output" == *"SECOND=Software Update Tool"* ]]
|
||||||
|
[[ "$output" == *"macOS 2"* ]]
|
||||||
|
}
|
||||||
|
|
||||||
@test "check_macos_update outputs debug info when MO_DEBUG set" {
|
@test "check_macos_update outputs debug info when MO_DEBUG set" {
|
||||||
run bash --noprofile --norc << 'EOF'
|
run bash --noprofile --norc << 'EOF'
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
source "$PROJECT_ROOT/lib/core/common.sh"
|
source "$PROJECT_ROOT/lib/core/common.sh"
|
||||||
source "$PROJECT_ROOT/lib/check/all.sh"
|
source "$PROJECT_ROOT/lib/check/all.sh"
|
||||||
|
|
||||||
defaults() { echo "1"; }
|
|
||||||
|
|
||||||
export MO_DEBUG=1
|
export MO_DEBUG=1
|
||||||
|
|
||||||
run_with_timeout() {
|
run_with_timeout() {
|
||||||
@@ -696,7 +756,7 @@ check_macos_update 2>&1
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
[[ "$output" == *"[DEBUG] softwareupdate exit status:"* ]]
|
[[ "$output" == *"[DEBUG] softwareupdate cached output lines:"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "run_with_timeout succeeds without GNU timeout" {
|
@test "run_with_timeout succeeds without GNU timeout" {
|
||||||
|
|||||||
Reference in New Issue
Block a user