Files
torben 5d937233b1
CI / verify (push) Successful in 5m20s
CI / pwsh (push) Successful in 1m53s
Release / release (push) Successful in 36s
fix: tools/bugreport launcher finds a Python 3.8+ itself and never starts a Store alias (#166)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2

Files changed:
- .gitea/workflows/ci.yml
- CHANGES.md
- INSTALL.md
- VERSION
- instructions/bug-report.md
- tools/README.md
- tools/bugreport
- tools/bugreport.ps1
- tools/bugreport.py
- tools/chemenu/tests/test_bugreport_launcher.py
- tools/chemenu/tests/test_instructions_shell.py
- tools/chemenu/tests/test_portability.py
2026-10-02 13:12:19 +02:00

130 lines
4.0 KiB
Bash
Executable File

#!/bin/sh
# Entry point for the bug-report collector, so agents and people start it through one
# stable path on every platform:
#
# tools/bugreport [options]
#
# This is the POSIX half - Linux, macOS and Git Bash on Windows. PowerShell resolves
# the same string to tools/bugreport.ps1 first.
#
# tools/bugreport.py is the one part of the stack that has to run when nothing else
# does, so this script assumes nothing the preflight sets up: no .wikitool-tools.json,
# no venv. It looks for a Python itself, the way the preflight does - on Windows
# python, py -3, python3; elsewhere python3, python; every match on PATH in PATH
# order - and only then tries the venv's. It never starts anything under WindowsApps:
# there, python.exe and python3.exe are the Microsoft Store's aliases, and in Git Bash
# `python3` is exactly that. Every candidate is probed first, so one that is too old or
# that the machine refuses to run (a venv python.exe blocked by Defender) is passed over
# rather than ending the report.
#
# Without any Python 3.8 or newer it says so and exits 1, never 42: the collector opens
# no gate.
#
# CHEMENU_PREFLIGHT_PLATFORM stands in for the platform, as it does for the preflight;
# the test suite is its only user.
set -u
DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P) || exit 1
MIN=3.8
# Exit 3 marks "a Python, but too old" apart from "did not start at all".
PROBE='import sys; sys.exit(0 if sys.version_info >= (3, 8) else 3)'
platform=${CHEMENU_PREFLIGHT_PLATFORM:-}
if [ -z "$platform" ]; then
case "$(uname -s 2>/dev/null)" in
MINGW*|MSYS*|CYGWIN*) platform=windows ;;
*) platform=other ;;
esac
fi
if [ "$platform" = windows ]; then
order="python: py:-3 python3:"
looked="python, py -3, python3"
else
order="python3: python:"
looked="python3, python"
fi
is_store_alias() {
case "$1" in *[Ww]indows[Aa]pps/*|*[Ww]indows[Aa]pps\\*) return 0 ;; esac
return 1
}
# Every executable called <name> on PATH, in PATH order, store aliases dropped.
on_path() {
set -f
old_ifs=$IFS
IFS=:
for d in $PATH; do
[ -n "$d" ] || d=.
for f in "$d/$1" "$d/$1.exe"; do
if [ -f "$f" ] && [ -x "$f" ] && ! is_store_alias "$f"; then
printf '%s\n' "$f"
fi
done
done
IFS=$old_ifs
set +f
}
PY="" EXTRA="" TOO_OLD=""
probe() { # <path> [extra argument, e.g. -3 for py] -> sets PY/EXTRA on success
"$@" -c "$PROBE" >/dev/null 2>&1
status=$?
if [ "$status" -eq 0 ]; then
PY=$1 EXTRA=${2:-}
return 0
fi
if [ "$status" -eq 3 ]; then
TOO_OLD="$TOO_OLD
$1"
fi
return 1
}
for candidate in $order; do
name=${candidate%%:*}
extra=${candidate#*:}
found=$(on_path "$name")
[ -n "$found" ] || continue
# A here-document, not a pipe: `break 2` has to leave the outer loop of this
# shell, and a path may contain spaces ("Program Files").
while IFS= read -r path; do
if [ -n "$extra" ]; then
probe "$path" "$extra" && break 2
else
probe "$path" && break 2
fi
done <<EOF
$found
EOF
done
if [ -z "$PY" ]; then
for venv in "$DIR/.venv/bin/python" "$DIR/.venv/Scripts/python.exe"; do
[ -f "$venv" ] && probe "$venv" && break
done
fi
if [ -n "$PY" ]; then
if [ -n "$EXTRA" ]; then
exec "$PY" "$EXTRA" "$DIR/bugreport.py" "$@"
fi
exec "$PY" "$DIR/bugreport.py" "$@"
fi
{
echo "No Python $MIN or newer could be started, so the bug-report collector did not run."
echo "Looked for $looked on PATH, then the one in tools/.venv. Microsoft Store aliases"
echo "under WindowsApps are skipped on purpose - they do not run Python."
if [ -n "$TOO_OLD" ]; then
echo "Found, but older than $MIN:$TOO_OLD"
fi
echo
echo "Install Python $MIN or newer, or start the collector directly with the full path"
echo "of one that works:"
echo
echo " <full path to python> tools/bugreport.py <the same options>"
} >&2
exit 1