Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Release Notes

## [v1.5.0](https://github.com/Thavarshan/phpvm/compare/v1.4.1...v1.5.0) - 2025-08-15

### Added

- **Added comprehensive version command support:** Implemented `phpvm version`, `phpvm --version`, and `phpvm -v` commands with detailed information including author, repository link, and usage hints.
- **Added intelligent system PHP detection:** Enhanced system PHP switching to properly detect and use Homebrew's main `php` formula as the system default on modern macOS.
- **Added post-install validation:** Added checks for PHP binary availability after installation with helpful warnings if binaries are missing.

### Changed

- **Improved shebang for WSL compatibility:** Changed from `#!/bin/sh` to `#!/bin/bash` for better compatibility with WSL and Linux distributions.
- **Enhanced Homebrew link failure detection:** Improved detection and handling of "already linked" warnings from Homebrew with proper error reporting and user guidance.
- **Updated system PHP messaging:** Changed misleading "macOS built-in PHP" references to accurate "Homebrew default PHP" messaging that reflects modern macOS reality.
- **Improved PHP version detection on Linux:** Enhanced `dpkg-query` usage for more reliable PHP version listing on Debian/Ubuntu systems.
- **Enhanced unlinking logic:** Replaced problematic wildcard unlinking with proper iteration through installed PHP formulas.

### Fixed

- **Fixed false success reporting on Homebrew link failures:** Script now properly detects when `brew link` fails due to "already linked" status and returns error instead of false success.
- **Fixed WSL script execution issues:** Resolved problem where phpvm would exit silently without output on WSL/Ubuntu systems due to shell compatibility issues.
- **Fixed system PHP switching on macOS:** System switching now correctly links to Homebrew's main PHP installation instead of looking for non-existent `/usr/bin/php`.
- **Fixed PHP version listing on Linux:** Improved reliability of `phpvm list` command showing installed PHP versions on apt-based systems.
- **Fixed error handling for missing PHP binaries:** Added proper error handling when PHP commands are not available, preventing script crashes.

## [v1.4.1](https://github.com/Thavarshan/phpvm/compare/v1.4.0...v1.4.1) - 2025-07-13

### Fixed
Expand Down
76 changes: 65 additions & 11 deletions phpvm.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#!/bin/sh
#!/bin/bash

# phpvm - A PHP Version Manager for macOS and Linux
# Author: Jerome Thayananthajothy (tjthavarshan@gmail.com)
# Version: 1.5.0

PHPVM_VERSION="1.5.0"

# Define a debug mode for testing
if [ "${BATS_TEST_FILENAME:-}" != "" ]; then
Expand Down Expand Up @@ -134,6 +137,10 @@ install_php() {
phpvm_err "Failed to install PHP $version. Package php$version may not exist."
return 1
fi
# Post-install check for binary
if ! [ -x "/usr/bin/php$version" ]; then
phpvm_warn "php$version installed, but /usr/bin/php$version not found. You may need to install php$version-cli or check your PATH."
fi
;;
dnf | yum)
run_with_sudo $PKG_MANAGER install -y php"$version" || {
Expand Down Expand Up @@ -166,8 +173,10 @@ get_installed_php_version() {

if command -v php-config >/dev/null 2>&1; then
php-config --version
else
elif command -v php >/dev/null 2>&1; then
php -v | awk '/^PHP/ {print $2}'
else
echo "N/A"
fi
}

Expand Down Expand Up @@ -203,21 +212,49 @@ use_php_version() {
brew)
phpvm_debug "Unlinking any existing PHP version..."
brew unlink php >/dev/null 2>&1 || true
brew unlink php@*.* >/dev/null 2>&1 || true
# Unlink all versioned PHP installations
for php_formula in $(brew list --formula | grep -E '^php@[0-9]+\.[0-9]+$'); do
brew unlink "$php_formula" >/dev/null 2>&1 || true
done

if [ "$version" = "system" ]; then
# Special case for switching to system PHP
echo "system" >"$PHPVM_ACTIVE_VERSION_FILE"
phpvm_echo "Switched to system PHP."
return 0
# Remove the current symlink since we're using system PHP
rm -f "$PHPVM_CURRENT_SYMLINK"

# On macOS, "system" PHP typically means the main Homebrew php formula
# since Apple removed PHP from macOS starting with macOS Monterey 12.0
if [ -d "$HOMEBREW_PREFIX/Cellar/php" ]; then
phpvm_debug "Linking Homebrew php formula as system default..."
brew link php --force --overwrite >/dev/null 2>&1 || {
phpvm_err "Failed to link Homebrew php formula."
return 1
}
phpvm_echo "Switched to system PHP (Homebrew default)."
return 0
# Fallback: check for any system PHP in standard locations (rare on modern macOS)
elif command -v php >/dev/null 2>&1; then
phpvm_echo "Switched to system PHP."
return 0
else
phpvm_echo "Switched to system PHP."
phpvm_warn "No system PHP found. You may need to install PHP with 'brew install php' or switch to a specific version."
return 0
fi
fi

if [ -d "$HOMEBREW_PREFIX/Cellar/php@$version" ]; then
phpvm_debug "Linking PHP $version..."
brew link php@"$version" --force --overwrite || {
phpvm_err "Failed to link PHP $version."
link_output=$(brew link php@"$version" --force --overwrite 2>&1)
if echo "$link_output" | grep -iq "Already linked"; then
phpvm_warn "Homebrew reports PHP $version is already linked. To relink, run: brew unlink php@${version} && brew link --force php@${version}"
phpvm_warn "Switch NOT completed. Please relink manually."
return 1
}
elif echo "$link_output" | grep -q "Error"; then
phpvm_err "Failed to link PHP $version: $link_output"
Copy link
Preview

Copilot AI Aug 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The link_output variable captures both stdout and stderr, but the subsequent grep commands may not handle multiline output correctly. Consider using more robust pattern matching or adding explicit line-by-line processing.

Copilot uses AI. Check for mistakes.

return 1
fi
elif [ -d "$HOMEBREW_PREFIX/Cellar/php" ]; then
installed_version=$(get_installed_php_version)
if [ "$installed_version" = "$version" ]; then
Expand Down Expand Up @@ -340,7 +377,7 @@ list_installed_versions() {
fi
fi
done
echo " system (macOS built-in PHP)"
echo " system (Homebrew default PHP)"
echo ""
if [ -f "$PHPVM_ACTIVE_VERSION_FILE" ]; then
active_version=$(cat "$PHPVM_ACTIVE_VERSION_FILE")
Expand Down Expand Up @@ -368,10 +405,10 @@ list_installed_versions() {
fi
done
fi
echo " system (macOS built-in PHP)"
echo " system (Homebrew default PHP)"
;;
apt)
dpkg -l | grep -E '^ii +php[0-9]+\.[0-9]+' | awk '{print " " $2}' | sed 's/^ php//'
dpkg-query -W -f='${Package}\n' | grep -E '^php[0-9]+\.[0-9]+' | sed 's/^php//' | awk '{print " "$1}'
echo " system (default system PHP)"
;;
dnf | yum)
Expand Down Expand Up @@ -406,6 +443,7 @@ Usage:
phpvm list List installed PHP versions
phpvm help Show this help message
phpvm test Run self-tests to verify functionality
phpvm version Show version information

Examples:
phpvm install 8.1 Install PHP 8.1
Expand All @@ -415,6 +453,19 @@ Examples:
EOF
}

# Print version information
print_version() {
cat <<EOF
phpvm version $PHPVM_VERSION

PHP Version Manager for macOS and Linux
Author: Jerome Thayananthajothy <tjthavarshan@gmail.com>
Repository: https://github.com/Thavarshan/phpvm

Usage: phpvm help
EOF
}

# Self-tests for phpvm functionality
run_tests() {
# Set up test environment
Expand Down Expand Up @@ -909,6 +960,9 @@ main() {
help)
print_help
;;
version | --version | -v)
print_version
;;
test)
run_tests
;;
Expand Down
Loading