Skip to content

Commit d6e06dd

Browse files
authored
Merge pull request #5 from Thavarshan/fix/issue-04
Fix POSIX Compliance and Add Uninstall Feature
2 parents 360aaa2 + a087756 commit d6e06dd

File tree

2 files changed

+180
-21
lines changed

2 files changed

+180
-21
lines changed

.vscode/settings.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"files.exclude": {
3+
"**/.git": true,
4+
"**/.svn": true,
5+
"**/.hg": true,
6+
"**/.DS_Store": true,
7+
"**/Thumbs.db": true,
8+
"**/*.js": {
9+
"when": "$(basename).ts"
10+
},
11+
"**/*.js.map": true,
12+
".mule": true
13+
}
14+
}

phpvm.sh

Lines changed: 166 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55

66
# Define a debug mode for testing
77
if [ "${BATS_TEST_FILENAME:-}" != "" ]; then
8-
# Script is being tested
9-
# Don't execute main automatically
10-
PHPVM_TEST_MODE=true
11-
echo "TEST MODE ACTIVE" >&2
8+
# Script is being tested
9+
# Don't execute main automatically
10+
PHPVM_TEST_MODE=true
11+
echo "TEST MODE ACTIVE" >&2
1212
else
13-
PHPVM_TEST_MODE=false
13+
PHPVM_TEST_MODE=false
1414
fi
1515

1616
# Fix to prevent shell crash when sourced
@@ -184,13 +184,13 @@ use_php_version() {
184184
# Handle test mode specifically
185185
if [ "${PHPVM_TEST_MODE}" = "true" ]; then
186186
if [ "$version" = "system" ]; then
187-
echo "system" > "$PHPVM_ACTIVE_VERSION_FILE"
187+
echo "system" >"$PHPVM_ACTIVE_VERSION_FILE"
188188
phpvm_echo "Switched to system PHP."
189189
return 0
190190
fi
191191

192192
if [ -d "${TEST_PREFIX:-/tmp}/opt/homebrew/Cellar/php@$version" ]; then
193-
echo "$version" > "$PHPVM_ACTIVE_VERSION_FILE"
193+
echo "$version" >"$PHPVM_ACTIVE_VERSION_FILE"
194194
phpvm_echo "Switched to PHP $version."
195195
return 0
196196
else
@@ -543,7 +543,7 @@ EOF
543543
output_file=$(mktemp)
544544

545545
# Run the command, redirecting both stdout and stderr to the temporary file
546-
"$@" > "$output_file" 2>&1
546+
"$@" >"$output_file" 2>&1
547547

548548
# Check if the output contains the expected text
549549
if grep -q "$expected" "$output_file"; then
@@ -562,7 +562,7 @@ EOF
562562
local dir="$1"
563563
shift
564564

565-
"$@" > /dev/null 2>&1
565+
"$@" >/dev/null 2>&1
566566
if [ -d "$dir" ]; then
567567
return 0
568568
else
@@ -580,9 +580,9 @@ EOF
580580
# Test output functions with timestamps
581581
test_output_functions() {
582582
# Check that output contains timestamp format [YYYY-MM-DD HH:MM:SS]
583-
assert_output_contains "[INFO]" phpvm_echo "Test message" && \
584-
assert_output_contains "[ERROR]" phpvm_err "Test error" && \
585-
assert_output_contains "[WARNING]" phpvm_warn "Test warning"
583+
assert_output_contains "[INFO]" phpvm_echo "Test message" &&
584+
assert_output_contains "[ERROR]" phpvm_err "Test error" &&
585+
assert_output_contains "[WARNING]" phpvm_warn "Test warning"
586586
}
587587

588588
# Test timestamp format in logs
@@ -638,7 +638,7 @@ EOF
638638

639639
# Test install_php
640640
test_install_php() {
641-
install_php "7.4" > /dev/null
641+
install_php "7.4" >/dev/null
642642
local status=$?
643643

644644
# Check for success and file existence
@@ -651,7 +651,7 @@ EOF
651651
mkdir -p "$TEST_DIR/opt/homebrew/Cellar/[email protected]/bin"
652652

653653
# Test switching
654-
use_php_version "7.4" > /dev/null
654+
use_php_version "7.4" >/dev/null
655655
local status=$?
656656

657657
# Check for success and correct active version
@@ -660,7 +660,7 @@ EOF
660660

661661
# Test system_php_version
662662
test_system_php_version() {
663-
system_php_version > /dev/null
663+
system_php_version >/dev/null
664664
local status=$?
665665

666666
# Check for success and correct active version
@@ -674,13 +674,13 @@ EOF
674674

675675
# Create a project with .phpvmrc
676676
mkdir -p "$HOME/project"
677-
echo "7.4" > "$HOME/project/.phpvmrc"
677+
echo "7.4" >"$HOME/project/.phpvmrc"
678678

679679
# Change to the project directory
680680
cd "$HOME/project"
681681

682682
# Test auto-switching
683-
auto_switch_php_version > /dev/null
683+
auto_switch_php_version >/dev/null
684684
local status=$?
685685

686686
# Check for success and correct active version
@@ -760,6 +760,106 @@ EOF
760760
fi
761761
}
762762

763+
# Uninstall a specific PHP version
764+
uninstall_php() {
765+
version="$1"
766+
[ -z "$version" ] && {
767+
phpvm_err "No PHP version specified for uninstallation."
768+
return 1
769+
}
770+
771+
phpvm_echo "Uninstalling PHP $version..."
772+
773+
# If in test mode, just remove the mock directory
774+
if [ "${PHPVM_TEST_MODE}" = "true" ]; then
775+
case "$PKG_MANAGER" in
776+
brew)
777+
mock_dir="${TEST_PREFIX:-/tmp}/opt/homebrew/Cellar/php@$version"
778+
;;
779+
apt)
780+
mock_dir="${TEST_PREFIX:-/tmp}/var/lib/dpkg/info/php$version"
781+
;;
782+
dnf | yum)
783+
mock_dir="${TEST_PREFIX:-/tmp}/var/lib/rpm/php$version"
784+
;;
785+
pacman)
786+
mock_dir="${TEST_PREFIX:-/tmp}/var/lib/pacman/local/php$version"
787+
;;
788+
*)
789+
phpvm_err "Test mode not supported for this package manager."
790+
return 1
791+
;;
792+
esac
793+
rm -rf "$mock_dir"
794+
phpvm_echo "PHP $version uninstalled."
795+
return 0
796+
fi
797+
798+
case "$PKG_MANAGER" in
799+
brew)
800+
if brew list --versions php@"$version" >/dev/null 2>&1; then
801+
brew uninstall php@"$version" || {
802+
phpvm_err "Failed to uninstall PHP $version with Homebrew."
803+
return 1
804+
}
805+
phpvm_echo "PHP $version uninstalled."
806+
else
807+
phpvm_warn "PHP $version is not installed via Homebrew."
808+
return 1
809+
fi
810+
;;
811+
apt)
812+
if dpkg -l | grep -q "^ii\s*php$version\s"; then
813+
run_with_sudo apt-get remove -y php"$version" || {
814+
phpvm_err "Failed to uninstall PHP $version with apt."
815+
return 1
816+
}
817+
phpvm_echo "PHP $version uninstalled."
818+
else
819+
phpvm_warn "PHP $version is not installed via apt."
820+
return 1
821+
fi
822+
;;
823+
dnf | yum)
824+
if $PKG_MANAGER list installed | grep -q "^php$version$"; then
825+
run_with_sudo $PKG_MANAGER remove -y php"$version" || {
826+
phpvm_err "Failed to uninstall PHP $version with $PKG_MANAGER."
827+
return 1
828+
}
829+
phpvm_echo "PHP $version uninstalled."
830+
else
831+
phpvm_warn "PHP $version is not installed via $PKG_MANAGER."
832+
return 1
833+
fi
834+
;;
835+
pacman)
836+
if pacman -Qi php"$version" > /dev/null 2>&1; then
837+
run_with_sudo pacman -R --noconfirm php"$version" || {
838+
phpvm_err "Failed to uninstall PHP $version with pacman."
839+
return 1
840+
}
841+
phpvm_echo "PHP $version uninstalled."
842+
else
843+
phpvm_warn "PHP $version is not installed via pacman."
844+
return 1
845+
fi
846+
;;
847+
*)
848+
phpvm_err "Uninstall not supported for this package manager."
849+
return 1
850+
;;
851+
esac
852+
853+
# Clean up symlink and active version if needed
854+
if [ -f "$PHPVM_ACTIVE_VERSION_FILE" ] && [ "$(cat "$PHPVM_ACTIVE_VERSION_FILE")" = "$version" ]; then
855+
rm -f "$PHPVM_CURRENT_SYMLINK"
856+
rm -f "$PHPVM_ACTIVE_VERSION_FILE"
857+
phpvm_warn "Active PHP version was uninstalled. Please select another version."
858+
fi
859+
860+
return 0
861+
}
862+
763863
# Main function to handle commands
764864
main() {
765865
# Only run if not being sourced
@@ -790,6 +890,13 @@ main() {
790890
fi
791891
install_php "$@"
792892
;;
893+
uninstall)
894+
if [ "$#" -eq 0 ]; then
895+
phpvm_err "Missing PHP version argument for 'uninstall' command."
896+
exit 1
897+
fi
898+
uninstall_php "$@"
899+
;;
793900
system)
794901
system_php_version
795902
;;
@@ -813,8 +920,46 @@ main() {
813920
esac
814921
}
815922

816-
# This allows the script to be sourced without running main
817-
if [ "$PHPVM_TEST_MODE" != "true" ] && [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
818-
# Script is being executed directly and not in test mode
819-
main "$@"
923+
# Robust execution detection with multiple fallbacks
924+
phpvm_should_execute_main() {
925+
# Layer 1: Explicit override (highest priority)
926+
case "${PHPVM_SOURCED:-auto}" in
927+
true | 1 | yes) return 1 ;; # Don't execute
928+
false | 0 | no) return 0 ;; # Execute
929+
esac
930+
931+
# Layer 2: Test mode
932+
[ "$PHPVM_TEST_MODE" = "true" ] && return 1
933+
934+
# Layer 3: Return test (most reliable POSIX method)
935+
if (return 0 2>/dev/null); then
936+
return 1 # Sourced
937+
else
938+
return 0 # Executed
939+
fi
940+
}
941+
942+
# Safe main execution with error handling
943+
if phpvm_should_execute_main "$@"; then
944+
phpvm_debug "Executing main with $# arguments"
945+
946+
# Verify main function exists
947+
if command -v main >/dev/null 2>&1; then
948+
main "$@"
949+
else
950+
phpvm_err "main function not found - script may be corrupted"
951+
exit 1
952+
fi
953+
else
954+
phpvm_debug "Script sourced for function loading"
955+
956+
# Set environment for shell integration
957+
PHPVM_FUNCTIONS_LOADED=true
958+
export PHPVM_FUNCTIONS_LOADED
959+
960+
# Auto-use .phpvmrc if enabled and present
961+
if [ "${PHPVM_AUTO_USE:-true}" = "true" ] && [ -f ".phpvmrc" ]; then
962+
command -v auto_switch_php_version >/dev/null 2>&1 &&
963+
auto_switch_php_version 2>/dev/null || true
964+
fi
820965
fi

0 commit comments

Comments
 (0)