erplibre/install.sh
Mathieu Benoit aa3f99e746 [IMP] install.sh: ask y/N before installing the tooling venv
On a system too old to read TODO, install.sh ran the install without asking,
and the install DELETES an existing .venv.erplibre. It now runs only on a yes
typed in a terminal: o, oui, y or yes, any case. Enter alone means no, and
with no terminal no question is asked and nothing is installed. « aucun
python3 » finally shows when the probe is silent: the || fallback never fired
behind a pipe.
Checked: 16 tests, each answer on a pseudo-terminal; install.sh run in an
isolated copy exits 1 on « n » and installs on « o ».

--- FR ---

[IMP] install.sh : demander o/N avant d'installer le venv d'outillage

Sur un système trop ancien pour lire TODO, install.sh lançait l'installation
sans rien demander, et celle-ci SUPPRIME un .venv.erplibre existant. Elle ne
part plus que sur un oui tapé au terminal : o, oui, y ou yes, toute casse.
Entrée seule vaut non, et sans terminal aucune question n'est posée ni
installation lancée. « aucun python3 » s'affiche enfin quand la sonde est
muette : le repli par || ne se déclenchait jamais derrière un tube.
Vérifié : 16 tests, dont chaque réponse sur un pseudo-terminal ; install.sh
lancé dans une copie isolée sort en 1 sur « n » et installe sur « o ».

Assisted-by: Claude Opus 5.5
2026-09-25 01:29:53 -04:00

94 lines
4 KiB
Bash
Executable file

#!/usr/bin/env bash
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
#
# Point d'entrée de TODO : choisir un interpréteur capable de LIRE le code
# avant de le lui donner.
#
# todo.py porte le hashbang « python3 », donc le Python du système. Celui-ci
# est libre d'être plus vieux que conf/python-erplibre-version, qui est la
# seule version que le dépôt vise : une syntaxe qu'il ne connaît pas l'arrête
# en SyntaxError au chargement, AVANT le garde de todo.py qui aurait su nommer
# le geste. Un système hors d'âge n'a alors plus aucun moyen de lancer
# l'installation qui le tirerait de là.
#
# D'où l'ordre : le venv d'outillage, qui porte la bonne version ; sinon le
# Python du système s'il est assez récent pour lire le code, et le garde de
# todo.py prend le relais ; sinon l'installation, seule issue.
cd "$(dirname "$0")" || exit 1
VENV="$(xargs < conf/python-erplibre-venv 2> /dev/null)"
VOULUE="$(xargs < conf/python-erplibre-version 2> /dev/null)"
ATTENDUE="${VOULUE%.*}"
# Majeure.mineure de l'exécutable : elle seule décide de la grammaire acceptée.
# La version est lue par du code exécuté, et non par « -V » : celui-ci répond
# avant le chargement de la bibliothèque standard, si bien qu'un interpréteur
# qui ne la trouve pas rend sa version puis meurt au premier vrai lancement.
# Rien n'est rendu quand la sortie n'a pas la forme X.Y : un interpréteur en
# panne écrit son diagnostic, et le premier mot venu passerait sinon pour un
# numéro de version que « sort -V » jugerait assez récent.
el_mineure() {
"$1" -c 'import sys; print("%d.%d" % sys.version_info[:2])' 2> /dev/null \
| awk '/^[0-9]+\.[0-9]+$/ { print; exit }'
}
# Vrai si la version lue atteint au moins celle attendue, comparée en version
# et non en chaîne : « 3.9 » est une chaîne plus grande que « 3.14 ».
el_assez_recent() {
[ -n "$1" ] && [ -n "${ATTENDUE}" ] \
&& [ "$(printf '%s\n%s\n' "${ATTENDUE}" "$1" | sort -V | head -1)" \
= "${ATTENDUE}" ]
}
# Vrai sur une réponse affirmative lue au terminal, en français ou en anglais :
# o, oui, y, yes, sans égard à la casse. Le défaut est NON : une frappe sur
# Entrée ne lance pas une installation qui peut détruire un venv. Sans
# terminal sur l'entrée, rien ne peut consentir, et la réponse est non.
el_confirmer() {
[ -t 0 ] || return 1
printf '%s [o/N] ' "$1"
read -r reponse || return 1
case "$(printf '%s' "${reponse}" | tr '[:upper:]' '[:lower:]')" in
o | oui | y | yes) return 0 ;;
*) return 1 ;;
esac
}
PYTHON_VENV="./${VENV}/bin/python"
if [ -n "${VENV}" ] && [ -x "${PYTHON_VENV}" ] \
&& el_assez_recent "$(el_mineure "${PYTHON_VENV}")"; then
exec "${PYTHON_VENV}" ./script/todo/todo.py "$@"
fi
# Un venv dont l'interpréteur ne rend pas sa version ne démarrera pas
# davantage TODO : c'est le cas d'un checkout monté depuis une autre machine,
# dont le venv cherche sa bibliothèque standard là où elle n'est pas. Le dire,
# et couper la relance de todo.py, qui sinon se remplacerait par ce python mort
# et rendrait son pavé d'initialisation au lieu d'un message.
if [ -x "${PYTHON_VENV}" ] && [ -z "$(el_mineure "${PYTHON_VENV}")" ]; then
echo "${PYTHON_VENV} ne demarre pas : ce venv a ete bati ailleurs."
echo " Rebatissez-le ici : ./script/install/install_erplibre.sh"
export EL_TODO_VENV_RELAUNCHED=1
fi
if command -v python3 > /dev/null 2>&1 \
&& el_assez_recent "$(el_mineure python3)"; then
exec ./script/todo/todo.py "$@"
fi
SYSTEME="$(el_mineure python3)"
echo "Python ${VOULUE:-du depot} est requis pour lire le code de TODO ;"
echo " ce systeme livre ${SYSTEME:-aucun python3 utilisable}."
echo " L'installation du venv d'outillage le pose :"
echo " ./script/install/install_erplibre.sh"
if [ -d "./${VENV}" ]; then
echo " ${VENV} existant sera SUPPRIME puis rebati, avec ce qui y a ete"
echo " pose a la main."
fi
if ! el_confirmer "Lancer l'installation ?"; then
echo "Installation non lancee : TODO ne demarre pas."
exit 1
fi
exec ./script/todo/source_todo.sh "$@"