Ability to install extensions from source code/specific commits (#538)

pull/545/head 1.5.0
Michele Locati 2022-03-25 10:55:08 +01:00 committed by GitHub
parent 9167ef9b59
commit bf88b6d618
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 217 additions and 58 deletions

View File

@ -162,3 +162,31 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- run: IPE_INSTANTCLIENT_BASIC=1 ./install-php-extensions oci8 pdo_oci - run: IPE_INSTANTCLIENT_BASIC=1 ./install-php-extensions oci8 pdo_oci
test_install_fromsource:
name: Test installing from source
needs:
- check_syntax_data
- check_syntax_shell
- check_syntax_php
runs-on: ubuntu-latest
container: ${{ matrix.container }}
strategy:
matrix:
container:
- php:8.1-cli-alpine
source:
- php-memcached-dev/php-memcached@8f106564e6bb005ca6100b12ccc89000daafa9d8
- php-memcached-dev/php-memcached@8f106564e6bb
- php-memcached-dev/php-memcached@v3.2.0RC2
- php-memcached-dev/php-memcached@refs/tags/v3.2.0RC2
include:
-
container: php:8.1-cli-bullseye
source: php-memcached-dev/php-memcached@v3.2.0RC2
-
container: php:7.4-cli-alpine
source: php-memcached-dev/php-memcached@v3.2.0RC2
steps:
- name: Checkout
uses: actions/checkout@v3
- run: ./install-php-extensions ${{ matrix.source }}

View File

@ -95,6 +95,45 @@ For example:
install-php-extensions mongodb-stable install-php-extensions mongodb-stable
``` ```
### Installing from source code
You can also install PHP extensions from source code (provided that it comes with a `package.xml` or a `package2.xml` file).
Accepted formats are:
- A short version for repositories hosted on GitHub.
For example, for the [php-memcached-dev/php-memcached](https://github.com/php-memcached-dev/php-memcached) GitHub repository,
you can simply write:
```sh
# Install from a specific commit (full commit SHA-1)
install-php-extensions php-memcached-dev/php-memcached@8f106564e6bb005ca6100b12ccc89000daafa9d8
# Install from a specific commit (short commit SHA-1)
install-php-extensions php-memcached-dev/php-memcached@8f106564e6bb
# Install from tag v3.2.0RC2
install-php-extensions php-memcached-dev/php-memcached@v3.2.0RC2
install-php-extensions php-memcached-dev/php-memcached@refs/tags/v3.2.0RC2
# Install from branch master
install-php-extensions php-memcached-dev/php-memcached@master
install-php-extensions php-memcached-dev/php-memcached@refs/heads/master
```
- An URL providing an archive containing the source code.
Examples:
```sh
# tgz archive for commit 8f106564e6bb005ca6100b12ccc89000daafa9d8
install-php-extensions https://codeload.github.com/php-memcached-dev/php-memcached/tar.gz/8f106564e6bb005ca6100b12ccc89000daafa9d8
# tgz archive for tag v3.1.5
install-php-extensions https://codeload.github.com/php-memcached-dev/php-memcached/tar.gz/refs/tags/v3.1.5
# tgz archive for branch master
install-php-extensions https://codeload.github.com/php-memcached-dev/php-memcached/tar.gz/refs/heads/master
```
- The absolute path of a local directory
Examples:
```sh
# Download the source code
curl -o /tmp/source.tgz https://codeload.github.com/php-memcached-dev/php-memcached/tar.gz/refs/tags/v3.1.5
tar xzf /tmp/source.tgz -C /tmp
install-php-extensions /tmp/php-memcached-3.1.5
### Installing composer ### Installing composer
You can also install [composer](https://getcomposer.org/), and you also can specify a major version of it, or a full version. You can also install [composer](https://getcomposer.org/), and you also can specify a major version of it, or a full version.

View File

@ -183,9 +183,51 @@ extractPackageVersionFromXML() {
printf 'Unable to find the file\n%s\n' >&2 printf 'Unable to find the file\n%s\n' >&2
return 1 return 1
fi fi
extractPackageVersionFromXML_xml="$(cat "$1" | tr '\n' ' ' | sed -E 's/<!--.*?-->//')" extractPackageVersionFromXML_code="$(
printf '\extractPackageVersionFromXML_xml=\n%s\n' "$extractPackageVersionFromXML_xml" | sed -E 's/^.*?' cat <<'EOT'
exit 1 $doc = new DOMDocument();
if (!$doc->load($argv[1])) {
fwrite(STDERR, "Failed to load XML file\n");
exit(1);
}
set_error_handler(
static function($errno, $errstr) {
fwrite(STDERR, trim((string) $errstr) . "\n");
exit(1);
},
-1
);
$xpath = new DOMXpath($doc);
$xpath->registerNamespace('v20', 'http://pear.php.net/dtd/package-2.0');
$xpath->registerNamespace('v21', 'http://pear.php.net/dtd/package-2.1');
if ($xpath->query('/v20:package/v20:dependencies')->count() === 1) {
$ns = 'v20:';
} elseif ($xpath->query('/v21:package/v21:dependencies')->count() === 1) {
$ns = 'v21:';
} elseif ($xpath->query('/package')->count() === 1) {
$ns = '';
} else {
fwrite(STDERR, "Unsupported namespace of the XML of package version details\n");
}
$nodes = $xpath->query("/{$ns}package/{$ns}name");
$name = trim((string) $nodes[0]->nodeValue);
if ($ns === '') {
$nodes = $xpath->query("/{$ns}package/{$ns}version");
} else {
$nodes = $xpath->query("/{$ns}package/{$ns}version/{$ns}release");
}
$version = trim((string) $nodes[0]->nodeValue);
echo "EXTRACTPACKAGEVERSIONFROMXML_NAME='{$name}'\n";
echo "EXTRACTPACKAGEVERSIONFROMXML_VERSION='{$version}'\n";
exit(0);
EOT
)"
extractPackageVersionFromXML_vars="$(php -n -d display_errors=stderr -r "$extractPackageVersionFromXML_code" "$1")"
if test -z "$extractPackageVersionFromXML_vars"; then
return 1
fi
eval "$extractPackageVersionFromXML_vars"
return 0
} }
# Parse a module name (and optionally version) as received via command arguments, extracting the version and normalizing it # Parse a module name (and optionally version) as received via command arguments, extracting the version and normalizing it
@ -202,6 +244,7 @@ extractPackageVersionFromXML() {
# #
# Optionally set these variables: # Optionally set these variables:
# - PHP_WANTEDMODULEVERSION_<...> (where <...> is the normalized module name) # - PHP_WANTEDMODULEVERSION_<...> (where <...> is the normalized module name)
# - PHP_MODULESOURCECODEPATH_<...> (where <...> is the normalized module name)
# #
# Output: # Output:
# Nothing # Nothing
@ -212,7 +255,7 @@ processPHPModuleArgument() {
# php-memcached-dev/php-memcached@8f106564e6bb005ca6100b12ccc89000daafa9d8 # php-memcached-dev/php-memcached@8f106564e6bb005ca6100b12ccc89000daafa9d8
# to # to
# https://codeload.github.com/php-memcached-dev/php-memcached/tar.gz/8f106564e6bb005ca6100b12ccc89000daafa9d8 # https://codeload.github.com/php-memcached-dev/php-memcached/tar.gz/8f106564e6bb005ca6100b12ccc89000daafa9d8
processPHPModuleArgument_arg="$(printf '%s' "$processPHPModuleArgument_arg" | sed -E 's/^([a-zA-Z0-9_.\-]+\/[a-zA-Z0-9_.\-]+)@([a-zA-Z0-9]{40}$)/https:\/\/codeload.github.com\/\1\/tar.gz\/\2/')" processPHPModuleArgument_arg="$(printf '%s' "$processPHPModuleArgument_arg" | sed -E 's/^([a-zA-Z0-9_.\-]+\/[a-zA-Z0-9_.\-]+)@(.+$)/https:\/\/codeload.github.com\/\1\/tar.gz\/\2/')"
# Let's check if $processPHPModuleArgument_arg is an URL # Let's check if $processPHPModuleArgument_arg is an URL
if printf '%s' "$processPHPModuleArgument_arg" | grep -Eq '^https?://[^ ]+/[^ ]+$'; then if printf '%s' "$processPHPModuleArgument_arg" | grep -Eq '^https?://[^ ]+/[^ ]+$'; then
printf 'Downloading source from %s\n' "$processPHPModuleArgument_arg" printf 'Downloading source from %s\n' "$processPHPModuleArgument_arg"
@ -234,14 +277,24 @@ processPHPModuleArgument() {
printf 'Unable to find the package.xml file in the directory\n%s\n' "$processPHPModuleArgument_arg" printf 'Unable to find the package.xml file in the directory\n%s\n' "$processPHPModuleArgument_arg"
return 1 return 1
fi fi
fi printf 'good (name: %s, version: %s)\n' "$EXTRACTPACKAGEVERSIONFROMXML_NAME" "$EXTRACTPACKAGEVERSIONFROMXML_VERSION"
PROCESSED_PHP_MODULE_ARGUMENT="${processPHPModuleArgument_arg%%-*}" PROCESSED_PHP_MODULE_ARGUMENT="$(normalizePHPModuleName "$EXTRACTPACKAGEVERSIONFROMXML_NAME")"
if test -n "$PROCESSED_PHP_MODULE_ARGUMENT" && test "$PROCESSED_PHP_MODULE_ARGUMENT" != "$processPHPModuleArgument_arg"; then processPHPModuleArgument_version="$EXTRACTPACKAGEVERSIONFROMXML_VERSION"
processPHPModuleArgument_version="${processPHPModuleArgument_arg#*-}" if printf '%s' "$PROCESSED_PHP_MODULE_ARGUMENT" | grep -Eq '^[a-zA-Z0-9_]+$'; then
eval PHP_MODULESOURCECODEPATH_$PROCESSED_PHP_MODULE_ARGUMENT="$processPHPModuleArgument_arg"
else
printf 'Unable to parse the following module name:\n%s\n' "$PROCESSED_PHP_MODULE_ARGUMENT" >&2
exit 1
fi
else else
processPHPModuleArgument_version='' PROCESSED_PHP_MODULE_ARGUMENT="${processPHPModuleArgument_arg%%-*}"
if test -n "$PROCESSED_PHP_MODULE_ARGUMENT" && test "$PROCESSED_PHP_MODULE_ARGUMENT" != "$processPHPModuleArgument_arg"; then
processPHPModuleArgument_version="${processPHPModuleArgument_arg#*-}"
else
processPHPModuleArgument_version=''
fi
PROCESSED_PHP_MODULE_ARGUMENT="$(normalizePHPModuleName "$PROCESSED_PHP_MODULE_ARGUMENT")"
fi fi
PROCESSED_PHP_MODULE_ARGUMENT="$(normalizePHPModuleName "$PROCESSED_PHP_MODULE_ARGUMENT")"
if test -n "$processPHPModuleArgument_version"; then if test -n "$processPHPModuleArgument_version"; then
if printf '%s' "$PROCESSED_PHP_MODULE_ARGUMENT" | grep -Eq '^[a-zA-Z0-9_]+$'; then if printf '%s' "$PROCESSED_PHP_MODULE_ARGUMENT" | grep -Eq '^[a-zA-Z0-9_]+$'; then
eval PHP_WANTEDMODULEVERSION_$PROCESSED_PHP_MODULE_ARGUMENT="$processPHPModuleArgument_version" eval PHP_WANTEDMODULEVERSION_$PROCESSED_PHP_MODULE_ARGUMENT="$processPHPModuleArgument_version"
@ -268,6 +321,19 @@ getWantedPHPModuleVersion() {
fi fi
} }
# Get source code path of a PHP module version, as specified in the command line arguments.
#
# Arguments:
# $1: the name of the module to be normalized
#
# Output:
# The wanted version (if any)
getModuleSourceCodePath() {
if printf '%s' "$1" | grep -Eq '^[a-zA-Z0-9_]+$'; then
eval printf '%s' "\${PHP_MODULESOURCECODEPATH_$1:-}"
fi
}
# Get the wanted PHP module version, resolving it if it starts with '^' # Get the wanted PHP module version, resolving it if it starts with '^'
# #
# Arguments: # Arguments:
@ -1943,6 +2009,9 @@ installBundledModule() {
if test -n "$(getWantedPHPModuleVersion "$1")"; then if test -n "$(getWantedPHPModuleVersion "$1")"; then
printf '### WARNING the module "%s" is bundled with PHP, you can NOT specify a version for it\n' "$1" >&2 printf '### WARNING the module "%s" is bundled with PHP, you can NOT specify a version for it\n' "$1" >&2
fi fi
if test -n "$(getModuleSourceCodePath "$1")"; then
printf '### WARNING the module "%s" is bundled with PHP, you can NOT specify a source code path for it\n' "$1" >&2
fi
case "$1" in case "$1" in
dba) dba)
if test -e /usr/lib/$TARGET_TRIPLET/libdb-5.3.so && ! test -e /usr/lib/libdb-5.3.so; then if test -e /usr/lib/$TARGET_TRIPLET/libdb-5.3.so && ! test -e /usr/lib/libdb-5.3.so; then
@ -2199,6 +2268,7 @@ installRemoteModule() {
installRemoteModule_module="$1" installRemoteModule_module="$1"
printf '### INSTALLING REMOTE MODULE %s ###\n' "$installRemoteModule_module" printf '### INSTALLING REMOTE MODULE %s ###\n' "$installRemoteModule_module"
installRemoteModule_version="$(resolveWantedPHPModuleVersion "$installRemoteModule_module")" installRemoteModule_version="$(resolveWantedPHPModuleVersion "$installRemoteModule_module")"
installRemoteModule_path="$(getModuleSourceCodePath "$installRemoteModule_module")"
rm -rf "$CONFIGURE_FILE" rm -rf "$CONFIGURE_FILE"
installRemoteModule_manuallyInstalled=0 installRemoteModule_manuallyInstalled=0
installRemoteModule_cppflags='' installRemoteModule_cppflags=''
@ -2389,16 +2459,18 @@ installRemoteModule() {
fi fi
;; ;;
geos) geos)
if test -z "$installRemoteModule_version"; then if test -z "$installRemoteModule_path"; then
installRemoteModule_version=71b5f9001512e16d3cf4657b517e8a051d6ef36f if test -z "$installRemoteModule_version"; then
installRemoteModule_version=71b5f9001512e16d3cf4657b517e8a051d6ef36f
fi
installRemoteModule_src="$(getPackageSource https://git.osgeo.org/gitea/geos/php-geos/archive/$installRemoteModule_version.tar.gz)"
cd "$installRemoteModule_src"
./autogen.sh
./configure
make -j$(getProcessorCount) install
cd - >/dev/null
installRemoteModule_manuallyInstalled=1
fi fi
installRemoteModule_src="$(getPackageSource https://git.osgeo.org/gitea/geos/php-geos/archive/$installRemoteModule_version.tar.gz)"
cd "$installRemoteModule_src"
./autogen.sh
./configure
make -j$(getProcessorCount) install
cd - >/dev/null
installRemoteModule_manuallyInstalled=1
;; ;;
geospatial) geospatial)
if test -z "$installRemoteModule_version"; then if test -z "$installRemoteModule_version"; then
@ -2738,16 +2810,18 @@ installRemoteModule() {
fi fi
;; ;;
snuffleupagus) snuffleupagus)
if test -z "$installRemoteModule_version"; then if test -z "$installRemoteModule_path"; then
installRemoteModule_version=0.7.1 if test -z "$installRemoteModule_version"; then
installRemoteModule_version=0.7.1
fi
installRemoteModule_src="$(getPackageSource https://codeload.github.com/jvoisin/snuffleupagus/tar.gz/v$installRemoteModule_version)"
cd "$installRemoteModule_src/src"
phpize
./configure --enable-snuffleupagus
make -j$(getProcessorCount) install
cd - >/dev/null
cp -a "$installRemoteModule_src/config/default.rules" "$PHP_INI_DIR/conf.d/snuffleupagus.rules"
fi fi
installRemoteModule_src="$(getPackageSource https://codeload.github.com/jvoisin/snuffleupagus/tar.gz/v$installRemoteModule_version)"
cd "$installRemoteModule_src/src"
phpize
./configure --enable-snuffleupagus
make -j$(getProcessorCount) install
cd - >/dev/null
cp -a "$installRemoteModule_src/config/default.rules" "$PHP_INI_DIR/conf.d/snuffleupagus.rules"
installRemoteModule_manuallyInstalled=1 installRemoteModule_manuallyInstalled=1
;; ;;
solr) solr)
@ -2762,22 +2836,24 @@ installRemoteModule() {
installRemoteModule_manuallyInstalled=1 installRemoteModule_manuallyInstalled=1
;; ;;
spx) spx)
if test -z "$installRemoteModule_version"; then if test -z "$installRemoteModule_path"; then
installRemoteModule_version=6eba1a5839d0ce8dc71148ed723c72fe06c69600 if test -z "$installRemoteModule_version"; then
installRemoteModule_version=6eba1a5839d0ce8dc71148ed723c72fe06c69600
fi
if test "${installRemoteModule_version%.*}" = "$installRemoteModule_version"; then
installRemoteModule_displayVersion="$installRemoteModule_version"
else
installRemoteModule_displayVersion="git--master-$installRemoteModule_version"
fi
installRemoteModule_src="$(getPackageSource https://codeload.github.com/NoiseByNorthwest/php-spx/tar.gz/$installRemoteModule_version)"
cd -- "$installRemoteModule_src"
sed -Ei "s/^([ \t]*#define[ \t]+PHP_SPX_VERSION[ \t]+\")0.4.10(\")/\1git--master-$installRemoteModule_displayVersion\2/" src/php_spx.h
phpize
./configure
make -j$(getProcessorCount) install
cd - >/dev/null
installRemoteModule_manuallyInstalled=1
fi fi
if test "${installRemoteModule_version%.*}" = "$installRemoteModule_version"; then
installRemoteModule_displayVersion="$installRemoteModule_version"
else
installRemoteModule_displayVersion="git--master-$installRemoteModule_version"
fi
installRemoteModule_src="$(getPackageSource https://codeload.github.com/NoiseByNorthwest/php-spx/tar.gz/$installRemoteModule_version)"
cd -- "$installRemoteModule_src"
sed -Ei "s/^([ \t]*#define[ \t]+PHP_SPX_VERSION[ \t]+\")0.4.10(\")/\1git--master-$installRemoteModule_displayVersion\2/" src/php_spx.h
phpize
./configure
make -j$(getProcessorCount) install
cd - >/dev/null
installRemoteModule_manuallyInstalled=1
;; ;;
sqlsrv | pdo_sqlsrv) sqlsrv | pdo_sqlsrv)
isMicrosoftSqlServerODBCInstalled || installMicrosoftSqlServerODBC isMicrosoftSqlServerODBCInstalled || installMicrosoftSqlServerODBC
@ -2967,16 +3043,18 @@ installRemoteModule() {
make install make install
cd - >/dev/null cd - >/dev/null
fi fi
installRemoteModule_tmp="$(mktemp -p /tmp/src -d)" if test -z "$installRemoteModule_path"; then
git clone --depth=1 --recurse-submodules https://github.com/yaroslavche/phptdlib.git "$installRemoteModule_tmp" installRemoteModule_tmp="$(mktemp -p /tmp/src -d)"
mkdir "$installRemoteModule_tmp/build" git clone --depth=1 --recurse-submodules https://github.com/yaroslavche/phptdlib.git "$installRemoteModule_tmp"
cd "$installRemoteModule_tmp/build" mkdir "$installRemoteModule_tmp/build"
cmake -D USE_SHARED_PHPCPP:BOOL=ON .. cd "$installRemoteModule_tmp/build"
make cmake -D USE_SHARED_PHPCPP:BOOL=ON ..
make install make
cd - >/dev/null make install
rm "$PHP_INI_DIR/conf.d/tdlib.ini" cd - >/dev/null
installRemoteModule_manuallyInstalled=1 rm "$PHP_INI_DIR/conf.d/tdlib.ini"
installRemoteModule_manuallyInstalled=1
fi
;; ;;
tensor) tensor)
if test -z "$installRemoteModule_version"; then if test -z "$installRemoteModule_version"; then
@ -3135,10 +3213,12 @@ installRemoteModule() {
;; ;;
esac esac
if test $installRemoteModule_manuallyInstalled -eq 0; then if test $installRemoteModule_manuallyInstalled -eq 0; then
if test -n "$installRemoteModule_version"; then if test -n "$installRemoteModule_path"; then
printf ' (installing version %s from %s)\n' "$installRemoteModule_version" "$installRemoteModule_path"
elif test -n "$installRemoteModule_version"; then
printf ' (installing version %s)\n' "$installRemoteModule_version" printf ' (installing version %s)\n' "$installRemoteModule_version"
fi fi
installPeclPackage "$installRemoteModule_module" "$installRemoteModule_version" "$installRemoteModule_cppflags" installPeclPackage "$installRemoteModule_module" "$installRemoteModule_version" "$installRemoteModule_cppflags" "$installRemoteModule_path"
fi fi
postProcessModule "$installRemoteModule_module" postProcessModule "$installRemoteModule_module"
checkModuleWorking "$installRemoteModule_module" checkModuleWorking "$installRemoteModule_module"
@ -3263,7 +3343,8 @@ addConfigureOption() {
# Arguments: # Arguments:
# $1: the package to be installed # $1: the package to be installed
# $2: the package version to be installed (optional) # $2: the package version to be installed (optional)
# $3: the value of the CPPFLAGS variable # $3: the value of the CPPFLAGS variable (optional)
# $4: the path of the local package to be installed (optional, downloaded from PECL if omitted/empty)
installPeclPackage() { installPeclPackage() {
if ! test -f "$CONFIGURE_FILE"; then if ! test -f "$CONFIGURE_FILE"; then
printf '\n' >"$CONFIGURE_FILE" printf '\n' >"$CONFIGURE_FILE"
@ -3274,10 +3355,21 @@ installPeclPackage() {
else else
installPeclPackage_fullname="$installPeclPackage_name-$2" installPeclPackage_fullname="$installPeclPackage_name-$2"
fi fi
installPeclPackage_path="${4:-}"
if test -z "$installPeclPackage_path"; then
installPeclPackage_path="$installPeclPackage_fullname"
fi
if test $USE_PICKLE -eq 0; then if test $USE_PICKLE -eq 0; then
cat "$CONFIGURE_FILE" | MAKE="make -j$(getCompilationProcessorCount $1)" CPPFLAGS="${3:-}" pecl install "$installPeclPackage_fullname" if test -n "${4:-}"; then
if test -f "$installPeclPackage_path/package2.xml"; then
installPeclPackage_path="$installPeclPackage_path/package2.xml"
else
installPeclPackage_path="$installPeclPackage_path/package.xml"
fi
fi
cat "$CONFIGURE_FILE" | MAKE="make -j$(getCompilationProcessorCount $1)" CPPFLAGS="${3:-}" pecl install "$installPeclPackage_path"
else else
MAKE="make -j$(getCompilationProcessorCount $1)" CPPFLAGS="${3:-}" /tmp/pickle install --tmp-dir=/tmp/pickle.tmp --no-interaction --version-override='' --with-configure-options "$CONFIGURE_FILE" -- "$installPeclPackage_fullname" MAKE="make -j$(getCompilationProcessorCount $1)" CPPFLAGS="${3:-}" /tmp/pickle install --tmp-dir=/tmp/pickle.tmp --no-interaction --version-override='' --with-configure-options "$CONFIGURE_FILE" -- "$installPeclPackage_path"
fi fi
} }