mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 09:46:44 +00:00
- 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
186 lines
5.7 KiB
Bash
Executable File
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
|
|
}
|