#!/bin/sh # Let's set a sane environment set -o errexit set -o nounset echo 'Checking environment' if test -z "${TRAVIS_BUILD_DIR:-}"; then echo 'Not in a TravisCI environment' >&2 exit 1 fi if test -z "${TRAVIS_COMMIT_RANGE:-}"; then echo 'The TravisCI commit range is empty' >&2 exit 0 fi . "${TRAVIS_BUILD_DIR}/scripts/common" ALREADY_TESTED_EXTENSIONS='' # Get the docker image ID for a PHP extension and a PHP version # # Arguments: # $1: the extension name # $2: the PHP version # # Outputs: # the full docker image ID getDockerImageName () { case "${2}" in *) getDockerImageName_version="${2}" ;; esac getDockerImageName_suffix='-cli' getDockerImageName_reqs="${TRAVIS_BUILD_DIR}/data/special-requirements" if test -f "${getDockerImageName_reqs}"; then if test -n "$(cat "${getDockerImageName_reqs}" | grep -E "^${1}[ \t]+zts[ \t]*$")"; then getDockerImageName_suffix="-zts" fi fi case "${DOCKER_DISTRO:-}" in alpine) getDockerImageName_distro="-$DOCKER_DISTRO" ;; *) getDockerImageName_distro='' ;; esac printf 'php:%s%s%s' "${getDockerImageName_version}" "${getDockerImageName_suffix}" "${getDockerImageName_distro}" } # Test an extension # # Arguments: # $1: the extension name # $2: the PHP version # # Return: # 0 (true): if test passes # 1 (false): if test fails testExtension () { printf 'PHP version: %s\n' "${2}" if test -n "$(printf '%s' "${2}" | sed -E 's/^[0-9]+\.[0-9]+$//')"; then printf ' INVALID PHP VERSION: %s\n' "${2}" >&2 return 1 fi testExtension_Image="$(getDockerImageName "${1}" "${2}")" printf ' - Docker image: %s\n' "${testExtension_Image}" testExtension_out=`mktemp` if $(docker run --rm --volume "${TRAVIS_BUILD_DIR}:/app" --workdir /app "${testExtension_Image}" sh -c "./install-php-extensions '${1}' && php ./scripts/check-installed-extension.php '${1}'" >"${testExtension_out}" 2>&1); then rm -rf "${testExtension_out}" printf ' - Passed\n' return 0 fi printf ' - FAILED!\n' >&2 tail -n500 "${testExtension_out}" >&2 rm -rf "${testExtension_out}" return 1 } # Test a new extension line # # Arguments: # $1: the extension name # $@: the list of PHP versions # # Return: # 0 (true): if test passes # 1 (false): if test fails testNewExtensionLine () { testNewExtensionLine_rc=0 if test $# -lt 2; then printf 'Missing PHP version list for the new extension %s\n' "${1:-}" testNewExtensionLine_rc=1 elif ! stringInList "$1" "$ALREADY_TESTED_EXTENSIONS"; then printf '### TESTING NEW EXTENSION %s ###\n' "${1}" if test -n "$(printf '%s' "${1}" | sed -E 's/^[a-z][a-z0-9\-\_\.]+$//')"; then printf ' INVALID PHP EXTENSION NAME: %s\n' "${1}" >&2 testNewExtensionLine_rc=1 else ALREADY_TESTED_EXTENSIONS="$ALREADY_TESTED_EXTENSIONS $1" testNewExtensionLine_extension="${1}" while test $# -ge 2; do shift testNewExtensionLine_phpVersion="${1}" if ! testExtension "${testNewExtensionLine_extension}" "${1}"; then testNewExtensionLine_rc=1 fi done fi fi return ${testNewExtensionLine_rc} } #Get the list of all supported PHP versions # # Arguments: # $1: the extension name # # Outputs: # the space-separated list of supported PHP versions getAllPHPVersionsFor () { getAllPHPVersionsFor_result='' while IFS= read -r getAllPHPVersionsFor_line; do getAllPHPVersionsFor_ok= IFS=' ' for getAllPHPVersionsFor_chunk in $getAllPHPVersionsFor_line; do if test -z "$getAllPHPVersionsFor_ok"; then if test "$getAllPHPVersionsFor_chunk" = "$1"; then getAllPHPVersionsFor_ok=y else getAllPHPVersionsFor_ok=n fi else if test $getAllPHPVersionsFor_ok = 'y'; then if test -z "$getAllPHPVersionsFor_result"; then getAllPHPVersionsFor_result="$getAllPHPVersionsFor_chunk" else if ! stringInList "$getAllPHPVersionsFor_chunk" "$getAllPHPVersionsFor_result"; then getAllPHPVersionsFor_result="$getAllPHPVersionsFor_result $getAllPHPVersionsFor_chunk" fi fi fi fi done done < "$TRAVIS_BUILD_DIR/data/supported-extensions" printf '%s' "${getAllPHPVersionsFor_result}" } # Test extensions by reading a commit message # # Arguments: # $1: the commit hash # # Set: # STOP_NEXT_COMMITS to 1 if we should skip next commits # # Return: # 0 (true): if test passes # 1 (false): if test fails testExtensionsFromMessage () { testExtensionsFromMessage_result=0 TEST_EXTENSIONS= FIRST_LINE=1 testExtensionsFromMessage_message="$(git -C "${TRAVIS_BUILD_DIR}" log --pretty='format:%B' -n 1 "$1")" IFS=' ' for COMMIT_LINE in $testExtensionsFromMessage_message; do if test $FIRST_LINE -eq 1; then FIRST_LINE=0 else TESTLIST= case "$COMMIT_LINE" in Test:* ) TESTLIST=${COMMIT_LINE#Test:} ;; TEST:* ) TESTLIST=${COMMIT_LINE#TEST:} ;; test:* ) TESTLIST=${COMMIT_LINE#test:} ;; esac if test -n "$TESTLIST"; then IFS=' ,;' for COMMIT_LINE_EXT in $TESTLIST; do if test $COMMIT_LINE_EXT = '-STOP-'; then STOP_NEXT_COMMITS=1 elif test -z "$TEST_EXTENSIONS"; then TEST_EXTENSIONS=$COMMIT_LINE_EXT; else if ! stringInList "$COMMIT_LINE_EXT" "$TEST_EXTENSIONS"; then TEST_EXTENSIONS="$TEST_EXTENSIONS $COMMIT_LINE_EXT" fi fi done fi fi IFS=' ' for TEST_EXTENSION in $TEST_EXTENSIONS; do if ! stringInList "$TEST_EXTENSION" "$ALREADY_TESTED_EXTENSIONS"; then ALREADY_TESTED_EXTENSIONS="$ALREADY_TESTED_EXTENSIONS $TEST_EXTENSION" printf '### TESTING EXTENSION %s ###\n' "$TEST_EXTENSION" for TEST_PHPVERSION in $(getAllPHPVersionsFor $TEST_EXTENSION); do if ! testExtension "$TEST_EXTENSION" "$TEST_PHPVERSION"; then testExtensionsFromMessage_result=1 fi done fi done done resetIFS return $testExtensionsFromMessage_result } STOP_NEXT_COMMITS=0 TESTS_RESULTS=0 ADDED_EXTENSION_LINE= FOUND_ATAT= IFS=' ' for DIFF_LINE in $(git -C "${TRAVIS_BUILD_DIR}" diff --no-indent-heuristic --minimal --no-color --word-diff=none -no-renames --unified=0 "${TRAVIS_COMMIT_RANGE:-}" -- data/supported-extensions); do if test -n "${DIFF_LINE}"; then if test -z "${FOUND_ATAT}"; then if test -z "${DIFF_LINE##@@*}"; then FOUND_ATAT=y fi elif test -z "${DIFF_LINE##+*}"; then resetIFS ADDED_EXTENSION_LINE="${DIFF_LINE##+}" if ! testNewExtensionLine ${ADDED_EXTENSION_LINE}; then TESTS_RESULTS=1 fi fi fi done IFS=' ' for COMMIT_HASH in $(git -C "${TRAVIS_BUILD_DIR}" log --pretty='format:%H' "${TRAVIS_COMMIT_RANGE:-}"); do if ! testExtensionsFromMessage "$COMMIT_HASH"; then TESTS_RESULTS=1 fi if test $STOP_NEXT_COMMITS -eq 1; then break fi done if test ${TESTS_RESULTS} -ne 0; then exit ${TESTS_RESULTS} fi if test -z "${ADDED_EXTENSION_LINE}"; then echo 'No new extensions detected.' fi