mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 18:30:08 +00:00
Harden test mode against auth and uninstall side effects
This commit is contained in:
@@ -108,6 +108,11 @@ request_sudo_access() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Tests must never trigger real password or Touch ID prompts.
|
||||
if [[ "${MOLE_TEST_MODE:-0}" == "1" || "${MOLE_TEST_NO_AUTH:-0}" == "1" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Detect if running in TTY environment
|
||||
local tty_path="/dev/tty"
|
||||
local is_gui_mode=false
|
||||
@@ -299,6 +304,11 @@ ensure_sudo_session() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "${MOLE_TEST_MODE:-0}" == "1" || "${MOLE_TEST_NO_AUTH:-0}" == "1" ]]; then
|
||||
MOLE_SUDO_ESTABLISHED="false"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Stop old keepalive if exists
|
||||
if [[ -n "$MOLE_SUDO_KEEPALIVE_PID" ]]; then
|
||||
_stop_sudo_keepalive "$MOLE_SUDO_KEEPALIVE_PID"
|
||||
|
||||
26
mole
26
mole
@@ -494,6 +494,10 @@ update_mole() {
|
||||
# Remove flow (Homebrew + manual + config/cache).
|
||||
remove_mole() {
|
||||
local dry_run_mode="${1:-false}"
|
||||
local test_mode=false
|
||||
if [[ "${MOLE_TEST_MODE:-0}" == "1" ]]; then
|
||||
test_mode=true
|
||||
fi
|
||||
|
||||
if [[ -t 1 ]]; then
|
||||
start_inline_spinner "Detecting Mole installations..."
|
||||
@@ -507,6 +511,7 @@ remove_mole() {
|
||||
local -a manual_installs=()
|
||||
local -a alias_installs=()
|
||||
|
||||
if [[ "$test_mode" != "true" ]]; then
|
||||
if command -v brew > /dev/null 2>&1; then
|
||||
brew_cmd="brew"
|
||||
elif [[ -x "/opt/homebrew/bin/brew" ]]; then
|
||||
@@ -524,20 +529,29 @@ remove_mole() {
|
||||
if [[ "$brew_has_mole" == "true" ]] || is_homebrew_install; then
|
||||
is_homebrew=true
|
||||
fi
|
||||
fi
|
||||
|
||||
local found_mole
|
||||
found_mole=""
|
||||
if [[ "$test_mode" != "true" ]]; then
|
||||
found_mole=$(command -v mole 2> /dev/null || true)
|
||||
if [[ -n "$found_mole" && -f "$found_mole" ]]; then
|
||||
if [[ ! -L "$found_mole" ]] || ! readlink "$found_mole" | grep -q "Cellar/mole"; then
|
||||
manual_installs+=("$found_mole")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
local -a fallback_paths=(
|
||||
local -a fallback_paths=()
|
||||
if [[ "$test_mode" == "true" ]]; then
|
||||
fallback_paths=("$HOME/.local/bin/mole")
|
||||
else
|
||||
fallback_paths=(
|
||||
"/usr/local/bin/mole"
|
||||
"$HOME/.local/bin/mole"
|
||||
"/opt/local/bin/mole"
|
||||
)
|
||||
fi
|
||||
|
||||
for path in "${fallback_paths[@]}"; do
|
||||
if [[ -f "$path" && "$path" != "$found_mole" ]]; then
|
||||
@@ -548,18 +562,26 @@ remove_mole() {
|
||||
done
|
||||
|
||||
local found_mo
|
||||
found_mo=""
|
||||
if [[ "$test_mode" != "true" ]]; then
|
||||
found_mo=$(command -v mo 2> /dev/null || true)
|
||||
if [[ -n "$found_mo" && -f "$found_mo" ]]; then
|
||||
if [[ ! -L "$found_mo" ]] || ! readlink "$found_mo" | grep -q "Cellar/mole"; then
|
||||
alias_installs+=("$found_mo")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
local -a alias_fallback=(
|
||||
local -a alias_fallback=()
|
||||
if [[ "$test_mode" == "true" ]]; then
|
||||
alias_fallback=("$HOME/.local/bin/mo")
|
||||
else
|
||||
alias_fallback=(
|
||||
"/usr/local/bin/mo"
|
||||
"$HOME/.local/bin/mo"
|
||||
"/opt/local/bin/mo"
|
||||
)
|
||||
fi
|
||||
|
||||
for alias in "${alias_fallback[@]}"; do
|
||||
if [[ -f "$alias" && "$alias" != "$found_mo" ]]; then
|
||||
|
||||
@@ -10,6 +10,9 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
# Never allow the scripted test run to trigger real sudo or Touch ID prompts.
|
||||
export MOLE_TEST_NO_AUTH=1
|
||||
|
||||
# shellcheck source=lib/core/file_ops.sh
|
||||
source "$PROJECT_ROOT/lib/core/file_ops.sh"
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ EOF
|
||||
touch "$HOME/.local/bin/mo"
|
||||
mkdir -p "$HOME/.config/mole" "$HOME/.cache/mole"
|
||||
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="/usr/bin:/bin" bash --noprofile --norc <<'EOF'
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="/usr/bin:/bin" MOLE_TEST_MODE=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
start_inline_spinner() { :; }
|
||||
stop_inline_spinner() { :; }
|
||||
@@ -410,7 +410,7 @@ EOF
|
||||
touch "$HOME/.local/bin/mo"
|
||||
mkdir -p "$HOME/.config/mole" "$HOME/.cache/mole"
|
||||
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="/usr/bin:/bin" bash --noprofile --norc <<'EOF'
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="/usr/bin:/bin" MOLE_TEST_MODE=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
start_inline_spinner() { :; }
|
||||
stop_inline_spinner() { :; }
|
||||
@@ -425,3 +425,35 @@ EOF
|
||||
[ -d "$HOME/.config/mole" ]
|
||||
[ -d "$HOME/.cache/mole" ]
|
||||
}
|
||||
|
||||
@test "remove_mole test mode ignores PATH installs outside test HOME" {
|
||||
mkdir -p "$HOME/.local/bin" "$HOME/.config/mole" "$HOME/.cache/mole"
|
||||
touch "$HOME/.local/bin/mole"
|
||||
touch "$HOME/.local/bin/mo"
|
||||
|
||||
fake_global_bin="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-remove-path.XXXXXX")"
|
||||
touch "$fake_global_bin/mole"
|
||||
touch "$fake_global_bin/mo"
|
||||
cat > "$fake_global_bin/brew" <<'EOF'
|
||||
#!/bin/bash
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$fake_global_bin/brew"
|
||||
|
||||
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" PATH="$fake_global_bin:/usr/bin:/bin" MOLE_TEST_MODE=1 bash --noprofile --norc <<'EOF'
|
||||
set -euo pipefail
|
||||
start_inline_spinner() { :; }
|
||||
stop_inline_spinner() { :; }
|
||||
export -f start_inline_spinner stop_inline_spinner
|
||||
printf '\n' | "$PROJECT_ROOT/mole" remove --dry-run
|
||||
EOF
|
||||
|
||||
rm -rf "$fake_global_bin"
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"$HOME/.local/bin/mole"* ]]
|
||||
[[ "$output" == *"$HOME/.local/bin/mo"* ]]
|
||||
[[ "$output" != *"$fake_global_bin/mole"* ]]
|
||||
[[ "$output" != *"$fake_global_bin/mo"* ]]
|
||||
[[ "$output" != *"brew uninstall --force mole"* ]]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user