diff --git a/Makefile b/Makefile index 7a4992e..51b7256 100644 --- a/Makefile +++ b/Makefile @@ -208,34 +208,25 @@ format_all: # et chaque version d'Odoo n'en rapatrie qu'une partie. Voir format_addons.sh. .PHONY: format_code_generator format_code_generator: - .venv.erplibre/bin/isort --profile black -l 79 ./addons/TechnoLibre_odoo-code-generator/ - ./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator/ - ./script/maintenance/prettier_xml.sh ./addons/TechnoLibre_odoo-code-generator/ + ./script/maintenance/format_addons.sh --xml TechnoLibre_odoo-code-generator .PHONY: format_erplibre_addons format_erplibre_addons: - .venv.erplibre/bin/isort --profile black -l 79 ./addons/ERPLibre_erplibre_addons/ - ./script/maintenance/black.sh ./addons/ERPLibre_erplibre_addons/ - ./script/maintenance/prettier_xml.sh ./addons/ERPLibre_erplibre_addons/ - .venv.erplibre/bin/isort --profile black -l 79 ./addons/ERPLibre_erplibre_theme_addons/ - ./script/maintenance/black.sh ./addons/ERPLibre_erplibre_theme_addons/ - #./script/maintenance/prettier_xml.sh ./addons/ERPLibre_erplibre_theme_addons/ + ./script/maintenance/format_addons.sh --xml ERPLibre_erplibre_addons + ./script/maintenance/format_addons.sh ERPLibre_erplibre_theme_addons .PHONY: format_supported_addons format_supported_addons: - .venv.erplibre/bin/isort --profile black -l 79 ./addons/MathBenTech_erplibre-family-management/ - ./script/maintenance/black.sh ./addons/MathBenTech_erplibre-family-management/ - #./script/maintenance/prettier_xml.sh ./addons/MathBenTech_erplibre-family-management/ - .venv.erplibre/bin/isort --profile black -l 79 ./addons/MathBenTech_odoo-business-spending-management-quebec-canada/ - ./script/maintenance/black.sh ./addons/MathBenTech_odoo-business-spending-management-quebec-canada/ - #./script/maintenance/prettier_xml.sh ./addons/MathBenTech_erplibre-family-management/ + ./script/maintenance/format_addons.sh MathBenTech_erplibre-family-management \ + MathBenTech_odoo-business-spending-management-quebec-canada .PHONY: format_code_generator_template format_code_generator_template: - .venv.erplibre/bin/isort --profile black -l 79 ./addons/TechnoLibre_odoo-code-generator-template/ - ./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator-template/ - #./script/maintenance/prettier_xml.sh ./addons/TechnoLibre_odoo-code-generator-template/ + ./script/maintenance/format_addons.sh TechnoLibre_odoo-code-generator-template +# L'outillage passe par ruff, réglé une fois dans .ruff.toml, qui écarte les +# dépôts rapatriés sous script/. Les addons gardent black : voir +# script/maintenance/format_python.sh. .PHONY: format_script format_script: .venv.erplibre/bin/ruff check --select I --fix ./script/ diff --git a/conf/ruff.addons.toml b/conf/ruff.addons.toml new file mode 100644 index 0000000..44fc8d7 --- /dev/null +++ b/conf/ruff.addons.toml @@ -0,0 +1,53 @@ +# Norme OCA pour les MODULES ODOO, calquée sur le gabarit +# oca-addons-repo-template — celui que porte tout dépôt d'addons de la +# communauté, et qu'on lit dans odoo18.0/OCA_OpenUpgrade/.ruff.toml. +# +# OCA a quitté black : ruff-format formate, et ruff remplace d'un coup isort, +# flake8 et pyupgrade. L'outillage d'ERPLibre suit sa propre norme, plus +# étroite — voir .ruff.toml à la racine, et format_python.sh qui aiguille. +# +# Un dépôt d'addons qui porte SON PROPRE .ruff.toml gagne sur ce fichier : +# format_addons.sh le laisse décider chez lui. + +# La série Odoo décide, comme chez OCA, qui fixe une cible par branche. Cette +# valeur n'est qu'un repli : format_addons.sh passe celle de +# .python-odoo-version, la seule qui dise ce qui EXÉCUTE ces modules. +target-version = "py310" +# 88, la largeur d'OCA, et non les 79 de l'outillage. +line-length = 88 + +[lint] +extend-select = [ + "B", # bugbear + "C90", # complexité + "E501", # ligne trop longue + "I", # tri des imports + "UP", # pyupgrade +] + +[lint.per-file-ignores] +# Un __init__.py d'addon liste ses modules : ni inutilisés, ni à trier. +"__init__.py" = ["F401", "I001"] +# Un manifeste est un dictionnaire nu, que bugbear prend pour une expression +# sans effet. +"__manifest__.py" = ["B018"] + +[lint.isort] +# Ce qu'isort ne sait pas faire : « odoo » et « odoo.addons » sont deux +# sections à elles seules, avant le code du module. +section-order = [ + "future", + "standard-library", + "third-party", + "odoo", + "odoo-addons", + "first-party", + "local-folder", +] + +[lint.isort.sections] +"odoo" = ["odoo"] +"odoo-addons" = ["odoo.addons"] + +[lint.mccabe] +max-complexity = 16 diff --git a/script/maintenance/format_addons.sh b/script/maintenance/format_addons.sh new file mode 100755 index 0000000..0962ace --- /dev/null +++ b/script/maintenance/format_addons.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# © 2021-2026 TechnoLibre (http://www.technolibre.ca) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +# +# Formate un dépôt d'addons NOMMÉ, où qu'il soit rapatrié, et se tait s'il +# n'est pas là. +# +# Le chemin dépend du manifeste : la production range les addons sous +# « odoo/addons/ », le manifeste de développement sous « addons/ ». +# Les cibles du Makefile ne connaissaient que la seconde forme, si bien +# qu'elles lançaient isort sur un chemin inexistant — une trace Python, et +# « make format_all » qui échoue sans avoir rien formaté. +# +# Un dépôt absent n'est pas une erreur : chaque version d'Odoo n'en rapatrie +# qu'une partie. On le dit, et on passe au suivant. +# +# Le formateur est celui de la communauté : ruff, réglé par +# conf/ruff.addons.toml, qui reprend le gabarit oca-addons-repo-template. +# +# format_addons.sh [--xml] ... +# --xml passe aussi prettier sur les vues, quand le dépôt s'y prête + +AVEC_XML=0 +if [[ "$1" == "--xml" ]]; then + AVEC_XML=1 + shift +fi + +VENV="$(xargs < conf/python-erplibre-venv 2> /dev/null)" +ODOO="$(xargs < .odoo-version 2> /dev/null)" + +# La cible de syntaxe suit la SÉRIE, comme chez OCA, qui en fixe une par +# branche : ici celle d'Odoo, lue dans .python-odoo-version. La figer +# rejetterait le code qu'une série récente autorise — Odoo 18 tourne en 3.12, +# où une f-string accepte un backslash que 3.10 refuse. +PY_ODOO="$(xargs < .python-odoo-version 2> /dev/null)" +CIBLE=() +if [[ "${PY_ODOO}" =~ ^([0-9]+)\.([0-9]+) ]]; then + CIBLE=(--target-version "py${BASH_REMATCH[1]}${BASH_REMATCH[2]}") +fi + +for nom in "$@"; do + chemin="" + for candidat in "odoo${ODOO}/addons/${nom}" "addons/${nom}"; do + if [[ -n "${ODOO}" || "${candidat}" == addons/* ]] \ + && [[ -d "${candidat}" ]]; then + chemin="${candidat}" + break + fi + done + if [[ -z "${chemin}" ]]; then + echo "${nom} : absent de ce checkout, ignore." + continue + fi + echo "---- ${chemin} ----" + # La norme du dépôt s'il en porte une — c'est ainsi qu'OCA la distribue —, + # sinon celle du gabarit OCA que ce dépôt-ci conserve. + if [[ -f "${chemin}/.ruff.toml" ]] || [[ -f "${chemin}/pyproject.toml" ]]; then + config=() + else + config=(--config conf/ruff.addons.toml) + fi + # Le tri des imports SEUL : « --select I » remplace la sélection du + # fichier de configuration, dont le lint complet relève d'un autre chantier + # — il rend des centaines d'avertissements, et ses correctifs touchent au + # comportement, pas à la mise en forme. + "./${VENV}/bin/ruff" check "${config[@]}" "${CIBLE[@]}" --select I --fix \ + --quiet "${chemin}/" || exit 1 + "./${VENV}/bin/ruff" format "${config[@]}" "${CIBLE[@]}" --quiet \ + "${chemin}/" || exit 1 + if [[ ${AVEC_XML} -eq 1 ]]; then + ./script/maintenance/prettier_xml.sh "${chemin}/" || exit 1 + fi +done