erplibre/script/install/lib_pip_provider.sh

71 lines
2.9 KiB
Bash
Raw Normal View History

[ADD] install: uv to place Python packages, pip as fallback uv replaces pip where it can: the tools venv and the Poetry bootstrap. The choice lives in EL_PIP_PROVIDER -- auto, uv or pip -- and in a single file, lib_pip_provider.sh, on the exact model of the mise/pyenv switch. A uv failure falls back to pip: it is stricter on metadata and rejects packages pip accepts. Three guards. The target always goes through "--python" rather than being inferred from the active venv: poetry.toml declares a "./.venv" uv would also look for. Python 3.7, still used by Odoo 12 and 13, stays on pip. And "uv pip sync" is never used: it would delete pip itself and everything Poetry laid down. One bug falls along the way: the idempotence guard aimed at .venv.erplibre/bin/poetry while Poetry installs into the Odoo venv, so a successful replay reported failure all the same. --- FR --- uv remplace pip là où il le peut : le venv d'outils et l'amorçage de Poetry. Le choix vit dans EL_PIP_PROVIDER — auto, uv ou pip — et dans un seul fichier, lib_pip_provider.sh, sur le modèle exact de l'aiguillage mise/pyenv. Un échec d'uv retombe sur pip : il est plus strict sur les métadonnées et refuse des paquets que pip accepte. Trois gardes. La cible passe toujours par « --python » plutôt que d'être déduite du venv actif : poetry.toml déclare un « ./.venv » qu'uv chercherait aussi. Python 3.7, encore utilisé par Odoo 12 et 13, reste sur pip. Et « uv pip sync » n'est jamais employé : il supprimerait pip lui-même et tout ce que Poetry a posé. Un défaut tombe au passage : le garde d'idempotence visait .venv.erplibre/bin/poetry alors que Poetry s'installe dans le venv Odoo, si bien qu'un rejeu réussi rapportait quand même un échec. Assisted-by: Claude Opus 5
2026-08-11 23:16:26 -04:00
#!/usr/bin/env bash
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
#
# Bibliothèque SOURÇABLE : installer des paquets Python dans un venv donné.
#
# Seul endroit du dépôt qui décide COMMENT les paquets sont posés. Deux
# fournisseurs, même contrat de sortie :
# pip historique, toujours présent dans un venv.
# uv nettement plus rapide sur la résolution, le téléchargement et la
# pose ; il met aussi en cache les roues qu'il CONSTRUIT, ce qui
# compte là où rien n'a de roue publiée.
#
# EL_PIP_PROVIDER choisit : auto (défaut), uv, ou pip.
#
# CE QUE ÇA NE FAIT PAS — et il faut le savoir avant d'en attendre trop :
# « poetry install --no-root » n'est PAS concerné. uv ne lit pas poetry.lock
# (astral-sh/uv#1804, fermé « not planned ») et Poetry 2.1.3 n'a plus la
# commande « export ». Or c'est cette étape qui domine : 354 paquets contre
# 153 pour le venv d'outils. Le gain porte donc sur le venv d'outils et
# l'amorçage de Poetry, pas sur le gros morceau.
#
# Et sur s390x il est quasi nul : une trentaine de paquets binaires n'ont
# aucune roue (numpy, pandas, pillow, lxml, pymupdf…) et se COMPILENT. uv
# n'enlève pas une seconde de gcc ; il parallélise seulement entre paquets.
# uv ne supporte pas officiellement Python 3.7, encore utilisé par Odoo 12
# et 13. En dessous de ce seuil on reste sur pip, sans discuter.
EL_UV_MIN_PY_MINOR=8
el_uv_usable() {
# $1 = interpréteur du venv visé.
local py="$1" minor
command -v uv > /dev/null 2>&1 || return 1
[ -x "${py}" ] || return 1
minor="$("${py}" -c 'import sys;print(sys.version_info[1])' 2> /dev/null)"
[ -n "${minor}" ] || return 1
[ "${minor}" -ge "${EL_UV_MIN_PY_MINOR}" ] 2> /dev/null || return 1
}
# API publique : installe dans le venv `$1`, avec les arguments qui suivent.
#
# La CIBLE est toujours explicite, jamais déduite de l'environnement. uv
# cherche sinon un « .venv » dans le répertoire courant ou un parent, et
# poetry.toml en déclare justement un — le dépôt porte déjà la trace de cette
# confusion, des dépendances du pyproject Odoo s'étant retrouvées dans
# .venv.erplibre. « --python » ferme la question.
#
# « uv pip sync » n'est jamais utilisé : il SUPPRIME ce qui n'est pas dans le
# fichier d'entrée, donc pip lui-même et tout ce que Poetry a posé.
el_pip_install() {
local venv="$1"
shift
local py="${venv}/bin/python"
local provider="${EL_PIP_PROVIDER:-auto}"
if [ "${provider}" != "pip" ] && el_uv_usable "${py}"; then
echo " installation par uv ($(uv --version 2>&1 | head -1))"
if uv pip install --python "${py}" "$@"; then
return 0
fi
if [ "${provider}" = "uv" ]; then
return 1
fi
# uv est plus strict que pip sur les métadonnées : il refuse des paquets
# que pip accepte. Le repli n'est donc pas théorique.
echo " uv a echoue : reprise avec pip." >&2
fi
"${py}" -m pip install "$@"
}