From ce20b56b564d52ac5d7d39ddb61806bee5e9dbfa Mon Sep 17 00:00:00 2001 From: Michele Locati Date: Tue, 26 Jan 2021 16:58:14 +0100 Subject: [PATCH] Support installing generic versions of extensions --- .github/workflows/test-extensions.yml | 2 + README.md | 13 +++++- install-php-extensions | 57 ++++++++++++++++++++++++++- scripts/test-installversion | 5 ++- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-extensions.yml b/.github/workflows/test-extensions.yml index 590aef4..4c89ce8 100644 --- a/.github/workflows/test-extensions.yml +++ b/.github/workflows/test-extensions.yml @@ -110,6 +110,8 @@ jobs: - '' - 2.9.8 - 3.0.0 + - ^2 + - ^2.8 steps: - name: Checkout uses: actions/checkout@v1 diff --git a/README.md b/README.md index 5ca8bed..6ffdf71 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ docker pull mlocati/php-extension-installer *otherwise the `COPY` instruction could use a previously downloaded, outdated version of the image stored in the local docker cache.* -### Installing a specific version of an extension +### Installing specific versions of an extension Simply append `-` to the module name. For example: @@ -59,6 +59,17 @@ For example: install-php-extensions xdebug-2.9.7 ``` +The script also support resolving *compatible* versions by prefixing the version with a caret (`^`). +For example: + +```sh +# Install the most recent xdebug 2.x version (for example 2.9.8) +install-php-extensions xdebug-^2 +# Install the most recent xdebug 2.x version (for example 2.8.1) +install-php-extensions xdebug-^2.8 +``` + + ### Installing composer You can also install [composer](https://getcomposer.org/), and you also can specify a major version of it, or a full version. diff --git a/install-php-extensions b/install-php-extensions index ddf02f1..9461ac4 100755 --- a/install-php-extensions +++ b/install-php-extensions @@ -141,8 +141,10 @@ getPeclModuleName() { } # Parse a module name (and optionally version) as received via command arguments, extracting the version and normalizing it -# Example: +# Examples: # xdebug-2.9.8 +# xdebug-^2 +# xdebug-^2.9 # # Arguments: # $1: the name of the module to be normalized @@ -189,6 +191,56 @@ getWantedPHPModuleVersion() { fi } +# Get the wanted PHP module version, resolving it if it starts with '^' +# +# Arguments: +# $1: the name of the module to be normalized +# +# Output: +# The version to be used +resolveWantedPHPModuleVersion() { + resolveWantedPHPModuleVersion_raw="$(getWantedPHPModuleVersion "$1")" + resolveWantedPHPModuleVersion_afterCaret="${resolveWantedPHPModuleVersion_raw#^}" + if test "$resolveWantedPHPModuleVersion_raw" = "$resolveWantedPHPModuleVersion_afterCaret"; then + printf '%s' "$resolveWantedPHPModuleVersion_raw" + return + fi + resolveWantedPHPModuleVersion_xml="$(curl -sSLf "http://pecl.php.net/rest/r/$1/allreleases.xml")" + resolveWantedPHPModuleVersion_versions="$(printf '%s' "$resolveWantedPHPModuleVersion_xml" | tr -s ' \t\r\n' ' ' | sed -r 's# *<#\n<#g' | grep '' | sed 's###g' | sed 's# ##g')" + resetIFS + for resolveWantedPHPModuleVersion_version in $resolveWantedPHPModuleVersion_versions; do + resolveWantedPHPModuleVersion_suffix="${resolveWantedPHPModuleVersion_version#$resolveWantedPHPModuleVersion_afterCaret}" + if test "$resolveWantedPHPModuleVersion_version" != "${resolveWantedPHPModuleVersion_version#$resolveWantedPHPModuleVersion_afterCaret.}"; then + # Example: looking for 1.0, found 1.0.1 + printf '%s' "$resolveWantedPHPModuleVersion_version" + return + fi + done + for resolveWantedPHPModuleVersion_version in $resolveWantedPHPModuleVersion_versions; do + resolveWantedPHPModuleVersion_suffix="${resolveWantedPHPModuleVersion_version#$resolveWantedPHPModuleVersion_afterCaret}" + if test "$resolveWantedPHPModuleVersion_version" = "$resolveWantedPHPModuleVersion_suffix"; then + continue + fi + if test -z "$resolveWantedPHPModuleVersion_suffix"; then + # Example: looking for 1.0, found exactly it + printf '%s' "$resolveWantedPHPModuleVersion_version" + return + fi + case "$resolveWantedPHPModuleVersion_suffix" in + [0-9]) + # Example: looking for 1.1, but this is 1.10 + ;; + *) + # Example: looking for 1.1, this is 1.1rc1 + printf '%s' "$resolveWantedPHPModuleVersion_version" + return + ;; + esac + done + printf 'Unable to find a version of "%s" compatible with "%s"\nAvailable versions are:\n%s\n' "$1" "$resolveWantedPHPModuleVersion_raw" "$resolveWantedPHPModuleVersion_versions" >&2 + exit 1 +} + # Set these variables: # - PHP_PREINSTALLED_MODULES the normalized list of PHP modules installed before running this script setPHPPreinstalledModules() { @@ -1222,6 +1274,7 @@ installMicrosoftSqlServerODBC() { # Install Composer installComposer() { installComposer_version="$(getWantedPHPModuleVersion @composer)" + installComposer_version="${installComposer_version#^}" if test -z "$installComposer_version"; then installComposer_fullname=composer installComposer_flags='' @@ -1442,7 +1495,7 @@ getPackageSource() { installRemoteModule() { installRemoteModule_module="$1" printf '### INSTALLING REMOTE MODULE %s ###\n' "$installRemoteModule_module" - installRemoteModule_version="$(getWantedPHPModuleVersion "$installRemoteModule_module")" + installRemoteModule_version="$(resolveWantedPHPModuleVersion "$installRemoteModule_module")" rm -rf "$CONFIGURE_FILE" installRemoteModule_manuallyInstalled=0 installRemoteModule_cppflags='' diff --git a/scripts/test-installversion b/scripts/test-installversion index 84cbcf3..b9d7799 100755 --- a/scripts/test-installversion +++ b/scripts/test-installversion @@ -5,6 +5,7 @@ set -o errexit set -o nounset WANTED_VERSION="${1:-}" +WANTED_VERSION_AFTERCARET="${1#^}" INSTALLME=xdebug if test -n "$WANTED_VERSION"; then INSTALLME="$INSTALLME-$1" @@ -14,9 +15,11 @@ CI=true ./install-php-extensions "$INSTALLME" INSTALLED_VERSION="$(php --ri xdebug | grep -Ei 'Version\s*=>\s*' | sed -E 's/^.*?=>\s*//')" if test -z "$WANTED_VERSION"; then - echo 'Installing the default version worked' + printf 'Installing the default version worked (we installed version %s)\n' "$INSTALLED_VERSION" elif test "$WANTED_VERSION" = "$INSTALLED_VERSION"; then printf 'Installing specific version %s worked\n' "$WANTED_VERSION" +elif test "$WANTED_VERSION" != "$WANTED_VERSION_AFTERCARET" && test "${INSTALLED_VERSION#$WANTED_VERSION_AFTERCARET.}" != "$INSTALLED_VERSION"; then + printf 'Installing version compatible with %s worked (we installed version %s)\n' "$WANTED_VERSION" "$INSTALLED_VERSION" else printf 'We wanted to install version %s, but we installed %s\n' "$WANTED_VERSION" "$INSTALLED_VERSION" >&2 exit 1