[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
This commit is contained in:
parent
a8f7512130
commit
aa3f99e746
8 changed files with 129 additions and 14 deletions
|
|
@ -162,7 +162,7 @@ au [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
- `--bios` is refused on an image with no BIOS boot sector, and says why. Forced there, it gave a VM reported « running » with a silent console — the very failure that flag exists to avoid elsewhere
|
||||
- The tooling virtual environment `.venv.erplibre` runs Python 3.14.7, independently of the Odoo one (3.12.10 for Odoo 18.0). `install_erplibre.sh` builds it through `install_venv.sh` and `EL_PYTHON_PROVIDER` instead of the system `python3`
|
||||
- `.venv.erplibre` on an incompatible Python is DELETED and rebuilt; whatever was installed in it by hand goes with it. Odoo's venv is kept when it merely differs in version, and rebuilt only when it is unusable: rebuilding it redoes a whole Poetry install. A directory without `pyvenv.cfg` is never deleted
|
||||
- `make` and `make todo` run `./todo.sh`, a launcher whose name says a menu opens and not an installation; it hands every argument to `install.sh`, which picks an interpreter able to READ the code before running it: `.venv.erplibre` on the right version, else a recent enough system `python3`, else the install. A system older than `conf/python-erplibre-version` would otherwise stop on a syntax error raised before any guard could name the command to type. TODO then relaunches itself in `.venv.erplibre`, or offers to run `install_erplibre.sh` in a terminal
|
||||
- `make` and `make todo` run `./todo.sh`, a launcher whose name says a menu opens and not an installation; it hands every argument to `install.sh`, which picks an interpreter able to READ the code before running it: `.venv.erplibre` on the right version, else a recent enough system `python3`, else the install, which runs only on a yes typed in a terminal (`o`, `oui`, `y`, `yes`) since it can delete `.venv.erplibre`. A system older than `conf/python-erplibre-version` would otherwise stop on a syntax error raised before any guard could name the command to type. TODO then relaunches itself in `.venv.erplibre`, or offers to run `install_erplibre.sh` in a terminal
|
||||
- The production Docker image builds `.venv.erplibre` on Odoo's Python and stops when that Python cannot parse `script/`
|
||||
- Debian 11 is dropped from the deployment catalogue: its LTS ended, and its security suite is neither served nor archived — the index it still publishes names packages whose pool no longer holds the file, so apt stops before installing git. Debian 13 takes its place, its cloud image always being the latest point release
|
||||
- Every container image is built on bookworm, whatever the Odoo version. The base is `python:<version>-slim-<suite>`: the interpreter comes from the official image, never from Debian, and the bookworm variants exist down to 3.7.17. The wkhtmltopdf build follows the suite — bullseye's requires libssl1.1, absent from bookworm
|
||||
|
|
@ -187,7 +187,7 @@ au [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
- `--bios` est refusé sur une image sans secteur d'amorçage BIOS, et dit pourquoi. Forcé là, il donnait une VM « running » à console muette — la panne même que ce drapeau évite ailleurs
|
||||
- L'environnement virtuel d'outillage `.venv.erplibre` tourne en Python 3.14.7, indépendamment de celui d'Odoo (3.12.10 pour Odoo 18.0). `install_erplibre.sh` le bâtit par `install_venv.sh` et `EL_PYTHON_PROVIDER` plutôt qu'avec le `python3` du système
|
||||
- `.venv.erplibre` sur un Python incompatible est SUPPRIMÉ puis rebâti ; ce qu'on y avait posé à la main part avec lui. Le venv d'Odoo est conservé quand seule sa version diffère, et rebâti seulement s'il est hors service : le rebâtir refait une installation Poetry entière. Un répertoire sans `pyvenv.cfg` n'est jamais effacé
|
||||
- `make` et `make todo` lancent `./todo.sh`, dont le nom annonce un menu et non une installation ; il passe chaque argument à `install.sh`, qui choisit un interpréteur capable de LIRE le code avant de le lancer : `.venv.erplibre` s'il porte la bonne version, sinon le `python3` du système s'il est assez récent, sinon l'installation. Un système plus ancien que `conf/python-erplibre-version` s'arrêterait autrement sur une erreur de syntaxe levée avant qu'aucun garde puisse nommer la commande à taper. TODO se relance ensuite dans `.venv.erplibre`, ou propose de lancer `install_erplibre.sh` en terminal
|
||||
- `make` et `make todo` lancent `./todo.sh`, dont le nom annonce un menu et non une installation ; il passe chaque argument à `install.sh`, qui choisit un interpréteur capable de LIRE le code avant de le lancer : `.venv.erplibre` s'il porte la bonne version, sinon le `python3` du système s'il est assez récent, sinon l'installation, qui ne part que sur un oui tapé au terminal (`o`, `oui`, `y`, `yes`) puisqu'elle peut supprimer `.venv.erplibre`. Un système plus ancien que `conf/python-erplibre-version` s'arrêterait autrement sur une erreur de syntaxe levée avant qu'aucun garde puisse nommer la commande à taper. TODO se relance ensuite dans `.venv.erplibre`, ou propose de lancer `install_erplibre.sh` en terminal
|
||||
- L'image Docker de production bâtit `.venv.erplibre` sur le Python d'Odoo et s'arrête quand ce Python ne sait pas lire `script/`
|
||||
- Debian 11 quitte le catalogue de déploiement : son LTS est terminé, et sa suite de sécurité n'est ni servie ni archivée — l'index qu'elle publie encore nomme des paquets dont le pool ne porte plus le fichier, et apt s'arrête avant d'installer git. Debian 13 la remplace, son image cloud étant toujours le dernier point de version
|
||||
- Toutes les images de conteneur reposent sur bookworm, quelle que soit la version d'Odoo. La base est `python:<version>-slim-<version Debian>` : l'interpréteur vient de l'image officielle, jamais de Debian, et les variantes bookworm existent jusqu'à 3.7.17. Le build de wkhtmltopdf suit la version — celui de bullseye réclame libssl1.1, absente de bookworm
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ au [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
- `--bios` est refusé sur une image sans secteur d'amorçage BIOS, et dit pourquoi. Forcé là, il donnait une VM « running » à console muette — la panne même que ce drapeau évite ailleurs
|
||||
- L'environnement virtuel d'outillage `.venv.erplibre` tourne en Python 3.14.7, indépendamment de celui d'Odoo (3.12.10 pour Odoo 18.0). `install_erplibre.sh` le bâtit par `install_venv.sh` et `EL_PYTHON_PROVIDER` plutôt qu'avec le `python3` du système
|
||||
- `.venv.erplibre` sur un Python incompatible est SUPPRIMÉ puis rebâti ; ce qu'on y avait posé à la main part avec lui. Le venv d'Odoo est conservé quand seule sa version diffère, et rebâti seulement s'il est hors service : le rebâtir refait une installation Poetry entière. Un répertoire sans `pyvenv.cfg` n'est jamais effacé
|
||||
- `make` et `make todo` lancent `./todo.sh`, dont le nom annonce un menu et non une installation ; il passe chaque argument à `install.sh`, qui choisit un interpréteur capable de LIRE le code avant de le lancer : `.venv.erplibre` s'il porte la bonne version, sinon le `python3` du système s'il est assez récent, sinon l'installation. Un système plus ancien que `conf/python-erplibre-version` s'arrêterait autrement sur une erreur de syntaxe levée avant qu'aucun garde puisse nommer la commande à taper. TODO se relance ensuite dans `.venv.erplibre`, ou propose de lancer `install_erplibre.sh` en terminal
|
||||
- `make` et `make todo` lancent `./todo.sh`, dont le nom annonce un menu et non une installation ; il passe chaque argument à `install.sh`, qui choisit un interpréteur capable de LIRE le code avant de le lancer : `.venv.erplibre` s'il porte la bonne version, sinon le `python3` du système s'il est assez récent, sinon l'installation, qui ne part que sur un oui tapé au terminal (`o`, `oui`, `y`, `yes`) puisqu'elle peut supprimer `.venv.erplibre`. Un système plus ancien que `conf/python-erplibre-version` s'arrêterait autrement sur une erreur de syntaxe levée avant qu'aucun garde puisse nommer la commande à taper. TODO se relance ensuite dans `.venv.erplibre`, ou propose de lancer `install_erplibre.sh` en terminal
|
||||
- L'image Docker de production bâtit `.venv.erplibre` sur le Python d'Odoo et s'arrête quand ce Python ne sait pas lire `script/`
|
||||
- Debian 11 quitte le catalogue de déploiement : son LTS est terminé, et sa suite de sécurité n'est ni servie ni archivée — l'index qu'elle publie encore nomme des paquets dont le pool ne porte plus le fichier, et apt s'arrête avant d'installer git. Debian 13 la remplace, son image cloud étant toujours le dernier point de version
|
||||
- Toutes les images de conteneur reposent sur bookworm, quelle que soit la version d'Odoo. La base est `python:<version>-slim-<version Debian>` : l'interpréteur vient de l'image officielle, jamais de Debian, et les variantes bookworm existent jusqu'à 3.7.17. Le build de wkhtmltopdf suit la version — celui de bullseye réclame libssl1.1, absente de bookworm
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
- `--bios` is refused on an image with no BIOS boot sector, and says why. Forced there, it gave a VM reported « running » with a silent console — the very failure that flag exists to avoid elsewhere
|
||||
- The tooling virtual environment `.venv.erplibre` runs Python 3.14.7, independently of the Odoo one (3.12.10 for Odoo 18.0). `install_erplibre.sh` builds it through `install_venv.sh` and `EL_PYTHON_PROVIDER` instead of the system `python3`
|
||||
- `.venv.erplibre` on an incompatible Python is DELETED and rebuilt; whatever was installed in it by hand goes with it. Odoo's venv is kept when it merely differs in version, and rebuilt only when it is unusable: rebuilding it redoes a whole Poetry install. A directory without `pyvenv.cfg` is never deleted
|
||||
- `make` and `make todo` run `./todo.sh`, a launcher whose name says a menu opens and not an installation; it hands every argument to `install.sh`, which picks an interpreter able to READ the code before running it: `.venv.erplibre` on the right version, else a recent enough system `python3`, else the install. A system older than `conf/python-erplibre-version` would otherwise stop on a syntax error raised before any guard could name the command to type. TODO then relaunches itself in `.venv.erplibre`, or offers to run `install_erplibre.sh` in a terminal
|
||||
- `make` and `make todo` run `./todo.sh`, a launcher whose name says a menu opens and not an installation; it hands every argument to `install.sh`, which picks an interpreter able to READ the code before running it: `.venv.erplibre` on the right version, else a recent enough system `python3`, else the install, which runs only on a yes typed in a terminal (`o`, `oui`, `y`, `yes`) since it can delete `.venv.erplibre`. A system older than `conf/python-erplibre-version` would otherwise stop on a syntax error raised before any guard could name the command to type. TODO then relaunches itself in `.venv.erplibre`, or offers to run `install_erplibre.sh` in a terminal
|
||||
- The production Docker image builds `.venv.erplibre` on Odoo's Python and stops when that Python cannot parse `script/`
|
||||
- Debian 11 is dropped from the deployment catalogue: its LTS ended, and its security suite is neither served nor archived — the index it still publishes names packages whose pool no longer holds the file, so apt stops before installing git. Debian 13 takes its place, its cloud image always being the latest point release
|
||||
- Every container image is built on bookworm, whatever the Odoo version. The base is `python:<version>-slim-<suite>`: the interpreter comes from the official image, never from Debian, and the bookworm variants exist down to 3.7.17. The wkhtmltopdf build follows the suite — bullseye's requires libssl1.1, absent from bookworm
|
||||
|
|
|
|||
|
|
@ -257,8 +257,10 @@ make
|
|||
`make` and `./install.sh` start TODO through the interpreter that can read it:
|
||||
`.venv.erplibre` when it carries the right version, otherwise the system
|
||||
`python3` when it is recent enough, otherwise the install itself — a system
|
||||
older than `conf/python-erplibre-version` cannot parse the code, so it goes
|
||||
straight to the install rather than stopping on a syntax error. When the
|
||||
older than `conf/python-erplibre-version` cannot parse the code, so it offers
|
||||
the install rather than stopping on a syntax error. The install runs only on a
|
||||
yes typed in a terminal (`o`, `oui`, `y` or `yes`); Enter alone, or no
|
||||
terminal, means no. When the
|
||||
environment is missing but the system Python suffices, TODO offers to run
|
||||
`./script/install/install_erplibre.sh` (in a terminal) or prints that command. The install builds the environment
|
||||
through `EL_PYTHON_PROVIDER` (mise or pyenv); an existing `.venv.erplibre` on
|
||||
|
|
@ -270,8 +272,10 @@ by hand goes with it.
|
|||
`make` et `./install.sh` lancent TODO par l'interpréteur capable de le lire :
|
||||
`.venv.erplibre` quand il porte la bonne version, sinon le `python3` du système
|
||||
s'il est assez récent, sinon l'installation elle-même — un système plus ancien
|
||||
que `conf/python-erplibre-version` ne sait pas analyser le code, donc on va
|
||||
droit à l'installation plutôt que de s'arrêter sur une erreur de syntaxe. Quand
|
||||
que `conf/python-erplibre-version` ne sait pas analyser le code, donc
|
||||
l'installation est proposée plutôt que de s'arrêter sur une erreur de syntaxe.
|
||||
Elle ne part que sur un oui tapé au terminal (`o`, `oui`, `y` ou `yes`) ;
|
||||
Entrée seule, ou l'absence de terminal, vaut non. Quand
|
||||
l'environnement manque mais que le Python du système suffit, TODO propose de
|
||||
lancer `./script/install/install_erplibre.sh` (dans un terminal) ou affiche
|
||||
cette commande. L'installation bâtit l'environnement par
|
||||
|
|
|
|||
|
|
@ -129,8 +129,10 @@ make
|
|||
`make` et `./install.sh` lancent TODO par l'interpréteur capable de le lire :
|
||||
`.venv.erplibre` quand il porte la bonne version, sinon le `python3` du système
|
||||
s'il est assez récent, sinon l'installation elle-même — un système plus ancien
|
||||
que `conf/python-erplibre-version` ne sait pas analyser le code, donc on va
|
||||
droit à l'installation plutôt que de s'arrêter sur une erreur de syntaxe. Quand
|
||||
que `conf/python-erplibre-version` ne sait pas analyser le code, donc
|
||||
l'installation est proposée plutôt que de s'arrêter sur une erreur de syntaxe.
|
||||
Elle ne part que sur un oui tapé au terminal (`o`, `oui`, `y` ou `yes`) ;
|
||||
Entrée seule, ou l'absence de terminal, vaut non. Quand
|
||||
l'environnement manque mais que le Python du système suffit, TODO propose de
|
||||
lancer `./script/install/install_erplibre.sh` (dans un terminal) ou affiche
|
||||
cette commande. L'installation bâtit l'environnement par
|
||||
|
|
|
|||
|
|
@ -127,8 +127,10 @@ make
|
|||
`make` and `./install.sh` start TODO through the interpreter that can read it:
|
||||
`.venv.erplibre` when it carries the right version, otherwise the system
|
||||
`python3` when it is recent enough, otherwise the install itself — a system
|
||||
older than `conf/python-erplibre-version` cannot parse the code, so it goes
|
||||
straight to the install rather than stopping on a syntax error. When the
|
||||
older than `conf/python-erplibre-version` cannot parse the code, so it offers
|
||||
the install rather than stopping on a syntax error. The install runs only on a
|
||||
yes typed in a terminal (`o`, `oui`, `y` or `yes`); Enter alone, or no
|
||||
terminal, means no. When the
|
||||
environment is missing but the system Python suffices, TODO offers to run
|
||||
`./script/install/install_erplibre.sh` (in a terminal) or prints that command. The install builds the environment
|
||||
through `EL_PYTHON_PROVIDER` (mise or pyenv); an existing `.venv.erplibre` on
|
||||
|
|
|
|||
28
install.sh
28
install.sh
|
|
@ -42,6 +42,20 @@ el_assez_recent() {
|
|||
= "${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
|
||||
|
|
@ -64,7 +78,17 @@ if command -v python3 > /dev/null 2>&1 \
|
|||
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 $(el_mineure python3 2> /dev/null || echo 'aucun python3')."
|
||||
echo " Installation du venv d'outillage, qui le pose :"
|
||||
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 "$@"
|
||||
|
|
|
|||
83
test/test_install_sh_confirm.py
Normal file
83
test/test_install_sh_confirm.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
# © 2026 TechnoLibre (http://www.technolibre.ca)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
||||
|
||||
"""La question qu'install.sh pose avant l'installation du venv d'outillage.
|
||||
|
||||
L'installation peut SUPPRIMER un .venv.erplibre existant : elle ne part que
|
||||
sur un oui explicite. La réponse se donne en français ou en anglais (o, oui,
|
||||
y, yes, toute casse) ; Entrée seule vaut non. Sans terminal sur l'entrée,
|
||||
personne ne peut consentir, et la réponse est non sans question posée.
|
||||
"""
|
||||
|
||||
import os
|
||||
import select
|
||||
import subprocess
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
RACINE = Path(__file__).resolve().parent.parent
|
||||
SCRIPT = (
|
||||
"source <(sed -n '/^el_confirmer()/,/^}/p' install.sh); "
|
||||
'el_confirmer "Lancer ?"'
|
||||
)
|
||||
|
||||
|
||||
def repondre_au_terminal(reponse):
|
||||
"""Lance el_confirmer sur un pseudo-terminal, y tape la réponse.
|
||||
|
||||
Rend le code de sortie et ce que le terminal a affiché.
|
||||
"""
|
||||
maitre, esclave = os.openpty()
|
||||
proc = subprocess.Popen(
|
||||
["bash", "-c", SCRIPT],
|
||||
cwd=RACINE,
|
||||
stdin=esclave,
|
||||
stdout=esclave,
|
||||
stderr=esclave,
|
||||
)
|
||||
os.close(esclave)
|
||||
os.write(maitre, (reponse + "\n").encode())
|
||||
code = proc.wait(timeout=10)
|
||||
lu = b""
|
||||
while select.select([maitre], [], [], 0.2)[0]:
|
||||
try:
|
||||
morceau = os.read(maitre, 4096)
|
||||
except OSError:
|
||||
break
|
||||
if not morceau:
|
||||
break
|
||||
lu += morceau
|
||||
os.close(maitre)
|
||||
return code, lu.decode(errors="replace")
|
||||
|
||||
|
||||
class TestConfirmer(unittest.TestCase):
|
||||
def test_oui_en_francais_et_en_anglais(self):
|
||||
for reponse in ("o", "O", "oui", "Oui", "y", "Y", "yes", "YES"):
|
||||
with self.subTest(reponse=reponse):
|
||||
self.assertEqual(repondre_au_terminal(reponse)[0], 0)
|
||||
|
||||
def test_entree_seule_et_non_refusent(self):
|
||||
for reponse in ("", "n", "non", "no", "ouais", "x"):
|
||||
with self.subTest(reponse=reponse):
|
||||
self.assertEqual(repondre_au_terminal(reponse)[0], 1)
|
||||
|
||||
def test_la_question_annonce_le_defaut(self):
|
||||
self.assertIn("Lancer ? [o/N]", repondre_au_terminal("n")[1])
|
||||
|
||||
def test_sans_terminal_la_reponse_est_non(self):
|
||||
proc = subprocess.run(
|
||||
["bash", "-c", SCRIPT],
|
||||
cwd=RACINE,
|
||||
input="o\n",
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
self.assertEqual(proc.returncode, 1)
|
||||
self.assertNotIn("[o/N]", proc.stdout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in a new issue