Skip to content

Commit c9939c9

Browse files
committed
feat: enhance alias functionality and add QA tooling
1 parent 539fe3c commit c9939c9

4 files changed

Lines changed: 190 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
### Added
66

77
- **Alias management commands:** Added `phpvm alias` and `phpvm unalias` for version alias creation, listing, and removal.
8+
- **Alias pattern filtering:** `phpvm alias <pattern>` now filters aliases by name.
89
- **Alias resolution support:** Aliases now resolve in `phpvm install`, `phpvm use`, and `phpvm which`.
910
- **Alias visibility:** `phpvm list` now shows configured aliases.
11+
- **Alias resolution in `.phpvmrc`:** `phpvm auto` now resolves aliases defined in `.phpvmrc`.
12+
- **Latest/stable keywords:** `latest` and `stable` now resolve to the latest installed PHP version.
1013
- **Quality assurance tooling:** Added ShellCheck and shfmt configuration, a QA Makefile, and a `qa.sh` runner script.
1114
- **BATS test suite:** Added comprehensive BATS tests for core functionality and new alias behavior.
1215
- **CI quality workflow:** Added a quality workflow for linting, formatting, and tests.

README.MD

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ phpvm auto
202202

203203
phpvm will automatically detect and switch to the version specified in the `.phpvmrc` file.
204204

205+
Aliases can also be used in `.phpvmrc`:
206+
207+
```sh
208+
echo "default" > .phpvmrc
209+
phpvm auto
210+
```
211+
205212
### Listing Installed Versions
206213

207214
To list all installed PHP versions:
@@ -227,6 +234,12 @@ List aliases:
227234
phpvm alias
228235
```
229236

237+
List aliases matching a pattern:
238+
239+
```sh
240+
phpvm alias def
241+
```
242+
230243
Remove an alias:
231244

232245
```sh
@@ -235,6 +248,13 @@ phpvm unalias production
235248

236249
Aliases also appear in `phpvm list` output when defined.
237250

251+
You can also use `latest` or `stable` as shorthand for the latest installed PHP version:
252+
253+
```sh
254+
phpvm use latest
255+
phpvm use stable
256+
```
257+
238258
### Cache Directory
239259

240260
Show the phpvm cache directory:

phpvm.sh

Lines changed: 136 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,14 @@ phpvm_resolve_version() {
396396
return 1
397397
fi
398398

399+
# Resolve special keywords
400+
if [ "$input" = "latest" ] || [ "$input" = "stable" ]; then
401+
if resolved=$(phpvm_get_latest_installed_version); then
402+
echo "$resolved"
403+
return 0
404+
fi
405+
fi
406+
399407
# Check alias file first
400408
if [ -f "$PHPVM_DIR/alias/$input" ]; then
401409
resolved=$(command cat "$PHPVM_DIR/alias/$input" 2>/dev/null | command tr -d '[:space:]')
@@ -411,6 +419,70 @@ phpvm_resolve_version() {
411419
return 0
412420
}
413421

422+
# Get latest installed PHP version (best-effort)
423+
phpvm_get_latest_installed_version() {
424+
local versions=()
425+
local version
426+
local latest
427+
428+
if [ "${PHPVM_TEST_MODE}" = "true" ]; then
429+
# Test mode: use test prefix paths
430+
for path in "${TEST_PREFIX:-/tmp}/opt/homebrew/Cellar/php"*; do
431+
if [ -d "$path" ]; then
432+
version=$(basename "$path")
433+
version=${version#php@}
434+
[ "$version" = "php" ] && continue
435+
versions+=("$version")
436+
fi
437+
done
438+
else
439+
case "$PKG_MANAGER" in
440+
brew)
441+
if [ -d "$HOMEBREW_PREFIX/Cellar" ]; then
442+
for path in "$HOMEBREW_PREFIX/Cellar/php"*; do
443+
if [ -d "$path" ]; then
444+
version=$(basename "$path")
445+
if [ "$version" = "php" ]; then
446+
version=$(get_installed_php_version)
447+
else
448+
version=${version#php@}
449+
fi
450+
[ -n "$version" ] && versions+=("$version")
451+
fi
452+
done
453+
fi
454+
;;
455+
apt)
456+
while read -r version; do
457+
versions+=("$version")
458+
done < <(dpkg-query -W -f='${Package}\n' 2>/dev/null | grep -E '^php[0-9]+\.[0-9]+' | sed 's/^php//')
459+
;;
460+
dnf | yum)
461+
while read -r version; do
462+
versions+=("$version")
463+
done < <($PKG_MANAGER list installed 2>/dev/null | grep -E 'php[0-9]+\.' | awk '{print $1}' | sed 's/^php//')
464+
;;
465+
pacman)
466+
while read -r version; do
467+
versions+=("$version")
468+
done < <(pacman -Q 2>/dev/null | grep '^php' | awk '{print $1}' | sed 's/^php//')
469+
;;
470+
esac
471+
fi
472+
473+
if [ ${#versions[@]} -eq 0 ]; then
474+
return 1
475+
fi
476+
477+
latest=$(printf '%s\n' "${versions[@]}" | sort -V | tail -1)
478+
if [ -n "$latest" ]; then
479+
echo "$latest"
480+
return 0
481+
fi
482+
483+
return 1
484+
}
485+
414486
# Check if Remi repository is available/enabled for RHEL/Fedora systems
415487
check_remi_repository() {
416488
# Check if Remi repository is installed
@@ -1334,14 +1406,17 @@ auto_switch_php_version() {
13341406
return 1
13351407
fi
13361408

1409+
# Resolve aliases before validation
1410+
version=$(phpvm_resolve_version "$version")
1411+
13371412
# Validate version is not empty and contains only valid characters
13381413
if [ -z "$version" ]; then
13391414
phpvm_warn "No valid PHP version found in $phpvmrc_file."
13401415
return 1
13411416
fi
13421417

1343-
# Basic validation for PHP version format (X.Y or system)
1344-
if ! echo "$version" | grep -qE '^([0-9]+\.[0-9]+|system)$'; then
1418+
# Validate version format (X.Y, X.Y.Z, or system)
1419+
if ! validate_php_version "$version"; then
13451420
phpvm_err "Invalid PHP version format in $phpvmrc_file: $version"
13461421
return 1
13471422
fi
@@ -1857,6 +1932,17 @@ EOF
18571932
[ $status -eq 0 ] && [ "$(cat $PHPVM_ACTIVE_VERSION_FILE)" = "7.4" ]
18581933
}
18591934

1935+
# Test use default alias
1936+
test_use_default_alias() {
1937+
mkdir -p "$TEST_DIR/opt/homebrew/Cellar/php@8.2/bin"
1938+
phpvm_alias "default" "8.2" >/dev/null 2>&1 || return 1
1939+
1940+
use_php_version "default" >/dev/null
1941+
local status=$?
1942+
1943+
[ $status -eq 0 ] && [ "$(cat $PHPVM_ACTIVE_VERSION_FILE)" = "8.2" ]
1944+
}
1945+
18601946
# Test system_php_version
18611947
test_system_php_version() {
18621948
system_php_version >/dev/null
@@ -1886,6 +1972,29 @@ EOF
18861972
[ $status -eq 0 ] && [ "$(cat $PHPVM_ACTIVE_VERSION_FILE)" = "7.4" ]
18871973
}
18881974

1975+
# Test auto_switch_php_version with alias
1976+
test_auto_switch_alias() {
1977+
# Create mock installation
1978+
mkdir -p "$TEST_DIR/opt/homebrew/Cellar/php@8.1/bin"
1979+
1980+
# Create alias
1981+
phpvm_alias "default" "8.1" >/dev/null 2>&1 || return 1
1982+
1983+
# Create a project with .phpvmrc
1984+
mkdir -p "$HOME/alias_project"
1985+
echo "default" >"$HOME/alias_project/.phpvmrc"
1986+
1987+
# Change to the project directory
1988+
cd "$HOME/alias_project"
1989+
1990+
# Test auto-switching
1991+
auto_switch_php_version >/dev/null
1992+
local status=$?
1993+
1994+
# Check for success and correct active version
1995+
[ $status -eq 0 ] && [ "$(cat $PHPVM_ACTIVE_VERSION_FILE)" = "8.1" ]
1996+
}
1997+
18891998
# Test handling of corrupted .phpvmrc file
18901999
test_corrupted_phpvmrc() {
18912000
# Create an invalid .phpvmrc file (empty)
@@ -2101,12 +2210,18 @@ EOF
21012210
total=$((total + 1))
21022211
test_function "use_php_version" test_use_php_version || failed=$((failed + 1))
21032212

2213+
total=$((total + 1))
2214+
test_function "use default alias" test_use_default_alias || failed=$((failed + 1))
2215+
21042216
total=$((total + 1))
21052217
test_function "system_php_version" test_system_php_version || failed=$((failed + 1))
21062218

21072219
total=$((total + 1))
21082220
test_function "auto_switch_php_version" test_auto_switch || failed=$((failed + 1))
21092221

2222+
total=$((total + 1))
2223+
test_function "auto_switch_php_version alias" test_auto_switch_alias || failed=$((failed + 1))
2224+
21102225
total=$((total + 1))
21112226
test_function "corrupted .phpvmrc handling" test_corrupted_phpvmrc || failed=$((failed + 1))
21122227

@@ -2308,6 +2423,16 @@ phpvm_alias() {
23082423
return 0
23092424
fi
23102425

2426+
# Pattern filter listing (phpvm alias <pattern>)
2427+
if [ -z "$version" ] && [ ! -f "$PHPVM_DIR/alias/$name" ]; then
2428+
phpvm_echo "Version aliases matching '$name':"
2429+
if phpvm_list_aliases "$name"; then
2430+
return 0
2431+
fi
2432+
echo " (no aliases matched)"
2433+
return $PHPVM_EXIT_NOT_FOUND
2434+
fi
2435+
23112436
# Show single alias
23122437
if [ -z "$version" ]; then
23132438
if [ -f "$PHPVM_DIR/alias/$name" ]; then
@@ -2415,10 +2540,16 @@ main() {
24152540
case "$command" in
24162541
use)
24172542
if [ "$#" -eq 0 ]; then
2418-
phpvm_err "Missing PHP version argument for 'use' command."
2419-
exit $PHPVM_EXIT_INVALID_ARG
2543+
if [ -f "$PHPVM_DIR/alias/default" ]; then
2544+
use_php_version "default"
2545+
else
2546+
phpvm_err "Missing PHP version argument for 'use' command."
2547+
phpvm_warn "Set a default alias with: phpvm alias default <version>"
2548+
exit $PHPVM_EXIT_INVALID_ARG
2549+
fi
2550+
else
2551+
use_php_version "$@"
24202552
fi
2421-
use_php_version "$@"
24222553
;;
24232554
install)
24242555
if [ "$#" -eq 0 ]; then

tests/02_features.bats

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ load test_helper
3535
[ "$status" -eq 0 ]
3636
[[ "$output" =~ "default" ]]
3737

38+
run PHPVM_DIR="$temp_dir/.phpvm" bash "$BATS_TEST_DIRNAME/../phpvm.sh" alias def
39+
[ "$status" -eq 0 ]
40+
[[ "$output" =~ "default" ]]
41+
3842
rm -rf "$temp_dir"
3943
}
4044

@@ -52,6 +56,33 @@ load test_helper
5256
rm -rf "$temp_dir"
5357
}
5458

59+
@test "phpvm auto resolves alias in .phpvmrc" {
60+
local temp_dir
61+
temp_dir=$(mktemp -d /tmp/phpvm-bats-rcalias.XXXXXX)
62+
63+
mkdir -p "$temp_dir/project"
64+
echo "default" > "$temp_dir/project/.phpvmrc"
65+
66+
PHPVM_DIR="$temp_dir/.phpvm" bash "$BATS_TEST_DIRNAME/../phpvm.sh" alias default 8.1
67+
68+
run bash -c "cd $temp_dir/project && PHPVM_DIR=$temp_dir/.phpvm PHPVM_TEST_MODE=true bash $BATS_TEST_DIRNAME/../phpvm.sh auto"
69+
[ "$status" -eq 0 ]
70+
71+
rm -rf "$temp_dir"
72+
}
73+
74+
@test "phpvm use without args uses default alias" {
75+
local temp_dir
76+
temp_dir=$(mktemp -d /tmp/phpvm-bats-default.XXXXXX)
77+
78+
PHPVM_DIR="$temp_dir/.phpvm" bash "$BATS_TEST_DIRNAME/../phpvm.sh" alias default 8.1
79+
80+
run PHPVM_DIR="$temp_dir/.phpvm" PHPVM_TEST_MODE=true bash "$BATS_TEST_DIRNAME/../phpvm.sh" use
81+
[ "$status" -eq 0 ]
82+
83+
rm -rf "$temp_dir"
84+
}
85+
5586
@test "phpvm cache dir works" {
5687
run bash "$BATS_TEST_DIRNAME/../phpvm.sh" cache dir
5788
[ "$status" -eq 0 ]

0 commit comments

Comments
 (0)