[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
This commit is contained in:
parent
e4aea8b8a6
commit
e20d8d9baa
5 changed files with 166 additions and 23 deletions
|
|
@ -24,3 +24,16 @@ compile.
|
|||
Un seul fichier décide : `script/install/lib_python_provider.sh`. mise n'est
|
||||
jamais installé automatiquement — `make install_mise` porte cette décision.
|
||||
Pas de binaire mise pour s390x à ce jour : cette architecture reste sur pyenv.
|
||||
|
||||
## Paquets Python
|
||||
|
||||
`EL_PIP_PROVIDER` (dans `env_var.sh`) vaut `auto`, `uv` ou `pip`. `auto` prend
|
||||
uv s'il est présent et si le venv visé est en Python ≥ 3.8, sinon pip ; un
|
||||
échec d'uv retombe sur pip. Un seul fichier décide :
|
||||
`script/install/lib_pip_provider.sh`. uv n'est jamais installé
|
||||
automatiquement — `make install_uv` porte cette décision.
|
||||
|
||||
Portée réelle : le venv d'outils et l'amorçage de Poetry. **`poetry install`
|
||||
n'est pas concerné** — uv ne lit pas `poetry.lock` — et c'est pourtant l'étape
|
||||
qui domine. Sur s390x le gain est quasi nul : une trentaine de paquets sans
|
||||
roue se compilent, et uv n'enlève pas une seconde de gcc.
|
||||
|
|
|
|||
19
Makefile
19
Makefile
|
|
@ -105,6 +105,25 @@ pyenv_update:
|
|||
#
|
||||
# Pas de binaire s390x publie a ce jour : sur cette architecture, la cible
|
||||
# le dit et n'installe rien.
|
||||
# uv installe les paquets Python nettement plus vite que pip, et met en cache
|
||||
# les roues qu'il CONSTRUIT — ce qui compte la ou rien n'a de roue publiee.
|
||||
# Contrairement a mise, uv publie une roue s390x : un « pip install uv » dans
|
||||
# le venv d'outils suffit, sans « curl | sh ». Reste EXPLICITE quand meme,
|
||||
# comme install_mise : EL_PIP_PROVIDER=auto s'en sert des qu'il est la.
|
||||
#
|
||||
# Attention a l'attente : « poetry install », qui domine le temps
|
||||
# d'installation, n'est PAS accelere — uv ne lit pas poetry.lock.
|
||||
.PHONY: install_uv
|
||||
install_uv:
|
||||
@if command -v uv >/dev/null 2>&1; then \
|
||||
echo "uv deja present : $$(uv --version)"; \
|
||||
else \
|
||||
echo "Installation de uv dans le venv d outils"; \
|
||||
./$$(cat conf/python-erplibre-venv | xargs)/bin/pip install uv; \
|
||||
echo "uv : ./$$(cat conf/python-erplibre-venv | xargs)/bin/uv"; \
|
||||
echo "Ajoutez ce repertoire au PATH, ou installez uv globalement."; \
|
||||
fi
|
||||
|
||||
.PHONY: install_mise
|
||||
install_mise:
|
||||
@if command -v mise >/dev/null 2>&1; then \
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@ EL_ERPLIBRE_VERSION=$(cat ".erplibre-version" | xargs)
|
|||
# precompile, quelques secondes), sinon pyenv (compilation). Voir
|
||||
# script/install/lib_python_provider.sh.
|
||||
EL_PYTHON_PROVIDER="${EL_PYTHON_PROVIDER:-auto}"
|
||||
# Installateur de paquets Python : auto | uv | pip.
|
||||
# « auto » prend uv s'il est present et si le venv vise est en Python >= 3.8,
|
||||
# sinon pip ; un echec d'uv retombe sur pip. Voir
|
||||
# script/install/lib_pip_provider.sh. Note : « poetry install » n'est PAS
|
||||
# concerne, uv ne lit pas poetry.lock.
|
||||
EL_PIP_PROVIDER="${EL_PIP_PROVIDER:-auto}"
|
||||
# The default port where this Odoo instance will run under (provided you use the command -c in the terminal)
|
||||
# Set to true if you want to install it, false if you don't need it or have it already installed.
|
||||
EL_INSTALL_WKHTMLTOPDF="True"
|
||||
|
|
|
|||
|
|
@ -19,15 +19,27 @@ Color_Off='\033[0m' # Text Reset
|
|||
PYTHON_VERSION_MAJOR=$(echo "$EL_PYTHON_ODOO_VERSION" | sed 's/\.[^\.]*$//')
|
||||
VENV_ERPLIBRE_PATH=$(cat "conf/python-erplibre-venv" | xargs)
|
||||
VENV_ODOO_PATH=".venv.${EL_ERPLIBRE_VERSION}"
|
||||
POETRY_ODOO_PATH=${VENV_ERPLIBRE_PATH}/bin/poetry
|
||||
# Poetry est installé dans le venv ODOO, pas dans celui des outils : le garde
|
||||
# d'idempotence visait le mauvais chemin, donc il était TOUJOURS vrai. Sans
|
||||
# conséquence visible — poetry se réinstallait pour rien — mais le jour où ce
|
||||
# fichier aurait existé, « poetry install » aurait été purement sauté.
|
||||
POETRY_ODOO_PATH=${VENV_ODOO_PATH}/bin/poetry
|
||||
|
||||
# Choix pip/uv : un seul endroit décide, comme pour mise/pyenv.
|
||||
# shellcheck source=script/install/lib_pip_provider.sh
|
||||
. ./script/install/lib_pip_provider.sh
|
||||
export WITH_POETRY_INSTALLATION=1
|
||||
|
||||
# Verbosité de l'installation Poetry : silencieuse (-q) par défaut, les logs
|
||||
# détaillés (-vvv) reviennent avec la variable d'environnement EL_VERBOSE=1.
|
||||
# Verbosité de l'installation Poetry. « -q » a été retiré du défaut : dans Cleo,
|
||||
# le mode silencieux coupe AUSSI la sortie d'erreur. Mesuré — « poetry -q
|
||||
# commande-inexistante » rend 1 sans imprimer un caractère, quand la même sans
|
||||
# « -q » nomme le problème. Un échec devenait donc parfaitement muet, et c'est
|
||||
# pour cela qu'il avait fallu ajouter un rejeu de diagnostic plus bas.
|
||||
# La verbosité par défaut de Poetry tient en une ligne par paquet.
|
||||
if [[ "${EL_VERBOSE:-0}" == "1" ]]; then
|
||||
POETRY_VERBOSE="-vvv"
|
||||
else
|
||||
POETRY_VERBOSE="-q"
|
||||
POETRY_VERBOSE=""
|
||||
fi
|
||||
|
||||
# EL_PHASE controls which steps to execute. Used by install_locally_dev.sh
|
||||
|
|
@ -72,7 +84,8 @@ if [[ "${EL_PHASE}" != "poetry" ]]; then
|
|||
source ./${VENV_ERPLIBRE_PATH}/bin/activate
|
||||
echo -e "Upgrade pip to ${VENV_ERPLIBRE_PATH}"
|
||||
pip install --upgrade pip
|
||||
pip install -r requirement/erplibre_require-ments.txt
|
||||
el_pip_install "${VENV_ERPLIBRE_PATH}" \
|
||||
-r requirement/erplibre_require-ments.txt
|
||||
|
||||
./script/install/install_git_repo.sh
|
||||
fi
|
||||
|
|
@ -121,28 +134,50 @@ if [[ "${EL_PHASE}" != "setup" ]]; then
|
|||
esac
|
||||
fi
|
||||
|
||||
# Delete artifacts created by pip, cause error in next "poetry install"
|
||||
if [[ ! -f "${POETRY_ODOO_PATH}" ]]; then
|
||||
# Le garde ne couvre QUE l'amorçage de Poetry. « poetry install » doit
|
||||
# rejouer à chaque fois : c'est lui qui applique un lock régénéré par
|
||||
# « make poetry_update ». L'englober rendrait la mise à jour sans effet
|
||||
# dès la seconde installation.
|
||||
if [[ ! -x "${POETRY_ODOO_PATH}" ]]; then
|
||||
echo -e "Install Poetry ${POETRY_ODOO_PATH}"
|
||||
pip install ${PIP_CONSTRAINT_CRYPTO} poetry==${EL_POETRY_VERSION}
|
||||
poetry --version
|
||||
# Fix broken poetry by installing ignored dependence
|
||||
# poetry lock --no-update
|
||||
# To fix keyring problem when installation is blocked, use
|
||||
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
|
||||
if [[ ${WITH_POETRY_INSTALLATION} -ne 0 ]]; then
|
||||
poetry install --no-root ${POETRY_VERBOSE}
|
||||
fi
|
||||
el_pip_install "${VENV_ODOO_PATH}" \
|
||||
${PIP_CONSTRAINT_CRYPTO} "poetry==${EL_POETRY_VERSION}"
|
||||
fi
|
||||
# Chemin EXPLICITE, jamais le « poetry » du PATH. Le script active pourtant
|
||||
# le bon venv juste avant, mais poetry.toml porte « virtualenvs.create =
|
||||
# false » : hors activation, Poetry installe dans l'interpréteur de BASE.
|
||||
# Vérifié à la dure sur une VM — 772 paquets posés dans le CPython de mise,
|
||||
# invisibles du venv qui a « include-system-site-packages = false », et
|
||||
# promis à polluer tout autre venv bâti sur le même interpréteur.
|
||||
if [[ ! -x "${POETRY_ODOO_PATH}" ]]; then
|
||||
echo "Poetry introuvable a ${POETRY_ODOO_PATH}, arret."
|
||||
exit 1
|
||||
fi
|
||||
"${POETRY_ODOO_PATH}" --version
|
||||
# To fix keyring problem when installation is blocked, use
|
||||
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
|
||||
# « poetry install » reste à Poetry : uv ne lit pas poetry.lock
|
||||
# (astral-sh/uv#1804, « not planned ») et Poetry 2.1.3 n'a plus « export ».
|
||||
if [[ ${WITH_POETRY_INSTALLATION} -ne 0 ]]; then
|
||||
"${POETRY_ODOO_PATH}" install --no-root ${POETRY_VERBOSE}
|
||||
retVal=$?
|
||||
if [[ $retVal -ne 0 ]]; then
|
||||
echo "Poetry installation error with status ${retVal}"
|
||||
# « -q » masque la CAUSE. On rejoue en « -vvv » (debug) car c'est
|
||||
# le SEUL niveau où Poetry affiche la sortie des sous-processus
|
||||
# (git clone/checkout, build pip) — donc l'erreur réelle d'une
|
||||
# dépendance VCS/build. Capturé dans le log pour diagnostic.
|
||||
echo "---- Poetry: rejeu -vvv pour diagnostic ----"
|
||||
poetry install --no-root -vvv 2>&1 || true
|
||||
exit 1
|
||||
# Un rejeu, parce qu'une partie des échecs sont des aléas de
|
||||
# téléchargement : le lock est figé, rien ne dépend de l'instant.
|
||||
# « -vvv » est le SEUL niveau où Poetry montre la sortie des
|
||||
# sous-processus (git clone, build pip), donc l'erreur réelle.
|
||||
#
|
||||
# Le « exit 1 » était INCONDITIONNEL : un rejeu réussi laissait une
|
||||
# installation complète... et la déclarait quand même en échec.
|
||||
# C'est ce qui a arrêté openSUSE Leap 16 sur un pdfminer-six posé
|
||||
# correctement au second essai.
|
||||
echo "---- Poetry: rejeu -vvv (diagnostic et seconde chance) ----"
|
||||
if "${POETRY_ODOO_PATH}" install --no-root -vvv 2>&1; then
|
||||
echo "Le rejeu a REUSSI : le premier echec etait transitoire."
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
|||
70
script/install/lib_pip_provider.sh
Executable file
70
script/install/lib_pip_provider.sh
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
#!/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 "$@"
|
||||
}
|
||||
Loading…
Reference in a new issue