From e8ddc02797b5696d319f859158aa85d198335c3f Mon Sep 17 00:00:00 2001 From: Irfan Hardiyanto Date: Tue, 9 Jun 2026 22:53:30 +0700 Subject: [PATCH 1/2] Sprint 5: Linux parity + auto-release (1.7.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - phpvm composer: install composer.phar + POSIX shim per active PHP version, installer signature verified against composer.github.io/installer.sig - phpvm fix-ini: rewrites extension_dir to PHP_EXTENSION_DIR (in-place or append) - phpvm ext laravel [minimal|full]: enable bundled exts via conf.d drop-in, optional Redis via PECL on full preset, gracefully skips missing .so - .github/workflows/release.yml: auto-create GitHub release on v* tag push, verifies tag matches version.txt, generates notes from git log since previous tag - tests/linux/commands.bats: 13 tests covering dispatch + behavior of the new commands, stubs _phpvm_current_version so the suite runs cross-platform - README: documents the three new Linux commands; existing Linux section notes parity with Windows since 1.7.0 - Version bumped 1.6.5 → 1.7.0 across all 5 sources --- .github/workflows/release.yml | 56 +++++++++ README.md | 29 +++++ linux/install.sh | 2 +- linux/phpvm.sh | 216 +++++++++++++++++++++++++++++++++- tests/linux/commands.bats | 184 +++++++++++++++++++++++++++++ version.txt | 2 +- windows/install.ps1 | 2 +- windows/phpvm.ps1 | 2 +- 8 files changed, 488 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 tests/linux/commands.bats diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..67f4d92 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,56 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + release: + name: Create GitHub release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Verify tag matches version.txt + run: | + set -e + tag="${GITHUB_REF_NAME#v}" + file=$(tr -d '[:space:]' < version.txt) + if [ "$tag" != "$file" ]; then + echo "Tag '$tag' does not match version.txt '$file'." + exit 1 + fi + echo "Tag matches version.txt -> $file" + + - name: Generate release notes from commits since previous tag + id: notes + run: | + prev=$(git describe --tags --abbrev=0 "${GITHUB_REF_NAME}^" 2>/dev/null || echo "") + { + echo "## Changes" + echo "" + if [ -n "$prev" ]; then + git log --pretty=format:'- %s' "$prev..${GITHUB_REF_NAME}" + echo "" + echo "" + echo "**Full Changelog**: https://github.com/${GITHUB_REPOSITORY}/compare/${prev}...${GITHUB_REF_NAME}" + else + git log --pretty=format:'- %s' "${GITHUB_REF_NAME}" + fi + } > RELEASE_NOTES.md + echo "----- Generated notes -----" + cat RELEASE_NOTES.md + + - name: Create release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "${GITHUB_REF_NAME}" \ + --title "${GITHUB_REF_NAME}" \ + --notes-file RELEASE_NOTES.md diff --git a/README.md b/README.md index ceee39b..e07e359 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,34 @@ phpvm ext install mongodb 1.17.0 # specific version phpvm ext install xdebug ``` +### Laravel quick setup + +One command enables the extensions a typical Laravel app needs: + +```bash +phpvm ext laravel # full preset: minimal + intl, gd, opcache, pdo_pgsql, Redis (PECL) +phpvm ext laravel minimal # required only: openssl, pdo_mysql, mbstring, tokenizer, xml, ctype, fileinfo, bcmath, curl, zip, sodium +phpvm ext laravel full # explicit full (same as bare `phpvm ext laravel`) +``` + +Already-loaded extensions are reported as `already ON` and skipped. On Linux, extensions that aren't built into the active PHP are skipped with a `not built into this PHP` note rather than failed. + +### Composer + +```bash +phpvm composer # installs composer.phar + shim into the active PHP version's bin dir +``` + +The installer signature is verified against `composer.github.io/installer.sig` (SHA-384) before execution. Composer lives **inside the active PHP version's directory** — switch versions with `phpvm use ` then re-run `phpvm composer` for that version. + +### Fix `php.ini` extension_dir + +```bash +phpvm fix-ini # rewrites extension_dir to match PHP's compiled-in path +``` + +Useful when `extension_dir` was set by a previous install or copied from another machine. On Linux, the value comes from `PHP_EXTENSION_DIR`; on Windows, from `$VERSIONS_DIR\\ext`. + --- ## How It Works @@ -134,6 +162,7 @@ phpvm ext install xdebug - Stores versions in `~/.phpvm/versions//` - Switches via symlink (`~/.phpvm/current`) prepended to `$PATH` - Extensions installed via `pecl`, enabled via per-version `conf.d/` drop-ins +- `phpvm composer` / `phpvm fix-ini` / `phpvm ext laravel` work the same as Windows since 1.7.0 --- diff --git a/linux/install.sh b/linux/install.sh index 752bbe5..ebf13b8 100644 --- a/linux/install.sh +++ b/linux/install.sh @@ -6,7 +6,7 @@ set -e -PHPVM_VERSION="1.6.5" +PHPVM_VERSION="1.7.0" PHPVM_DIR="${PHPVM_DIR:-$HOME/.phpvm}" PHPVM_REPO="https://raw.githubusercontent.com/devhardiyanto/phpvm/main" diff --git a/linux/phpvm.sh b/linux/phpvm.sh index 282aaa9..95c897c 100644 --- a/linux/phpvm.sh +++ b/linux/phpvm.sh @@ -10,7 +10,7 @@ # phpvm use 8.3.0 # ============================================================================== -PHPVM_VERSION="1.6.5" +PHPVM_VERSION="1.7.0" PHPVM_DIR="${PHPVM_DIR:-$HOME/.phpvm}" PHPVM_VERSIONS="$PHPVM_DIR/versions" PHPVM_CURRENT="$PHPVM_DIR/current" @@ -671,6 +671,87 @@ if (extension_loaded('$name')) { echo "" } +phpvm_ext_laravel() { + local preset="${1:-full}" + case "$preset" in min|minimal) preset="minimal" ;; *) preset="full" ;; esac + + local cur + cur=$(_phpvm_current_version) + [[ -z "$cur" ]] && { _err "No active PHP version."; return 1; } + + local php_bin="$PHPVM_VERSIONS/$cur/bin/php" + [[ ! -x "$php_bin" ]] && { _err "php binary not found: $php_bin"; return 1; } + + local minimal=(openssl pdo pdo_mysql pdo_sqlite mbstring tokenizer xml ctype fileinfo bcmath curl zip sodium) + local extra=(intl gd exif opcache pdo_pgsql pgsql sockets) + local pecl=(redis) + + local enable_list=("${minimal[@]}") + local pecl_list=() + if [[ "$preset" != "minimal" ]]; then + enable_list+=("${extra[@]}") + pecl_list+=("${pecl[@]}") + fi + + echo "" + echo -e " \033[36mLaravel extension setup ($preset) — PHP $cur\033[0m" + echo -e " \033[90m─────────────────────────────────────────────────\033[0m" + echo "" + + local loaded + loaded=$("$php_bin" -m 2>/dev/null | tr '[:upper:]' '[:lower:]') + + local ext_dir + ext_dir=$("$php_bin" -r "echo ini_get('extension_dir');" 2>/dev/null) + + echo -e " \033[33m[1/2] Enabling bundled extensions ...\033[0m" + for ext in "${enable_list[@]}"; do + if echo "$loaded" | grep -qx "$ext"; then + printf " %-18s already ON\n" "$ext" + continue + fi + # Built-in extensions (e.g. pdo, mbstring) have no .so file; try enable anyway. + if [[ -n "$ext_dir" && ! -f "$ext_dir/$ext.so" && ! -f "$ext_dir/php_$ext.so" ]]; then + # Check if it's a static built-in via php -m again (case-insensitive match above already failed) + printf " \033[90mskip %-18s (not built into this PHP)\033[0m\n" "$ext" + continue + fi + phpvm_ext_enable "$ext" >/dev/null 2>&1 && _ok "Enabled: $ext" || _warn "Could not enable: $ext" + done + + if [[ ${#pecl_list[@]} -gt 0 ]]; then + echo "" + echo -e " \033[33m[2/2] PECL extensions ...\033[0m" + for ext in "${pecl_list[@]}"; do + if echo "$loaded" | grep -qx "$ext"; then + printf " %-18s already ON\n" "$ext" + continue + fi + if [[ -f "$ext_dir/$ext.so" || -f "$ext_dir/php_$ext.so" ]]; then + phpvm_ext_enable "$ext" >/dev/null 2>&1 && _ok "Enabled: $ext" + else + _step "Installing $ext via PECL ..." + if phpvm_ext_install "$ext"; then + phpvm_ext_enable "$ext" >/dev/null 2>&1 && _ok "Enabled: $ext" + fi + fi + done + fi + + echo "" + _ok "Done! Verify with: php -m" + echo "" + if [[ "$preset" == "minimal" ]]; then + _dim "For Redis + GD + opcache + intl, run: phpvm ext laravel full" + else + _dim "Optional extras:" + _dim " phpvm ext install xdebug # debugger" + _dim " phpvm ext install imagick # advanced image processing" + _dim " phpvm composer # install Composer" + fi + echo "" +} + phpvm_ext() { local sub="${1:-help}" local name="${2:-}" @@ -683,10 +764,129 @@ phpvm_ext() { enable) phpvm_ext_enable "$name" ;; disable) phpvm_ext_disable "$name" ;; info) phpvm_ext_info "$name" ;; + laravel) phpvm_ext_laravel "$name" ;; help|*) phpvm_ext_help ;; esac } +# ============================================================================== +# COMPOSER (one composer.phar per active PHP version) +# ============================================================================== +phpvm_composer() { + local cur + cur=$(_phpvm_current_version) + [[ -z "$cur" ]] && { _err "No active PHP version. Run: phpvm use "; return 1; } + + local php_root="$PHPVM_VERSIONS/$cur" + local php_bin="$php_root/bin/php" + [[ ! -x "$php_bin" ]] && { _err "php binary not found: $php_bin"; return 1; } + + local phar="$php_root/bin/composer.phar" + local shim="$php_root/bin/composer" + + if [[ -x "$shim" && -f "$phar" ]]; then + _warn "Composer already installed at $shim" + _dim "Run: composer --version" + return 0 + fi + + # openssl is bundled on most distros' PHP-from-source builds; warn if missing. + if ! "$php_bin" -r "exit(extension_loaded('openssl') ? 0 : 1);" 2>/dev/null; then + _warn "openssl extension not loaded; Composer requires it." + _dim "Enable it then retry: phpvm ext enable openssl" + fi + + local installer_url="https://getcomposer.org/installer" + local sig_url="https://composer.github.io/installer.sig" + local tmp; tmp=$(mktemp -t composer-setup.XXXXXX.php) || { _err "mktemp failed."; return 1; } + + _step "Downloading Composer installer ..." + if command -v curl &>/dev/null; then + curl -fsSL "$installer_url" -o "$tmp" || { _err "Download failed."; rm -f "$tmp"; return 1; } + elif command -v wget &>/dev/null; then + wget -qO "$tmp" "$installer_url" || { _err "Download failed."; rm -f "$tmp"; return 1; } + else + _err "curl or wget is required."; rm -f "$tmp"; return 1 + fi + + _step "Verifying installer integrity ..." + local expected actual + if command -v curl &>/dev/null; then + expected=$(curl -fsSL "$sig_url" 2>/dev/null | tr -d '[:space:]') + else + expected=$(wget -qO- "$sig_url" 2>/dev/null | tr -d '[:space:]') + fi + actual=$("$php_bin" -r "echo hash_file('sha384', '$tmp');" 2>/dev/null) + + if [[ -z "$expected" || "$actual" != "$expected" ]]; then + _err "Hash mismatch! Installer may be corrupt or tampered." + rm -f "$tmp" + return 1 + fi + _ok "Hash verified." + + _step "Installing Composer ..." + mkdir -p "$php_root/bin" + (cd "$php_root/bin" && "$php_bin" "$tmp" --quiet --filename=composer.phar) || { + _err "Composer installer failed." + rm -f "$tmp" + return 1 + } + rm -f "$tmp" + + [[ ! -f "$phar" ]] && { _err "composer.phar not created at $phar"; return 1; } + + # POSIX shim — works in bash/zsh/sh. + cat > "$shim" </dev/null + echo "" + _dim "Note: composer is installed inside the PHP $cur bin dir." + _dim "After 'phpvm use ', re-run 'phpvm composer' for that version." +} + +# ============================================================================== +# FIX-INI (sync extension_dir in active php.ini) +# ============================================================================== +phpvm_fix_ini() { + local cur + cur=$(_phpvm_current_version) + [[ -z "$cur" ]] && { _err "No active PHP version. Run: phpvm use "; return 1; } + + local target_dir="$PHPVM_VERSIONS/$cur" + local php_bin="$target_dir/bin/php" + local ini="$target_dir/etc/php.ini" + [[ ! -x "$php_bin" ]] && { _err "php binary not found: $php_bin"; return 1; } + [[ ! -f "$ini" ]] && { _err "php.ini not found: $ini"; return 1; } + + # Resolve the real extension_dir compiled into PHP. + local ext_path + ext_path=$("$php_bin" -r "echo PHP_EXTENSION_DIR;" 2>/dev/null) + [[ -z "$ext_path" ]] && { _err "Could not resolve PHP_EXTENSION_DIR."; return 1; } + + if grep -qE '^\s*;?\s*extension_dir\s*=' "$ini"; then + # In-place edit, escaping path for sed (/ in path). + local esc + esc=$(printf '%s' "$ext_path" | sed 's:[\\/&]:\\&:g') + sed -i.bak -E "s|^[[:space:]]*;?[[:space:]]*extension_dir[[:space:]]*=.*$|extension_dir = \"$esc\"|" "$ini" + rm -f "$ini.bak" + _ok "Fixed extension_dir → $ext_path" + else + printf '\nextension_dir = "%s"\n' "$ext_path" >> "$ini" + _ok "Added extension_dir → $ext_path" + fi + + _dim "Verify: phpvm ext list" +} + # ============================================================================== # HELP # ============================================================================== @@ -703,6 +903,9 @@ phpvm_ext_help() { phpvm ext install Install via PECL phpvm ext install Install specific version via PECL phpvm ext info Extension details + phpvm ext laravel Enable all Laravel extensions (full) + phpvm ext laravel minimal Enable required Laravel extensions only + phpvm ext laravel full Enable required + recommended + Redis Examples: phpvm ext install redis @@ -729,8 +932,17 @@ phpvm_help() { phpvm uninstall Remove a PHP version phpvm which Path to active php binary phpvm ini Open active php.ini in \$EDITOR + phpvm fix-ini Sync extension_dir in active php.ini phpvm deps Print dependency install command + COMPOSER + phpvm composer Install Composer for active PHP version + + LARAVEL QUICK SETUP + phpvm ext laravel Enable all Laravel extensions (full) + phpvm ext laravel minimal Required extensions only + phpvm ext laravel full Required + recommended + Redis + AUTO-SWITCH (.phpvmrc) phpvm auto Switch to the version named in .phpvmrc phpvm hook enable Enable auto-switching on cd (bash/zsh) @@ -888,6 +1100,8 @@ phpvm() { ini) phpvm_ini ;; deps) phpvm_deps ;; ext) phpvm_ext "$@" ;; + composer) phpvm_composer ;; + fix-ini) phpvm_fix_ini ;; auto) phpvm_auto ;; hook) phpvm_hook "$@" ;; upgrade|update) phpvm_upgrade ;; diff --git a/tests/linux/commands.bats b/tests/linux/commands.bats new file mode 100644 index 0000000..1c4a160 --- /dev/null +++ b/tests/linux/commands.bats @@ -0,0 +1,184 @@ +#!/usr/bin/env bats +# Tests for Sprint 5 Linux commands: composer, fix-ini, ext laravel. +# Run from repo root: bats tests/linux/ + +setup() { + export PHPVM_DIR="$BATS_TEST_TMPDIR/phpvm" + export PHPVM_VERSIONS="$PHPVM_DIR/versions" + export PHPVM_CURRENT="$PHPVM_DIR/current" + export PHPVM_NO_INIT=1 + export PHPVM_NO_UPDATE_CHECK=1 + mkdir -p "$PHPVM_VERSIONS" + + # shellcheck disable=SC1091 + . "$BATS_TEST_DIRNAME/../../linux/phpvm.sh" +} + +# Stand up a fake PHP install at $PHPVM_VERSIONS/$1 with a fake php binary +# whose behavior is driven by env vars the test sets. Stubs +# _phpvm_current_version directly so the suite works on Windows Git Bash +# (where `ln -s` produces a copy rather than a real symlink). +_fake_php_install() { + local ver="$1" + local root="$PHPVM_VERSIONS/$ver" + mkdir -p "$root/bin" "$root/etc" "$root/lib/php/extensions" + eval "_phpvm_current_version() { echo '$ver'; }" + + # The fake php binary supports: -m (extensions list), -r (one-liner), + # -v, --version, and the composer-setup --quiet flow. + cat > "$root/bin/php" <<'PHPEOF' +#!/usr/bin/env bash +# Test double for php. Behavior controlled via env: +# FAKE_PHP_EXTS space-separated extension names for -m +# FAKE_PHP_EXT_DIR value returned for ini_get('extension_dir') / PHP_EXTENSION_DIR +# FAKE_PHP_HASH value returned for hash_file() +case "$1" in + -m) printf '%s\n' ${FAKE_PHP_EXTS:-Core openssl} ;; + -r) + case "$2" in + *PHP_EXTENSION_DIR*) printf '%s' "${FAKE_PHP_EXT_DIR:-/dev/null/ext}" ;; + *ini_get*extension_dir*) printf '%s' "${FAKE_PHP_EXT_DIR:-/dev/null/ext}" ;; + *hash_file*) printf '%s' "${FAKE_PHP_HASH:-deadbeef}" ;; + *extension_loaded*openssl*) + case " ${FAKE_PHP_EXTS:-openssl} " in *" openssl "*) exit 0 ;; *) exit 1 ;; esac ;; + *extension_loaded*) exit 1 ;; + *) ;; + esac ;; + -v|--version) echo "PHP fake" ;; + *) + # composer installer invocation: php /tmp/setup.php --quiet --filename=composer.phar + # Just create a stub composer.phar in CWD. + if [[ -n "${FAKE_COMPOSER_OK:-}" ]]; then + echo '#!/usr/bin/env php' > composer.phar + fi + ;; +esac +PHPEOF + chmod +x "$root/bin/php" + + # Default etc/php.ini for fix-ini tests + printf ';extension_dir = "/old/path"\n' > "$root/etc/php.ini" +} + +# ---------- phpvm_composer ---------- + +@test "composer: errors when no active version" { + eval "_phpvm_current_version() { echo ''; }" + run phpvm_composer + [ "$status" -ne 0 ] + [[ "$output" == *"No active PHP version"* ]] +} + +@test "composer: no-op when shim + phar already present" { + _fake_php_install 8.3.0 + local bin="$PHPVM_VERSIONS/8.3.0/bin" + touch "$bin/composer.phar" + cat > "$bin/composer" <<'EOF' +#!/usr/bin/env sh +EOF + chmod +x "$bin/composer" + run phpvm_composer + [ "$status" -eq 0 ] + [[ "$output" == *"already installed"* ]] +} + +# ---------- phpvm_fix_ini ---------- + +@test "fix-ini: errors when no active version" { + eval "_phpvm_current_version() { echo ''; }" + run phpvm_fix_ini + [ "$status" -ne 0 ] + [[ "$output" == *"No active PHP version"* ]] +} + +@test "fix-ini: rewrites commented extension_dir line" { + _fake_php_install 8.3.0 + export FAKE_PHP_EXT_DIR="$PHPVM_VERSIONS/8.3.0/lib/php/extensions/no-debug-non-zts-20230831" + run phpvm_fix_ini + [ "$status" -eq 0 ] + [[ "$output" == *"Fixed extension_dir"* ]] + grep -q "^extension_dir = \"$FAKE_PHP_EXT_DIR\"" "$PHPVM_VERSIONS/8.3.0/etc/php.ini" +} + +@test "fix-ini: appends extension_dir when missing" { + _fake_php_install 8.3.0 + : > "$PHPVM_VERSIONS/8.3.0/etc/php.ini" # empty ini + export FAKE_PHP_EXT_DIR="/opt/ext" + run phpvm_fix_ini + [ "$status" -eq 0 ] + [[ "$output" == *"Added extension_dir"* ]] + grep -q '^extension_dir = "/opt/ext"' "$PHPVM_VERSIONS/8.3.0/etc/php.ini" +} + +@test "fix-ini: errors when php.ini missing" { + _fake_php_install 8.3.0 + rm -f "$PHPVM_VERSIONS/8.3.0/etc/php.ini" + run phpvm_fix_ini + [ "$status" -ne 0 ] + [[ "$output" == *"php.ini not found"* ]] +} + +# ---------- phpvm_ext_laravel ---------- + +@test "ext laravel: errors when no active version" { + eval "_phpvm_current_version() { echo ''; }" + run phpvm_ext_laravel + [ "$status" -ne 0 ] + [[ "$output" == *"No active PHP version"* ]] +} + +@test "ext laravel: minimal preset reports already-loaded extensions" { + _fake_php_install 8.3.0 + # All minimal extensions report as loaded → no enable attempts. + export FAKE_PHP_EXTS="openssl pdo pdo_mysql pdo_sqlite mbstring tokenizer xml ctype fileinfo bcmath curl zip sodium" + export FAKE_PHP_EXT_DIR="$PHPVM_VERSIONS/8.3.0/lib/php/extensions/no-debug-non-zts-20230831" + mkdir -p "$FAKE_PHP_EXT_DIR" + run phpvm_ext_laravel minimal + [ "$status" -eq 0 ] + [[ "$output" == *"minimal"* ]] + [[ "$output" == *"already ON"* ]] + [[ "$output" == *"Done"* ]] +} + +@test "ext laravel: full preset banner + Redis hint" { + _fake_php_install 8.3.0 + export FAKE_PHP_EXTS="Core openssl" + export FAKE_PHP_EXT_DIR="$PHPVM_VERSIONS/8.3.0/lib/php/extensions/no-debug-non-zts-20230831" + mkdir -p "$FAKE_PHP_EXT_DIR" + run phpvm_ext_laravel full + [ "$status" -eq 0 ] + [[ "$output" == *"full"* ]] + [[ "$output" == *"PECL extensions"* ]] +} + +@test "ext laravel: defaults to full when no preset arg" { + _fake_php_install 8.3.0 + export FAKE_PHP_EXT_DIR="$PHPVM_VERSIONS/8.3.0/lib/php/extensions/no-debug-non-zts-20230831" + mkdir -p "$FAKE_PHP_EXT_DIR" + run phpvm_ext_laravel + [ "$status" -eq 0 ] + [[ "$output" == *"(full)"* ]] +} + +# ---------- dispatch ---------- + +@test "dispatch: 'phpvm composer' routes to phpvm_composer" { + eval "_phpvm_current_version() { echo ''; }" + run phpvm composer + [ "$status" -ne 0 ] + [[ "$output" == *"No active PHP version"* ]] +} + +@test "dispatch: 'phpvm fix-ini' routes to phpvm_fix_ini" { + eval "_phpvm_current_version() { echo ''; }" + run phpvm fix-ini + [ "$status" -ne 0 ] + [[ "$output" == *"No active PHP version"* ]] +} + +@test "dispatch: 'phpvm ext laravel' routes to phpvm_ext_laravel" { + eval "_phpvm_current_version() { echo ''; }" + run phpvm ext laravel + [ "$status" -ne 0 ] + [[ "$output" == *"No active PHP version"* ]] +} diff --git a/version.txt b/version.txt index 9f05f9f..bd8bf88 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.6.5 +1.7.0 diff --git a/windows/install.ps1 b/windows/install.ps1 index 559590f..8ee9ffd 100644 --- a/windows/install.ps1 +++ b/windows/install.ps1 @@ -7,7 +7,7 @@ Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" -$PHPVM_VERSION = "1.6.5" +$PHPVM_VERSION = "1.7.0" $PHPVM_DIR = if ($env:PHPVM_DIR) { $env:PHPVM_DIR } else { "$env:USERPROFILE\.phpvm" } $PHPVM_BIN = "$PHPVM_DIR\bin" diff --git a/windows/phpvm.ps1 b/windows/phpvm.ps1 index b5c7b6b..477dc89 100644 --- a/windows/phpvm.ps1 +++ b/windows/phpvm.ps1 @@ -14,7 +14,7 @@ Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" # -- Constants ----------------------------------------------------------------- -$PHPVM_VERSION = "1.6.5" +$PHPVM_VERSION = "1.7.0" $PHPVM_DIR = if ($env:PHPVM_DIR) { $env:PHPVM_DIR } else { "$env:USERPROFILE\.phpvm" } $VERSIONS_DIR = "$PHPVM_DIR\versions" $CURRENT_LINK = "$PHPVM_DIR\current" From 2210863d3ad12102e8a4302d1e614cfcd862b7fa Mon Sep 17 00:00:00 2001 From: Irfan Hardiyanto Date: Tue, 9 Jun 2026 22:55:45 +0700 Subject: [PATCH 2/2] =?UTF-8?q?Fix=20SC2015=20in=20phpvm=5Fext=5Flaravel?= =?UTF-8?q?=20=E2=80=94=20use=20if/else=20instead=20of=20A=20&&=20B=20||?= =?UTF-8?q?=20C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- linux/phpvm.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux/phpvm.sh b/linux/phpvm.sh index 95c897c..d43d66e 100644 --- a/linux/phpvm.sh +++ b/linux/phpvm.sh @@ -716,7 +716,11 @@ phpvm_ext_laravel() { printf " \033[90mskip %-18s (not built into this PHP)\033[0m\n" "$ext" continue fi - phpvm_ext_enable "$ext" >/dev/null 2>&1 && _ok "Enabled: $ext" || _warn "Could not enable: $ext" + if phpvm_ext_enable "$ext" >/dev/null 2>&1; then + _ok "Enabled: $ext" + else + _warn "Could not enable: $ext" + fi done if [[ ${#pecl_list[@]} -gt 0 ]]; then