1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 11:31:46 +00:00

refactor: standardize epoch time retrieval with get_epoch_seconds and ensure locale-independent string transformations.

This commit is contained in:
Tw93
2026-01-03 18:07:47 +08:00
parent 4efe1411aa
commit 6dfd675417
15 changed files with 79 additions and 41 deletions

View File

@@ -369,7 +369,8 @@ safe_clean() {
fi
local idx=0
local last_progress_update=$(date +%s)
local last_progress_update
last_progress_update=$(get_epoch_seconds)
for path in "${existing_paths[@]}"; do
local size
size=$(get_cleanup_path_size_kb "$path")
@@ -384,14 +385,15 @@ safe_clean() {
((idx++))
if [[ $((idx % 20)) -eq 0 && "$show_spinner" == "true" && -t 1 ]]; then
update_progress_if_needed "$idx" "${#existing_paths[@]}" last_progress_update 1 || true
last_progress_update=$(date +%s)
last_progress_update=$(get_epoch_seconds)
fi
done
else
local -a pids=()
local idx=0
local completed=0
local last_progress_update=$(date +%s)
local last_progress_update
last_progress_update=$(get_epoch_seconds)
local total_paths=${#existing_paths[@]}
if [[ ${#existing_paths[@]} -gt 0 ]]; then

View File

@@ -38,8 +38,8 @@ scan_applications() {
ensure_user_dir "$cache_dir"
if [[ $force_rescan == false && -f "$cache_file" ]]; then
local cache_age=$(($(date +%s) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(date +%s) ]] && cache_age=86401 # Handle mtime read failure
local cache_age=$(($(get_epoch_seconds) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(get_epoch_seconds) ]] && cache_age=86401 # Handle mtime read failure
if [[ $cache_age -lt $cache_ttl ]]; then
if [[ -t 2 ]]; then
echo -e "${GREEN}Loading from cache...${NC}" >&2
@@ -60,7 +60,7 @@ scan_applications() {
temp_file=$(create_temp_file)
local current_epoch
current_epoch=$(date "+%s")
current_epoch=$(get_epoch_seconds)
# Pass 1: collect app paths and bundle IDs (no mdls).
local -a app_data_tuples=()
@@ -377,8 +377,8 @@ main() {
local needs_scanning=true
local cache_file="$HOME/.cache/mole/app_scan_cache"
if [[ $force_rescan == false && -f "$cache_file" ]]; then
local cache_age=$(($(date +%s) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(date +%s) ]] && cache_age=86401
local cache_age=$(($(get_epoch_seconds) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(get_epoch_seconds) ]] && cache_age=86401
[[ $cache_age -lt 86400 ]] && needs_scanning=false
fi

View File

@@ -79,8 +79,8 @@ scan_applications() {
# Check if cache exists and is fresh
if [[ $force_rescan == false && -f "$cache_file" ]]; then
local cache_age=$(($(date +%s) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(date +%s) ]] && cache_age=86401 # Handle missing file
local cache_age=$(($(get_epoch_seconds) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(get_epoch_seconds) ]] && cache_age=86401 # Handle missing file
if [[ $cache_age -lt $cache_ttl ]]; then
# Cache hit - return immediately
# Show brief flash of cache usage if in interactive mode
@@ -107,7 +107,7 @@ scan_applications() {
# Pre-cache current epoch to avoid repeated calls
local current_epoch
current_epoch=$(date "+%s")
current_epoch=$(get_epoch_seconds)
# First pass: quickly collect all valid app paths and bundle IDs (NO mdls calls)
local -a app_data_tuples=()
@@ -454,8 +454,8 @@ main() {
local needs_scanning=true
local cache_file="$HOME/.cache/mole/app_scan_cache"
if [[ $force_rescan == false && -f "$cache_file" ]]; then
local cache_age=$(($(date +%s) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(date +%s) ]] && cache_age=86401 # Handle missing file
local cache_age=$(($(get_epoch_seconds) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(get_epoch_seconds) ]] && cache_age=86401 # Handle missing file
[[ $cache_age -lt 86400 ]] && needs_scanning=false
fi

View File

@@ -200,7 +200,7 @@ is_cache_valid() {
return 1
fi
local cache_age=$(($(date +%s) - $(get_file_mtime "$cache_file")))
local cache_age=$(($(get_epoch_seconds) - $(get_file_mtime "$cache_file")))
[[ $cache_age -lt $ttl ]]
}

View File

@@ -73,7 +73,8 @@ get_uptime_days() {
boot_time=$(echo "$boot_output" | awk -F 'sec = |, usec' '{print $2}' 2> /dev/null || echo "")
if [[ -n "$boot_time" && "$boot_time" =~ ^[0-9]+$ ]]; then
local now=$(date +%s 2> /dev/null || echo "0")
local now
now=$(get_epoch_seconds)
local uptime_sec=$((now - boot_time))
uptime_days=$(LC_ALL=C awk "BEGIN {printf \"%.1f\", $uptime_sec / 86400}" 2> /dev/null || echo "0")
else

View File

@@ -66,7 +66,8 @@ scan_installed_apps() {
local cache_age_seconds=300 # 5 minutes
if [[ -f "$cache_file" ]]; then
local cache_mtime=$(get_file_mtime "$cache_file")
local current_time=$(date +%s)
local current_time
current_time=$(get_epoch_seconds)
local age=$((current_time - cache_mtime))
if [[ $age -lt $cache_age_seconds ]]; then
debug_log "Using cached app list (age: ${age}s)"
@@ -158,7 +159,8 @@ is_bundle_orphaned() {
esac
if [[ -e "$directory_path" ]]; then
local last_modified_epoch=$(get_file_mtime "$directory_path")
local current_epoch=$(date +%s)
local current_epoch
current_epoch=$(get_epoch_seconds)
local days_since_modified=$(((current_epoch - last_modified_epoch) / 86400))
if [[ $days_since_modified -lt ${ORPHAN_AGE_THRESHOLD:-60} ]]; then
return 1

View File

@@ -16,7 +16,7 @@ clean_homebrew() {
local last_cleanup
last_cleanup=$(cat "$brew_cache_file" 2> /dev/null || echo "0")
local current_time
current_time=$(date +%s)
current_time=$(get_epoch_seconds)
local time_diff=$((current_time - last_cleanup))
local days_diff=$((time_diff / 86400))
if [[ $days_diff -lt $cache_valid_days ]]; then
@@ -112,6 +112,6 @@ clean_homebrew() {
# Update cache timestamp when any work succeeded or was intentionally skipped.
if [[ "$skip_cleanup" == "true" ]] || [[ "$brew_success" == "true" ]] || [[ "$autoremove_success" == "true" ]]; then
ensure_user_file "$brew_cache_file"
date +%s > "$brew_cache_file"
get_epoch_seconds > "$brew_cache_file"
fi
}

View File

@@ -214,7 +214,7 @@ is_safe_project_artifact() {
fi
# Must not be a direct child of the search root.
local relative_path="${path#"$search_path"/}"
local depth=$(echo "$relative_path" | tr -cd '/' | wc -c)
local depth=$(echo "$relative_path" | LC_ALL=C tr -cd '/' | wc -c)
if [[ $depth -lt 1 ]]; then
return 1
fi
@@ -398,7 +398,8 @@ is_recently_modified() {
fi
local mod_time
mod_time=$(get_file_mtime "$path")
local current_time=$(date +%s)
local current_time
current_time=$(get_epoch_seconds)
local age_seconds=$((current_time - mod_time))
local age_in_days=$((age_seconds / 86400))
if [[ $age_in_days -lt $age_days ]]; then

View File

@@ -40,7 +40,7 @@ clean_deep_system() {
fi
if [[ -d "/macOS Install Data" ]]; then
local mtime=$(get_file_mtime "/macOS Install Data")
local age_days=$((($(date +%s) - mtime) / 86400))
local age_days=$((($(get_epoch_seconds) - mtime) / 86400))
debug_log "Found macOS Install Data (age: ${age_days} days)"
if [[ $age_days -ge 30 ]]; then
local size_kb=$(get_path_size_kb "/macOS Install Data")
@@ -58,17 +58,23 @@ clean_deep_system() {
start_section_spinner "Scanning system caches..."
local code_sign_cleaned=0
local found_count=0
local last_update_time=$(date +%s)
local last_update_time
last_update_time=$(get_epoch_seconds)
local update_interval=2
while IFS= read -r -d '' cache_dir; do
if safe_remove "$cache_dir" true; then
((code_sign_cleaned++))
fi
((found_count++))
local current_time=$(date +%s)
if [[ $((current_time - last_update_time)) -ge $update_interval ]]; then
start_section_spinner "Scanning system caches... ($found_count found)"
last_update_time=$current_time
# Optimize: only check time every 50 files
if ((found_count % 50 == 0)); then
local current_time
current_time=$(get_epoch_seconds)
if [[ $((current_time - last_update_time)) -ge $update_interval ]]; then
start_section_spinner "Scanning system caches... ($found_count found)"
last_update_time=$current_time
fi
fi
done < <(run_with_timeout 5 command find /private/var/folders -type d -name "*.code_sign_clone" -path "*/X/*" -print0 2> /dev/null || true)
stop_section_spinner
@@ -155,7 +161,8 @@ clean_time_machine_failed_backups() {
[[ -d "$inprogress_file" ]] || continue
# Only delete old incomplete backups (safety window).
local file_mtime=$(get_file_mtime "$inprogress_file")
local current_time=$(date +%s)
local current_time
current_time=$(get_epoch_seconds)
local hours_old=$(((current_time - file_mtime) / 3600))
if [[ $hours_old -lt $MOLE_TM_BACKUP_SAFE_HOURS ]]; then
continue
@@ -200,7 +207,8 @@ clean_time_machine_failed_backups() {
while IFS= read -r inprogress_file; do
[[ -d "$inprogress_file" ]] || continue
local file_mtime=$(get_file_mtime "$inprogress_file")
local current_time=$(date +%s)
local current_time
current_time=$(get_epoch_seconds)
local hours_old=$(((current_time - file_mtime) / 3600))
if [[ $hours_old -lt $MOLE_TM_BACKUP_SAFE_HOURS ]]; then
continue

View File

@@ -485,7 +485,7 @@ process_container_cache() {
if is_critical_system_component "$bundle_id"; then
return 0
fi
if should_protect_data "$bundle_id" || should_protect_data "$(echo "$bundle_id" | tr '[:upper:]' '[:lower:]')"; then
if should_protect_data "$bundle_id" || should_protect_data "$(echo "$bundle_id" | LC_ALL=C tr '[:upper:]' '[:lower:]')"; then
return 0
fi
local cache_dir="$container_dir/Data/Library/Caches"
@@ -583,7 +583,7 @@ clean_application_support_logs() {
for app_dir in ~/Library/Application\ Support/*; do
[[ -d "$app_dir" ]] || continue
local app_name=$(basename "$app_dir")
local app_name_lower=$(echo "$app_name" | tr '[:upper:]' '[:lower:]')
local app_name_lower=$(echo "$app_name" | LC_ALL=C tr '[:upper:]' '[:lower:]')
local is_protected=false
if should_protect_data "$app_name"; then
is_protected=true

View File

@@ -425,7 +425,7 @@ is_critical_system_component() {
[[ -z "$token" ]] && return 1
local lower
lower=$(echo "$token" | tr '[:upper:]' '[:lower:]')
lower=$(echo "$token" | LC_ALL=C tr '[:upper:]' '[:lower:]')
case "$lower" in
*backgroundtaskmanagement* | *loginitems* | *systempreferences* | *systemsettings* | *settings* | *preferences* | *controlcenter* | *biometrickit* | *sfl* | *tcc*)
@@ -489,7 +489,7 @@ should_protect_path() {
[[ -z "$path" ]] && return 1
local path_lower
path_lower=$(echo "$path" | tr '[:upper:]' '[:lower:]')
path_lower=$(echo "$path" | LC_ALL=C tr '[:upper:]' '[:lower:]')
# 1. Keyword-based matching for system components
# Protect System Settings, Preferences, Control Center, and related XPC services

View File

@@ -108,8 +108,30 @@ get_file_mtime() {
return
}
local result
result=$($STAT_BSD -f%m "$file" 2> /dev/null)
echo "${result:-0}"
result=$($STAT_BSD -f%m "$file" 2> /dev/null || echo "")
if [[ "$result" =~ ^[0-9]+$ ]]; then
echo "$result"
else
echo "0"
fi
}
# Determine date command once
if [[ -x /bin/date ]]; then
_DATE_CMD="/bin/date"
else
_DATE_CMD="date"
fi
# Get current time in epoch seconds (defensive against locale/aliases)
get_epoch_seconds() {
local result
result=$($_DATE_CMD +%s 2> /dev/null || echo "")
if [[ "$result" =~ ^[0-9]+$ ]]; then
echo "$result"
else
echo "0"
fi
}
# Get file owner username
@@ -635,11 +657,13 @@ update_progress_if_needed() {
local interval="${4:-2}" # Default: update every 2 seconds
# Get current time
local current_time=$(date +%s)
local current_time
current_time=$(get_epoch_seconds)
# Get last update time from variable
local last_time
eval "last_time=\${$last_update_var:-0}"
[[ "$last_time" =~ ^[0-9]+$ ]] || last_time=0
# Check if enough time has elapsed
if [[ $((current_time - last_time)) -ge $interval ]]; then

View File

@@ -590,9 +590,9 @@ opt_spotlight_index_optimize() {
local slow_count=0
local test_start test_end test_duration
for _ in 1 2; do
test_start=$(date +%s)
test_start=$(get_epoch_seconds)
mdfind "kMDItemFSName == 'Applications'" > /dev/null 2>&1 || true
test_end=$(date +%s)
test_end=$(get_epoch_seconds)
test_duration=$((test_end - test_start))
if [[ $test_duration -gt 3 ]]; then
((slow_count++))

4
mole
View File

@@ -179,7 +179,7 @@ show_version() {
local sip_status
if command -v csrutil > /dev/null; then
sip_status=$(csrutil status 2> /dev/null | grep -o "enabled\|disabled" || echo "Unknown")
sip_status="$(tr '[:lower:]' '[:upper:]' <<< "${sip_status:0:1}")${sip_status:1}"
sip_status="$(LC_ALL=C tr '[:lower:]' '[:upper:]' <<< "${sip_status:0:1}")${sip_status:1}"
else
sip_status="Unknown"
fi
@@ -613,7 +613,7 @@ interactive_main_menu() {
local flag_file
local cache_dir="$HOME/.cache/mole"
ensure_user_dir "$cache_dir"
flag_file="$cache_dir/intro_$(echo "$tty_name" | tr -c '[:alnum:]_' '_')"
flag_file="$cache_dir/intro_$(echo "$tty_name" | LC_ALL=C tr -c '[:alnum:]_' '_')"
if [[ ! -f "$flag_file" ]]; then
animate_mole_intro
ensure_user_file "$flag_file"

View File

@@ -302,7 +302,7 @@ create_alfred_workflow() {
for entry in "${workflows[@]}"; do
IFS="|" read -r bundle name keyword subtitle command <<< "$entry"
local workflow_uid="user.workflow.$(uuid | tr '[:upper:]' '[:lower:]')"
local workflow_uid="user.workflow.$(uuid | LC_ALL=C tr '[:upper:]' '[:lower:]')"
local input_uid
local action_uid
input_uid="$(uuid)"