Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 44 additions & 39 deletions templates/install-wp-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ WP_VERSION=${5-latest}
SKIP_DB_CREATE=${6-false}

TMPDIR=${TMPDIR-/tmp}
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
TMPDIR=$(echo "$TMPDIR" | sed -e "s/\/$//")
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
WP_TESTS_FILE="$WP_TESTS_DIR"/includes/functions.php
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress}
Expand Down Expand Up @@ -83,8 +83,10 @@ if [ "${WP_INSTALL_TESTS_SKIP_UPDATE_CHECK:-false}" != "true" ]; then
fi

if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then
WP_BRANCH=${WP_VERSION%\-*}
WP_TESTS_TAG="branches/$WP_BRANCH"
# Beta/RC versions — the stable branch (e.g. 7.1) does not exist yet on
# GitHub, so fall back to trunk for the test suite. WordPress core itself
# is still downloaded from wordpress.org which hosts beta archives.
WP_TESTS_TAG="trunk"
elif [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then
WP_TESTS_TAG="branches/$WP_VERSION"
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
Expand Down Expand Up @@ -115,32 +117,33 @@ set -ex

install_wp() {

if [ -f $WP_CORE_FILE ]; then
if [ -f "$WP_CORE_FILE" ]; then
echo -e "${CYAN}WordPress is already installed.${RESET}"
return;
return
fi

echo -e "${CYAN}Installing WordPress...${RESET}"

rm -rf $WP_CORE_DIR
mkdir -p $WP_CORE_DIR
rm -rf "$WP_CORE_DIR"
mkdir -p "$WP_CORE_DIR"

if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
download https://github.com/WordPress/wordpress/archive/refs/heads/master.tar.gz $TMPDIR/wordpress.tar.gz
tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR
download https://github.com/WordPress/wordpress/archive/refs/heads/master.tar.gz "$TMPDIR"/wordpress.tar.gz
tar --strip-components=1 -zxmf "$TMPDIR"/wordpress.tar.gz -C "$WP_CORE_DIR"
else
if [ $WP_VERSION == 'latest' ]; then
if [ "$WP_VERSION" == 'latest' ]; then
local ARCHIVE_NAME='latest'
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
# https serves multiple offers, whereas http serves single.
download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json
download https://api.wordpress.org/core/version-check/1.7/ "$TMPDIR"/wp-latest.json
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
LATEST_VERSION=${WP_VERSION%??}
else
# otherwise, scan the releases and get the most up to date minor version of the major release
local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'`
LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1)
local VERSION_ESCAPED
VERSION_ESCAPED=$(echo "$WP_VERSION" | sed 's/\./\\\\./g')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the remaining ShellCheck SC2001 warning.

Use parameter expansion for this fixed substitution instead of spawning echo and sed.

Proposed fix
-				VERSION_ESCAPED=$(echo "$WP_VERSION" | sed 's/\./\\\\./g')
+				VERSION_ESCAPED=${WP_VERSION//./\\.}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
VERSION_ESCAPED=$(echo "$WP_VERSION" | sed 's/\./\\\\./g')
VERSION_ESCAPED=${WP_VERSION//./\\.}
🧰 Tools
🪛 Shellcheck (0.11.0)

[style] 145-145: See if you can use ${variable//search/replace} instead.

(SC2001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/install-wp-tests.sh` at line 145, Update the VERSION_ESCAPED
assignment to use shell parameter expansion on WP_VERSION for replacing dots
with escaped dots, removing the echo and sed pipeline that triggers ShellCheck
SC2001. Preserve the existing escaped VERSION_ESCAPED value.

Source: Linters/SAST tools

LATEST_VERSION=$(grep -o '"version":"'"$VERSION_ESCAPED"'[^"]*' "$TMPDIR"/wp-latest.json | sed 's/"version":"//' | head -1)
fi
if [[ -z "$LATEST_VERSION" ]]; then
local ARCHIVE_NAME="wordpress-$WP_VERSION"
Expand All @@ -150,8 +153,8 @@ install_wp() {
else
local ARCHIVE_NAME="wordpress-$WP_VERSION"
fi
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz
tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR
download https://wordpress.org/"${ARCHIVE_NAME}".tar.gz "$TMPDIR"/wordpress.tar.gz
tar --strip-components=1 -zxmf "$TMPDIR"/wordpress.tar.gz -C "$WP_CORE_DIR"
fi
echo -e "${GREEN}WordPress installed successfully.${RESET}"
}
Expand All @@ -165,11 +168,11 @@ install_test_suite() {
fi

# set up testing suite if it doesn't yet exist or only partially exists
if [ ! -f $WP_TESTS_FILE ]; then
if [ ! -f "$WP_TESTS_FILE" ]; then
echo -e "${CYAN}Installing test suite...${RESET}"
# set up testing suite
rm -rf $WP_TESTS_DIR
mkdir -p $WP_TESTS_DIR
rm -rf "$WP_TESTS_DIR"
mkdir -p "$WP_TESTS_DIR"

if [[ $WP_TESTS_TAG == 'trunk' ]]; then
ref=trunk
Expand Down Expand Up @@ -225,17 +228,18 @@ install_test_suite() {
exit 1
fi

download https://raw.githubusercontent.com/WordPress/wordpress-develop/${ref}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
download "https://raw.githubusercontent.com/WordPress/wordpress-develop/${ref}/wp-tests-config-sample.php" "$WP_TESTS_DIR"/wp-tests-config.php
# remove all forward slashes in the end
WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
# Strip trailing slashes
WP_CORE_DIR="${WP_CORE_DIR%/}"
# escape special sed replacement characters in $WP_CORE_DIR (backslash, pipe, ampersand)
WP_CORE_DIR_ESCAPED=$(printf '%s' "$WP_CORE_DIR" | sed 's/[\\|&]/\\&/g')
sed $ioption "s|dirname( __FILE__ ) . '/src/'|'${WP_CORE_DIR_ESCAPED}/'|" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s|__DIR__ . '/src/'|'${WP_CORE_DIR_ESCAPED}/'|" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
sed "$ioption" "s|dirname( __FILE__ ) . '/src/'|'${WP_CORE_DIR_ESCAPED}/'|" "$WP_TESTS_DIR"/wp-tests-config.php
sed "$ioption" "s|__DIR__ . '/src/'|'${WP_CORE_DIR_ESCAPED}/'|" "$WP_TESTS_DIR"/wp-tests-config.php
sed "$ioption" "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
sed "$ioption" "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
sed "$ioption" "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
sed "$ioption" "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
Comment on lines +239 to +242

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Escape database values for sed replacement syntax.

Quoted expansions only protect the shell; DB_NAME, DB_USER, DB_PASS, and DB_HOST can still alter the sed replacement when they contain &, a delimiter, or \. Escape these values like WP_CORE_DIR_ESCAPED and use one delimiter consistently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/install-wp-tests.sh` around lines 239 - 242, Update the sed
substitutions in the install configuration flow to escape DB_NAME, DB_USER,
DB_PASS, and DB_HOST for replacement syntax, following the existing
WP_CORE_DIR_ESCAPED pattern. Use one consistent sed delimiter across all
substitutions so values containing &, the delimiter, or backslashes are inserted
literally.

echo -e "${GREEN}Test suite configured.${RESET}"
else
echo -e "${CYAN}Test suite is already configured.${RESET}"
Expand All @@ -249,9 +253,9 @@ recreate_db() {
then
echo -e "${CYAN}Recreating the database ($DB_NAME)...${RESET}"
if command -v mariadb-admin > /dev/null 2>&1; then
mariadb-admin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA
mariadb-admin drop "$DB_NAME" -f --user="$DB_USER" --password="$DB_PASS""$EXTRA"
else
mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA
mysqladmin drop "$DB_NAME" -f --user="$DB_USER" --password="$DB_PASS""$EXTRA"
fi
create_db
echo -e "${GREEN}Database ($DB_NAME) recreated.${RESET}"
Expand All @@ -263,31 +267,32 @@ recreate_db() {

create_db() {
if command -v mariadb-admin > /dev/null 2>&1; then
mariadb-admin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
mariadb-admin create "$DB_NAME" --user="$DB_USER" --password="$DB_PASS""$EXTRA"
else
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
mysqladmin create "$DB_NAME" --user="$DB_USER" --password="$DB_PASS""$EXTRA"
fi
}

install_db() {

if [ ${SKIP_DB_CREATE} = "true" ]; then
if [ "${SKIP_DB_CREATE}" = "true" ]; then
echo -e "${YELLOW}Skipping database creation.${RESET}"
return 0
fi

# parse DB_HOST for port or socket references
local PARTS=(${DB_HOST//\:/ })
local PARTS
read -ra PARTS <<< "${DB_HOST//:/ }"
local DB_HOSTNAME=${PARTS[0]};
local DB_SOCK_OR_PORT=${PARTS[1]};
local EXTRA=""

if ! [ -z $DB_HOSTNAME ] ; then
if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
if [ -n "$DB_HOSTNAME" ] ; then
if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]]; then
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
elif [ -n "$DB_SOCK_OR_PORT" ] ; then
EXTRA=" --socket=$DB_SOCK_OR_PORT"
elif ! [ -z $DB_HOSTNAME ] ; then
elif [ -n "$DB_HOSTNAME" ] ; then
Comment on lines 283 to +295

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve bracketed IPv6 database hosts.

Replacing every colon breaks valid values such as [::1]:3306: DB_HOSTNAME becomes [ and the next fragment is incorrectly used as a socket. Parse bracketed IPv6 hosts before handling the hostname-and-port/socket form.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/install-wp-tests.sh` around lines 283 - 295, Update the DB_HOST
parsing logic before the existing PARTS-based hostname/port handling to
recognize bracketed IPv6 values such as [::1]:3306, preserving the full IPv6
hostname and extracting only the trailing port or socket. Keep the current
hostname-and-port/socket behavior unchanged for non-bracketed DB_HOST values,
using DB_HOSTNAME and DB_SOCK_OR_PORT for the subsequent EXTRA construction.

EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
Comment on lines 288 to 296

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Pass database connection options as an argument array.

Quoting "$EXTRA" while adjoining it to --password="$DB_PASS" creates one argument, e.g. --password=secret --host=localhost; authentication fails whenever EXTRA is populated. Use a Bash array instead of an option string.

  • templates/install-wp-tests.sh#L288-L296: build EXTRA with local -a EXTRA=() and append each option separately.
  • templates/install-wp-tests.sh#L256-L258: pass "${EXTRA[@]}" after --password="$DB_PASS".
  • templates/install-wp-tests.sh#L270-L272: pass "${EXTRA[@]}" after --password="$DB_PASS".
  • templates/install-wp-tests.sh#L306-L306: pass "${EXTRA[@]}" after --password="$DB_PASS".
📍 Affects 1 file
  • templates/install-wp-tests.sh#L288-L296 (this comment)
  • templates/install-wp-tests.sh#L256-L258
  • templates/install-wp-tests.sh#L270-L272
  • templates/install-wp-tests.sh#L306-L306
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/install-wp-tests.sh` around lines 288 - 296, Replace the EXTRA
option string in templates/install-wp-tests.sh:288-296 with a Bash array and
append each host, port, protocol, or socket option as separate elements. Update
the command invocations at templates/install-wp-tests.sh:256-258, 270-272, and
306-306 to pass "${EXTRA[@]}" after --password="$DB_PASS", preserving correct
argument boundaries at every site.

fi
fi
Expand All @@ -298,11 +303,11 @@ install_db() {
else
local DB_CLIENT='mysql'
fi
if $DB_CLIENT --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute='show databases;' | grep -q "^$DB_NAME$";
if $DB_CLIENT --user="$DB_USER" --password="$DB_PASS""$EXTRA" --execute='show databases;' | grep -q "^$DB_NAME$";
then
echo -e "${YELLOW}Reinstalling will delete the existing test database ($DB_NAME)${RESET}"
read -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB
recreate_db $DELETE_EXISTING_DB
read -r -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB
recreate_db "$DELETE_EXISTING_DB"
else
echo -e "${CYAN}Creating database ($DB_NAME)...${RESET}"
create_db
Expand Down
Loading