erplibre/script/analyse/shell/view_file_arch.py
Mathieu Benoit 0870696701 [FIX] script: make the analysis and migration tools executable
Nine of the thirteen carried a shebang without the bit, so only four
could be run by their own path. Set to 755, not chmod +x: two were
664 under the 0002 umask and would have become 775 — executed by
others while a group member could still rewrite them. That pairing is
the only real risk here; the bit alone grants nothing, since reading
the file is enough to run python3 on it.

Being runnable opens a path without the venv: the shebang resolves to
the system python3, which has no Textual. --tui fell back to the text
report saying nothing. It now names the interpreter and the venv.

--- FR ---

[FIX] script : rendre exécutables les outils d'analyse et de migration

Neuf des treize portaient un shebang sans le bit ; quatre seulement
se lançaient par leur chemin. Mis à 755, pas chmod +x : deux étaient
en 664 sous l'umask 0002 et seraient passés à 775 — exécutés par
d'autres alors qu'un membre du groupe pouvait encore les réécrire.
C'est la seule vraie prise ici ; le bit seul n'accorde rien, lire le
fichier suffit déjà à lancer python3 dessus.

Devenir lançable ouvre un chemin sans le venv : le shebang résout le
python du système, sans Textual. --tui retombait sur le rapport texte
sans rien dire. Il nomme désormais l'interpréteur et le venv.

Assisted-by: Claude Opus 5
2026-08-22 07:23:59 -04:00

70 lines
2.6 KiB
Python
Executable file

#!/usr/bin/env python3
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
"""Arch de référence des vues, telle que le module la déclare.
Ce fichier ne se lance PAS seul : il est poussé dans l'entrée standard d'un
``odoo-bin shell``, qui lui fournit ``env``. Lancé directement, il ne trouve
aucun ``env`` et ne fait rien.
Pourquoi passer par l'ORM plutôt que relire le XML
--------------------------------------------------
La question « à quoi comparer l'arch en base » a une réponse dans le code
d'Odoo : c'est ce que fait son propre bouton « Reset view », mode ``hard`` —
``view.with_context(read_arch_from_file=True, lang=None).arch``.
Cette seule expression gère ce qu'une relecture du XML devrait réimplémenter :
localiser le fichier par ``arch_fs``, y trouver le bon nœud par identifiant
externe ou par identifiant court, suivre un ``<record>`` qui ne fait que
re-pointer, transformer un ``<template>`` en ``<t t-name>``, résoudre les
``%(xmlid)s`` en identifiants réels. Réécrire tout cela, c'est se tromper
autrement qu'Odoo.
Aucune écriture
---------------
``odoo/cli/shell.py`` fait un ``rollback`` après exécution. Le ``rollback``
final ici est une ceinture par-dessus cette bretelle ; il n'y a aucun
``commit``, et il n'y en aura pas.
"""
import json
import os
VIEW_IDS = os.environ.get("VIEW_IDS", "")
LANG = os.environ.get("ANALYSE_LANG") or None
lst_id = [int(part) for part in VIEW_IDS.split(",") if part.strip().isdigit()]
lst_out = []
if lst_id:
views = env["ir.ui.view"].with_context(active_test=False).browse(lst_id)
for view in views.exists():
try:
# lang=None demande la valeur brute, non traduite : comparer une
# arch traduite à une arch source ferait ressortir chaque terme
# traduit comme une différence.
reference = view.with_context(
read_arch_from_file=True, lang=LANG
).arch
error = None
except Exception as exc: # une vue cassée ne doit pas tuer le lot
reference, error = None, f"{type(exc).__name__}: {exc}"
try:
stored = view.with_context(lang=LANG).arch
except Exception as exc:
stored, error = None, error or f"{type(exc).__name__}: {exc}"
lst_out.append(
{
"id": view.id,
"xml_id": view.xml_id or view.key or "",
"arch_db": stored,
"arch_file": reference,
"error": error,
}
)
print("ANALYSE_JSON_BEGIN")
print(json.dumps(lst_out))
print("ANALYSE_JSON_END")
env.cr.rollback()