Ctrl K
ComunidadGuías…

script/gpforum-system-perl

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/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