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
70 lines
2.6 KiB
Python
Executable file
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()
|