script/gpforum-system-perl
Rama main · réplica de lectura del repositorio original.
#!/bin/sh
# SPDX-FileCopyrightText: 2026 GPForum Contributors
# SPDX-License-Identifier: BSD-3-Clause
set -eu
# Historical filename retained for callers. Validate the selected runtime by
# capability and version, independent of its package manager or prefix.
# Carton, cpm and child processes all use the same interpreter.
root=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)
# The operator's language, from the command line's catalogs. A copy of this
# script without them still says what it found, in English.
if [ -r "$root/script/lib/words.sh" ]; then
# shellcheck source=script/lib/words.sh
. "$root/script/lib/words.sh"
else
words_say() {
words_text=$2
shift 2
for words_pair in "$@"; do
words_name=${words_pair%%=*}
words_text=$(printf '%s' "$words_text" | sed "s|{$words_name}|${words_pair#*=}|g")
done
printf '%s\n' "$words_text"
}
words_mark() { printf '%s\n' "$2"; }
words_fixes() { for words_fix in "$@"; do printf ' %s\n' "$words_fix"; done; }
words_summary() { :; }
fi
usage() {
cat <<'EOF'
Usage: script/gpforum-system-perl [--print | --require | --preflight [--verbose]] [--as NAME]
Find Perl 5.40 or newer for GPForum. Distribution packages, Homebrew,
perlbrew, plenv, asdf and custom builds are supported.
Selection: GPFORUM_PERL, the active perl on PATH, then common install paths.
--print print its path (the default)
--require print its path, or say why there is none and exit 1
--preflight say whether this host has it, and what to do next
(make system-perl runs this)
--verbose with --preflight, also print perl -V
--as NAME with --require, the program named before why there is none
(bin/gpforum says gpforum)
--help this text
GPFORUM_PERL names an executable path or command; an invalid override fails.
An incompatible local/ must be rebuilt for the selected Perl and architecture.
EOF
}
mode=print
verbose=0
name=gpforum-system-perl
while [ $# -gt 0 ]; do
argument=$1
shift
case "$argument" in
--as)
if [ $# -eq 0 ] || [ -z "$1" ]; then
echo "gpforum-system-perl: --as needs a name" >&2
exit 2
fi
name=$1
shift
;;
--print)
mode=print
;;
--require)
mode=require
;;
--preflight)
mode=preflight
;;
--verbose)
verbose=1
;;
--help|-h)
usage
exit 0
;;
*)
echo "gpforum-system-perl: unknown option: $argument" >&2
usage >&2
exit 2
;;
esac
done
# Choose the runtime independently of the host's OS release.
perl_fix() {
words_say system.fix_perl_runtime 'select Perl 5.40 or newer with GPFORUM_PERL=/absolute/path/to/perl or your preferred toolchain on PATH'
}
# No acceptable Perl: under --preflight, a finding with its fix and the
# count; otherwise one line on stderr for the script that asked, and the
# fix under it.
reject() {
message=$(words_say "$@")
if [ "$mode" = preflight ]; then
words_mark fail "$message"
words_fixes "$(perl_fix)"
echo
words_summary 1
exit 1
fi
echo "$name: $message" >&2
words_fixes "$(perl_fix)" >&2
exit 1
}
meets_version() {
"$1" -MConfig -e 'exit($] < 5.040 ? 1 : 0)' >/dev/null 2>&1
}
# Version-manager shims are executable scripts. Ask the Perl they launch for
# its actual executable, then pin that binary rather than a mutable shim.
canonicalize() {
executable=$("$1" -e 'print $^X' 2>/dev/null) || return 1
[ -n "$executable" ] && [ -f "$executable" ] && [ -x "$executable" ] || return 1
if command -v readlink >/dev/null 2>&1; then
resolved=$(readlink -f "$executable" 2>/dev/null || true)
if [ -n "$resolved" ] && [ -x "$resolved" ]; then
printf '%s\n' "$resolved"
return 0
fi
fi
printf '%s\n' "$executable"
}
resolve_candidate() {
active=$(command -v perl 2>/dev/null || true)
for candidate in "$active" /usr/local/bin/perl /opt/homebrew/bin/perl /usr/bin/perl; do
[ -n "$candidate" ] && [ -f "$candidate" ] && [ -x "$candidate" ] || continue
if meets_version "$candidate"; then
canonicalize "$candidate" && return 0
fi
done
# Preserve a useful version diagnostic when only an old Perl exists.
if [ -n "$active" ]; then
canonicalize "$active"
return
fi
return 1
}
if [ -n "${GPFORUM_PERL:-}" ]; then
requested=$(command -v "$GPFORUM_PERL" 2>/dev/null || true)
if [ -z "$requested" ] || [ ! -f "$requested" ] || [ ! -x "$requested" ]; then
reject system.perl_not_executable 'GPFORUM_PERL names {path}, which is not a program' "path=$GPFORUM_PERL"
fi
perl_bin=$(canonicalize "$requested") || reject system.perl_invalid 'cannot run Perl at {path}' "path=$requested"
else
perl_bin=$(resolve_candidate) || reject system.perl_missing 'no runnable Perl was found on PATH or in the common installation paths'
fi
if ! meets_version "$perl_bin"; then
version=$("$perl_bin" -e 'printf "%vd", $^V' 2>/dev/null) || reject system.perl_invalid 'cannot run Perl at {path}' "path=$perl_bin"
reject system.perl_old 'Perl {version} at {path} is older than the 5.40 GPForum needs' "version=$version" "path=$perl_bin"
fi
case "$mode" in
print)
printf '%s\n' "$perl_bin"
;;
require)
printf '%s\n' "$perl_bin"
;;
preflight)
version=$("$perl_bin" -e 'printf "%vd", $^V')
words_mark ok "$(words_say system.perl_ok 'Perl {version} at {path}' "version=$version" "path=$perl_bin")"
if [ "$verbose" -eq 1 ]; then
"$perl_bin" -V
fi
echo
words_say system.next_deps 'Next: make install-deps-postgres, or sudo make install-deps-production on a server'
;;
esac