Skip to content

Commit 9b98de5

Browse files
committed
Refactor phpvm.sh for improved error handling and readability; streamline PHP installation and switching functions.
1 parent 8ef31aa commit 9b98de5

File tree

2 files changed

+81
-149
lines changed

2 files changed

+81
-149
lines changed

phpvm.sh

Lines changed: 72 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -10,110 +10,121 @@ HOMEBREW_PHP_CELLAR="/opt/homebrew/Cellar"
1010
HOMEBREW_PHP_BIN="/opt/homebrew/bin"
1111

1212
# Create the required directory and exit if it fails.
13-
mkdir -p "$PHPVM_VERSIONS_DIR" || { echo "Error: Failed to create directory $PHPVM_VERSIONS_DIR" >&2; exit 1; }
13+
mkdir -p "$PHPVM_VERSIONS_DIR" || {
14+
echo "Error: Failed to create directory $PHPVM_VERSIONS_DIR" >&2
15+
exit 1
16+
}
1417

1518
# ANSI color codes
1619
RED="\e[31m"
1720
GREEN="\e[32m"
1821
YELLOW="\e[33m"
19-
# Removed BLUE as it is unused
2022
RESET="\e[0m"
2123

22-
# Output functions for better readability and robust error checking.
23-
phpvm_echo() {
24-
if ! command printf "%b%s%b\n" "$GREEN" "$*" "$RESET"; then
25-
echo "Error: Failed in phpvm_echo" >&2
26-
fi
24+
# Output functions
25+
phpvm_echo() { printf "%b%s%b\n" "$GREEN" "$*" "$RESET"; }
26+
phpvm_err() { printf "%bError: %s%b\n" "$RED" "$*" "$RESET" >&2; }
27+
phpvm_warn() { printf "%bWarning: %s%b\n" "$YELLOW" "$*" "$RESET" >&2; }
28+
29+
# Helper function to check if Homebrew is installed
30+
is_brew_installed() {
31+
command -v brew &>/dev/null
2732
}
2833

29-
phpvm_err() {
30-
command >&2 printf "%bError: %s%b\n" "$RED" "$*" "$RESET"
34+
# Helper function to install PHP using Homebrew
35+
brew_install_php() {
36+
local version=$1
37+
if ! brew install php@"$version"; then
38+
phpvm_warn "php@$version is not available in Homebrew. Trying latest version..."
39+
if ! brew install php; then
40+
phpvm_err "Failed to install PHP."
41+
return 1
42+
fi
43+
fi
44+
return 0
3145
}
3246

33-
phpvm_warn() {
34-
command >&2 printf "%bWarning: %s%b\n" "$YELLOW" "$*" "$RESET"
47+
# Helper function to get the installed PHP version
48+
get_installed_php_version() {
49+
if command -v php-config &>/dev/null; then
50+
php-config --version
51+
else
52+
php -v | awk '/^PHP/ {print $2}'
53+
fi
3554
}
3655

37-
# Function to install a specific PHP version with error handling.
3856
install_php() {
3957
local version=$1
40-
if [[ -z $version ]]; then
41-
phpvm_err "No PHP version specified for installation."
42-
return 1
43-
fi
58+
[[ -z $version ]] && {
59+
phpvm_err "No PHP version specified for installation."
60+
return 1
61+
}
4462

4563
phpvm_echo "Installing PHP $version..."
46-
47-
if command -v brew &>/dev/null; then
48-
if ! brew install php@"$version"; then
49-
phpvm_err "Failed to install PHP $version via Homebrew."
50-
return 1
51-
fi
52-
elif command -v apt-get &>/dev/null; then
53-
if ! sudo apt-get update; then
54-
phpvm_err "apt-get update failed."
55-
return 1
56-
fi
57-
if ! sudo apt-get install -y php"$version"; then
58-
phpvm_err "Failed to install PHP $version via apt-get."
59-
return 1
60-
fi
61-
elif command -v dnf &>/dev/null; then
62-
if ! sudo dnf install -y php; then
63-
phpvm_err "Failed to install PHP via dnf."
64-
return 1
65-
fi
64+
if is_brew_installed; then
65+
brew_install_php "$version" || return 1
6666
else
67-
phpvm_err "Unsupported Linux distribution."
67+
phpvm_err "Unsupported package manager. Please install PHP manually."
6868
return 1
6969
fi
7070
phpvm_echo "PHP $version installed."
7171
return 0
7272
}
7373

74-
# Function to switch to a specific PHP version with robust error handling.
7574
use_php_version() {
7675
local version=$1
77-
if [[ -z $version ]]; then
78-
phpvm_err "No PHP version specified to switch."
79-
return 1
80-
fi
76+
[[ -z $version ]] && {
77+
phpvm_err "No PHP version specified to switch."
78+
return 1
79+
}
8180

8281
phpvm_echo "Switching to PHP $version..."
82+
if is_brew_installed; then
83+
if [[ -d "$HOMEBREW_PHP_CELLAR/php@$version" ]]; then
84+
brew unlink php &>/dev/null || phpvm_warn "Failed to unlink current PHP version."
85+
brew link php@"$version" --force --overwrite || {
86+
phpvm_err "Failed to link PHP $version."
87+
return 1
88+
}
89+
elif [[ -d "$HOMEBREW_PHP_CELLAR/php" ]]; then
90+
local installed_version
91+
installed_version=$(get_installed_php_version)
8392

84-
if command -v brew &>/dev/null && [[ -d "$HOMEBREW_PHP_CELLAR/php@$version" ]]; then
85-
if ! brew unlink php &>/dev/null; then
86-
phpvm_warn "Failed to unlink current PHP version. Continuing..."
87-
fi
88-
if ! brew link php@"$version" --force --overwrite; then
89-
phpvm_err "Failed to link PHP $version."
93+
if [[ "$installed_version" == "$version"* ]]; then
94+
phpvm_echo "Using PHP $version installed as 'php'."
95+
else
96+
phpvm_err "PHP version $version is not installed."
97+
return 1
98+
fi
99+
else
100+
phpvm_err "PHP version $version is not installed."
90101
return 1
91102
fi
92-
if ! ln -sfn "$HOMEBREW_PHP_BIN/php" "$PHPVM_CURRENT_SYMLINK"; then
93-
phpvm_err "Failed to update current symlink."
103+
ln -sfn "$HOMEBREW_PHP_BIN/php" "$PHPVM_CURRENT_SYMLINK" || {
104+
phpvm_err "Failed to update symlink."
94105
return 1
95-
fi
96-
if ! echo "$version" > "$PHPVM_ACTIVE_VERSION_FILE"; then
97-
phpvm_err "Failed to write active version to file."
106+
}
107+
echo "$version" >"$PHPVM_ACTIVE_VERSION_FILE" || {
108+
phpvm_err "Failed to write active version."
98109
return 1
99-
fi
110+
}
100111
phpvm_echo "Switched to PHP $version."
101-
return 0
102112
else
103-
phpvm_err "PHP version $version is not installed in Homebrew Cellar."
113+
phpvm_err "Homebrew is not installed."
104114
return 1
105115
fi
106116
}
107117

108-
# Function to auto-switch PHP version based on the .phpvmrc file with error handling.
109118
auto_switch_php_version() {
110119
local current_dir="$PWD"
111120
local found=0
121+
local depth=0
122+
local max_depth=5
112123

113-
while [[ "$current_dir" != "/" ]]; do
124+
while [[ "$current_dir" != "/" && $depth -lt $max_depth ]]; do
114125
if [[ -f "$current_dir/.phpvmrc" ]]; then
115126
local version
116-
if ! version=$(cat "$current_dir/.phpvmrc" 2>/dev/null | tr -d '[:space:]'); then
127+
if ! version=$(tr -d '[:space:]' <"$current_dir/.phpvmrc"); then
117128
phpvm_err "Failed to read $current_dir/.phpvmrc"
118129
return 1
119130
fi
@@ -125,11 +136,13 @@ auto_switch_php_version() {
125136
fi
126137
else
127138
phpvm_warn "No valid PHP version found in $current_dir/.phpvmrc."
139+
return 1
128140
fi
129141
found=1
130142
break
131143
fi
132144
current_dir=$(dirname "$current_dir")
145+
((depth++))
133146
done
134147

135148
if [[ $found -eq 0 ]]; then
@@ -138,62 +151,3 @@ auto_switch_php_version() {
138151
fi
139152
return 0
140153
}
141-
142-
# Stub function for uninstalling PHP. Added error handling.
143-
uninstall_php() {
144-
local version=$1
145-
if [[ -z "$version" ]]; then
146-
phpvm_err "No PHP version specified for uninstallation."
147-
return 1
148-
fi
149-
# Placeholder for actual uninstallation logic.
150-
phpvm_warn "Uninstall PHP $version is not yet implemented."
151-
return 1
152-
}
153-
154-
# Stub function for listing installed PHP versions. Added error handling.
155-
list_php_versions() {
156-
# Placeholder for PHP version listing logic.
157-
phpvm_echo "Listing installed PHP versions is not yet implemented."
158-
return 1
159-
}
160-
161-
# Prevent execution when sourced.
162-
if [[ "$0" == "${BASH_SOURCE[0]}" ]]; then
163-
case "$1" in
164-
install)
165-
if ! install_php "$2"; then
166-
phpvm_err "Installation failed."
167-
exit 1
168-
fi
169-
;;
170-
uninstall)
171-
if ! uninstall_php "$2"; then
172-
phpvm_err "Uninstallation failed."
173-
exit 1
174-
fi
175-
;;
176-
list)
177-
if ! list_php_versions; then
178-
phpvm_err "Listing PHP versions failed."
179-
exit 1
180-
fi
181-
;;
182-
use)
183-
if ! use_php_version "$2"; then
184-
phpvm_err "Switching PHP version failed."
185-
exit 1
186-
fi
187-
;;
188-
autoswitch)
189-
if ! auto_switch_php_version; then
190-
phpvm_err "Auto-switching PHP version failed."
191-
exit 1
192-
fi
193-
;;
194-
*)
195-
phpvm_echo "Usage: phpvm {install|uninstall|list|use|autoswitch} <version>"
196-
exit 1
197-
;;
198-
esac
199-
fi

test_phpvm.bats

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,13 @@ setup() {
1212
PATH="$MOCK_DIR:$PATH"
1313

1414
# Create a dummy 'brew' command
15-
cat << 'EOF' > "$MOCK_DIR/brew"
15+
cat <<'EOF' >"$MOCK_DIR/brew"
1616
#!/bin/bash
1717
# Simply print the arguments to verify the call.
1818
echo "brew $*"
1919
exit 0
2020
EOF
2121
chmod +x "$MOCK_DIR/brew"
22-
23-
# Create a dummy 'apt-get' command
24-
cat << 'EOF' > "$MOCK_DIR/apt-get"
25-
#!/bin/bash
26-
if [[ $1 == "update" ]]; then
27-
echo "apt-get update"
28-
exit 0
29-
fi
30-
if [[ $1 == "install" ]]; then
31-
echo "apt-get install $*"
32-
exit 0
33-
fi
34-
EOF
35-
chmod +x "$MOCK_DIR/apt-get"
36-
37-
# Create a dummy 'dnf' command
38-
cat << 'EOF' > "$MOCK_DIR/dnf"
39-
#!/bin/bash
40-
echo "dnf $*"
41-
exit 0
42-
EOF
43-
chmod +x "$MOCK_DIR/dnf"
4422
}
4523

4624
teardown() {
@@ -79,25 +57,25 @@ teardown() {
7957
@test "auto_switch_php_version warns when .phpvmrc is not found" {
8058
# Run from a temporary directory that does not contain .phpvmrc.
8159
TEST_DIR="$(mktemp -d)"
82-
pushd "$TEST_DIR" > /dev/null
60+
pushd "$TEST_DIR" >/dev/null
8361
run auto_switch_php_version
84-
popd > /dev/null
62+
popd >/dev/null
8563
[ "$status" -ne 0 ]
8664
[[ "$output" == *"No .phpvmrc file found"* ]]
8765
}
8866

8967
@test "auto_switch_php_version switches PHP version from .phpvmrc" {
9068
# Create a temporary directory with a .phpvmrc file
9169
TEST_DIR="$(mktemp -d)"
92-
echo "7.4" > "$TEST_DIR/.phpvmrc"
93-
70+
echo "7.4" >"$TEST_DIR/.phpvmrc"
71+
9472
# Create a fake Homebrew cellar directory to simulate an installed PHP version.
9573
mkdir -p "/opt/homebrew/Cellar/[email protected]"
96-
97-
pushd "$TEST_DIR" > /dev/null
74+
75+
pushd "$TEST_DIR" >/dev/null
9876
run auto_switch_php_version
99-
popd > /dev/null
100-
77+
popd >/dev/null
78+
10179
[ "$status" -eq 0 ]
10280
[[ "$output" == *"Auto-switching to PHP 7.4"* ]]
10381
}

0 commit comments

Comments
 (0)