1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 12:41:46 +00:00
Files
Mole/lib/core/common.sh
tw93 e966838c82 style: standardize punctuation across codebase
- Replace parentheses with commas for supplementary info
- Use commas instead of em-dashes for separators
- Update bullet points from - to * in some contexts
- Improve version extraction regex with fallback logic
2026-01-26 14:36:06 +08:00

186 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
# Mole - Common Functions Library
# Main entry point that loads all core modules
set -euo pipefail
# Prevent multiple sourcing
if [[ -n "${MOLE_COMMON_LOADED:-}" ]]; then
return 0
fi
readonly MOLE_COMMON_LOADED=1
_MOLE_CORE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Load core modules
source "$_MOLE_CORE_DIR/base.sh"
source "$_MOLE_CORE_DIR/log.sh"
source "$_MOLE_CORE_DIR/timeout.sh"
source "$_MOLE_CORE_DIR/file_ops.sh"
source "$_MOLE_CORE_DIR/ui.sh"
source "$_MOLE_CORE_DIR/app_protection.sh"
# Load sudo management if available
if [[ -f "$_MOLE_CORE_DIR/sudo.sh" ]]; then
source "$_MOLE_CORE_DIR/sudo.sh"
fi
# Update via Homebrew
update_via_homebrew() {
local current_version="$1"
local temp_update temp_upgrade
temp_update=$(mktemp_file "brew_update")
temp_upgrade=$(mktemp_file "brew_upgrade")
# Set up trap for interruption (Ctrl+C) with inline cleanup
trap 'stop_inline_spinner 2>/dev/null; safe_remove "$temp_update" true; safe_remove "$temp_upgrade" true; echo ""; exit 130' INT TERM
# Update Homebrew
if [[ -t 1 ]]; then
start_inline_spinner "Updating Homebrew..."
else
echo "Updating Homebrew..."
fi
brew update > "$temp_update" 2>&1 &
local update_pid=$!
wait $update_pid 2> /dev/null || true # Continue even if brew update fails
if [[ -t 1 ]]; then
stop_inline_spinner
fi
# Upgrade Mole
if [[ -t 1 ]]; then
start_inline_spinner "Upgrading Mole..."
else
echo "Upgrading Mole..."
fi
brew upgrade mole > "$temp_upgrade" 2>&1 &
local upgrade_pid=$!
wait $upgrade_pid 2> /dev/null || true # Continue even if brew upgrade fails
local upgrade_output
upgrade_output=$(cat "$temp_upgrade")
if [[ -t 1 ]]; then
stop_inline_spinner
fi
# Clear trap
trap - INT TERM
# Cleanup temp files
safe_remove "$temp_update" true
safe_remove "$temp_upgrade" true
if echo "$upgrade_output" | grep -q "already installed"; then
local installed_version
installed_version=$(brew list --versions mole 2> /dev/null | awk '{print $2}')
[[ -z "$installed_version" ]] && installed_version=$(mo --version 2> /dev/null | awk '/Mole version/ {print $3; exit}')
echo ""
echo -e "${GREEN}${ICON_SUCCESS}${NC} Already on latest version, ${installed_version:-$current_version}"
echo ""
elif echo "$upgrade_output" | grep -q "Error:"; then
log_error "Homebrew upgrade failed"
echo "$upgrade_output" | grep "Error:" >&2
return 1
else
echo "$upgrade_output" | grep -Ev "^(==>|Updating Homebrew|Warning:)" || true
local new_version
new_version=$(brew list --versions mole 2> /dev/null | awk '{print $2}')
[[ -z "$new_version" ]] && new_version=$(mo --version 2> /dev/null | awk '/Mole version/ {print $3; exit}')
echo ""
echo -e "${GREEN}${ICON_SUCCESS}${NC} Updated to latest version, ${new_version:-$current_version}"
echo ""
fi
# Clear update cache (suppress errors if cache doesn't exist or is locked)
rm -f "$HOME/.cache/mole/version_check" "$HOME/.cache/mole/update_message" 2> /dev/null || true
}
# Remove applications from Dock
remove_apps_from_dock() {
if [[ $# -eq 0 ]]; then
return 0
fi
local -a targets=()
for arg in "$@"; do
[[ -n "$arg" ]] && targets+=("$arg")
done
if [[ ${#targets[@]} -eq 0 ]]; then
return 0
fi
# Use pure shell (PlistBuddy) to remove items from Dock
# This avoids dependencies on Python 3 or osascript (AppleScript)
local plist="$HOME/Library/Preferences/com.apple.dock.plist"
[[ -f "$plist" ]] || return 0
# PlistBuddy is at /usr/libexec/PlistBuddy on macOS
[[ -x /usr/libexec/PlistBuddy ]] || return 0
local changed=false
for target in "${targets[@]}"; do
local app_path="$target"
local full_path=""
if [[ "$app_path" =~ [[:cntrl:]] ]]; then
debug_log "Skipping dock removal for path with control chars: $app_path"
continue
fi
if [[ -e "$app_path" ]]; then
if full_path=$(cd "$(dirname "$app_path")" 2> /dev/null && pwd); then
full_path="$full_path/$(basename "$app_path")"
else
continue
fi
else
case "$app_path" in
~/*) full_path="$HOME/${app_path#~/}" ;;
/*) full_path="$app_path" ;;
*) continue ;;
esac
fi
[[ -z "$full_path" ]] && continue
local encoded_path="${full_path// /%20}"
# Find the index of the app in persistent-apps
local i=0
while true; do
local label
label=$(/usr/libexec/PlistBuddy -c "Print :persistent-apps:$i:tile-data:file-label" "$plist" 2> /dev/null || echo "")
[[ -z "$label" ]] && break
local url
url=$(/usr/libexec/PlistBuddy -c "Print :persistent-apps:$i:tile-data:file-data:_CFURLString" "$plist" 2> /dev/null || echo "")
[[ -z "$url" ]] && {
((i++))
continue
}
# Match by URL-encoded path to handle spaces in app names
if [[ -n "$encoded_path" && "$url" == *"$encoded_path"* ]]; then
if /usr/libexec/PlistBuddy -c "Delete :persistent-apps:$i" "$plist" 2> /dev/null; then
changed=true
# After deletion, current index i now points to the next item
continue
fi
fi
((i++))
done
done
if [[ "$changed" == "true" ]]; then
# Restart Dock to apply changes from the plist
killall Dock 2> /dev/null || true
fi
}