Files
httrack/tests/146_bash-shell.test
Xavier Roche f3fa3a8b98 configure discards a user-supplied BASH_SHELL (#907)
* configure discards a user-supplied BASH_SHELL

AS_UNSET erased the variable before AC_PATH_PROGS could honour it, so
"./configure BASH_SHELL=/path" had no effect and there was no way to
point the build at a bash other than the first one on PATH. Nothing
presets BASH_SHELL, which was the whole problem with BASH in #895, so
declaring it precious is enough.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Run the nested configure against a symlink farm

An in-tree build leaves a config.status in srcdir, and autoconf then refuses
the out-of-tree run the test needs. Every CI build leg builds in-tree, so the
check failed there while passing on an out-of-tree tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Read the resolved bash from the configure trace, not the Makefile

The nested configure ran without the flags the outer one was given, so on
macOS it died at the openssl check that Homebrew paths satisfy. BASH_SHELL
is resolved long before that, so assert on the trace and let the run fail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

* Assert the value that reaches $(BASH_SHELL), not the macro's decision

Reading the configure trace let a mutant through: resolve the override
correctly, clobber BASH_SHELL one line later, and both assertions passed
while every Makefile got the wrong shell. Prefer the generated Makefile
and keep the trace only as a fallback for a configure that dies early.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>

---------

Signed-off-by: Xavier Roche <roche@httrack.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 12:53:15 +02:00

91 lines
2.8 KiB
Bash

#!/bin/bash
#
# configure must hand the Makefiles a real bash (BASH_SHELL): "make deb" and the test
# driver both run bash scripts through it. Not searched into BASH, which bash presets to
# its own path, so on macOS -- where /bin/sh is a bash -- it reported /bin/sh (#895, #891).
#
# shellcheck disable=SC2016 # the probes are for the shell under test to expand
set -euo pipefail
sh=${BASH_SHELL:-}
test -n "$sh" || {
echo "BASH_SHELL is empty; tests/Makefile.am must export the configured value" >&2
exit 1
}
test -x "$sh" || {
echo "BASH_SHELL=$sh is not an executable file" >&2
exit 1
}
version=$("$sh" -c 'echo "${BASH_VERSION:-}"')
test -n "$version" || {
echo "BASH_SHELL=$sh sets no BASH_VERSION, so it is not a bash" >&2
exit 1
}
# sh-mode bash sets BASH_VERSION too, so the version alone proves nothing.
opts=$("$sh" -c 'echo ":${SHELLOPTS:-}:"')
case "$opts" in
*:posix:*)
echo "BASH_SHELL=$sh is a bash in POSIX sh-mode" >&2
exit 1
;;
esac
# The test helpers use process substitution, which macOS's bash-3.2-as-sh rejects.
out=$("$sh" -c 'cat <(echo procsub)' 2>&1) || {
echo "BASH_SHELL=$sh cannot run a process substitution: $out" >&2
exit 1
}
test "$out" = procsub || {
echo "expected 'procsub' from BASH_SHELL=$sh, got: $out" >&2
exit 1
}
# Whatever configure picks, an absolute BASH_SHELL from the user must win over the search.
configure="${abs_top_srcdir:-}/configure"
test -r "$configure" || {
echo "no configure script at $configure; tests/Makefile.am must export abs_top_srcdir" >&2
exit 1
}
help=$(bash "$configure" --help)
grep -q '^ *BASH_SHELL ' <<<"$help" || {
echo "configure --help does not advertise BASH_SHELL (AC_ARG_VAR missing)" >&2
exit 1
}
tmp=$(mktemp -d)
trap 'set +e; rm -rf "$tmp"' EXIT
mkdir "$tmp/src" "$tmp/bld"
ln -s "$sh" "$tmp/mybash"
# Symlink farm, not the real srcdir: an in-tree config.status makes autoconf refuse it.
for f in "$abs_top_srcdir"/*; do
case "${f##*/}" in
config.status | config.log | config.h | stamp-h1 | Makefile) continue ;;
esac
ln -s "$f" "$tmp/src/"
done
# Prefer the Makefile: it proves the value that reaches $(BASH_SHELL), not just the macro's
# decision. configure may die on a library check before writing one, so fall back to the
# trace it printed earlier.
(cd "$tmp/bld" && BASH_SHELL="$tmp/mybash" bash "$tmp/src/configure" --disable-https >conf.log 2>&1) || true
if test -f "$tmp/bld/Makefile"; then
got=$(sed -n 's/^BASH_SHELL = //p' "$tmp/bld/Makefile")
from="Makefile"
else
got=$(sed -n 's/^checking for bash\.\.\. //p' "$tmp/bld/conf.log")
got=${got#"(cached) "}
from="trace"
fi
test "$got" = "$tmp/mybash" || {
echo "configure discarded BASH_SHELL=$tmp/mybash, $from has: ${got:-<nothing>}" >&2
tail -20 "$tmp/bld/conf.log" >&2
exit 1
}
echo "configured bash is $sh ($version)"