[ADD] addons: uninstall a theme the way Odoo removes one
There was no counterpart to install_addons_theme.sh, so themes were
removed with a plain --uninstall. That takes out the module, not the
theme: it skips _theme_remove(), whose first act is
_reset_default_config() — the call that writes font-number and its
three neighbours into user_values.scss.
Measured on a real 12 -> 13 migration: web.assets_frontend stopped on
« Undefined variable: $o-theme-font-number ». Odoo 12 defined it in
option_font_body_*, dropped in 13.0; only the theme still redefined
it, so removing the theme exposed a frozen 2020 customization.
theme_leftover.py then reports what unloading does not take — 15
attachments on the measured database. It deletes nothing: their
content may be the only trace of a customization.
--- FR ---
[ADD] addons : désinstaller un thème comme Odoo le retire
install_addons_theme.sh n'avait pas de symétrique : on retirait donc
les thèmes par un --uninstall nu. Cela enlève le module, pas le thème
— cela saute _theme_remove(), dont le premier geste est
_reset_default_config(), l'appel qui écrit font-number et ses trois
voisines dans user_values.scss.
Mesuré sur une vraie migration 12 → 13 : web.assets_frontend s'arrête
sur « Undefined variable: $o-theme-font-number ». Odoo 12 la
définissait dans option_font_body_*, supprimés en 13.0 ; seul le thème
la redéfinissait, et le retirer a mis à nu un SCSS figé en 2020.
theme_leftover.py signale ensuite ce que le déchargement ne prend pas
— 15 pièces jointes sur la base mesurée. Il ne supprime rien : leur
contenu peut être la seule trace d'une personnalisation.
Assisted-by: Claude Opus 5
(cherry picked from commit 16a7b1e1333752e2ef603d66f47374a22590d665)
2026-08-13 05:56:06 -04:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# Désinstaller un thème comme Odoo le fait lui-même.
|
|
|
|
|
#
|
|
|
|
|
# « ./run.sh --uninstall theme_x » retire le MODULE, pas le THÈME. Choisir un
|
|
|
|
|
# thème (button_choose_theme, ce que pose --install-theme) fait DEUX choses :
|
|
|
|
|
# copier ses vues et ressources dans chaque site, et écrire dans
|
|
|
|
|
# user_values.scss une personnalisation qui DÉFINIT $o-theme-font-number et
|
|
|
|
|
# ses trois voisines. Le chemin de retrait d'Odoo, _theme_remove(), défait les
|
|
|
|
|
# deux.
|
|
|
|
|
#
|
|
|
|
|
# Le désinstaller sans lui laisse donc les copies, et surtout n'écrit jamais
|
|
|
|
|
# ces définitions. Mesuré sur une migration réelle 12 -> 13 : le bundle
|
|
|
|
|
# web.assets_frontend s'arrête sur « Undefined variable: $o-theme-font-number
|
|
|
|
|
# ». La variable venait des fichiers option_font_body_* d'Odoo 12, supprimés
|
|
|
|
|
# en 13.0 ; seul le thème la redéfinissait encore, et le retirer a mis à nu
|
|
|
|
|
# une personnalisation figée depuis des années.
|
|
|
|
|
#
|
|
|
|
|
# Usage : ./script/addons/uninstall_addons_theme.sh <base> <theme> [config]
|
|
|
|
|
|
|
|
|
|
Red='\033[0;31m' # Red
|
|
|
|
|
Color_Off='\033[0m' # Text Reset
|
|
|
|
|
|
|
|
|
|
if [[ $# -lt 2 ]]; then
|
|
|
|
|
echo "Usage: $0 <database> <theme_module> [config]"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
DATABASE="$1"
|
|
|
|
|
THEME="$2"
|
|
|
|
|
CONFIG="${3:-./config.conf}"
|
|
|
|
|
|
|
|
|
|
if [[ $# -eq 3 ]]; then
|
|
|
|
|
./script/addons/check_addons_exist.py -m "$THEME" -c "$3"
|
|
|
|
|
else
|
|
|
|
|
./script/addons/check_addons_exist.py -m "$THEME"
|
|
|
|
|
fi
|
|
|
|
|
retVal=$?
|
|
|
|
|
if [[ $retVal -ne 0 ]]; then
|
|
|
|
|
echo -e "${Red}Error${Color_Off} check_addons_exist.py into uninstall_addons_theme.sh"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "Unload theme '$THEME' from every website of BD '$DATABASE'"
|
|
|
|
|
|
|
|
|
|
# Le déchargement passe par le shell : _theme_remove() n'a pas d'option de
|
|
|
|
|
# ligne de commande, et l'écrire ici évite d'ajouter une option au fork pour
|
|
|
|
|
# chaque version d'Odoo. Les journaux se mêlent à la sortie, d'où la
|
|
|
|
|
# sentinelle : on ne conclut que sur ce qui la suit.
|
|
|
|
|
./odoo_bin.sh shell -c "$CONFIG" -d "$DATABASE" --no-http --log-level=warn <<PYTHON
|
|
|
|
|
theme_name = "$THEME"
|
|
|
|
|
Module = env["ir.module.module"]
|
|
|
|
|
theme = Module.search([("name", "=", theme_name)], limit=1)
|
|
|
|
|
if not theme:
|
|
|
|
|
print("ERPLIBRE_THEME_UNLOAD: unknown %s" % theme_name)
|
|
|
|
|
else:
|
|
|
|
|
lst_website = env["website"].search([])
|
|
|
|
|
for website in lst_website:
|
|
|
|
|
# _theme_remove décharge le thème COURANT du site et, avant tout,
|
|
|
|
|
# rappelle _reset_default_config() : c'est cet appel qui écrit
|
|
|
|
|
# font-number & co. dans user_values.scss. Il vaut même quand le
|
|
|
|
|
# site n'a plus de thème — c'est précisément le cas à réparer.
|
|
|
|
|
theme.with_context(website_id=website.id)._theme_remove(website)
|
|
|
|
|
env.cr.commit()
|
|
|
|
|
print("ERPLIBRE_THEME_UNLOAD: done %s website(s)" % len(lst_website))
|
|
|
|
|
PYTHON
|
|
|
|
|
|
|
|
|
|
retVal=$?
|
|
|
|
|
if [[ $retVal -ne 0 ]]; then
|
|
|
|
|
echo -e "${Red}Error${Color_Off} odoo_bin.sh shell into uninstall_addons_theme.sh"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "Uninstall theme module '$THEME' on BD '$DATABASE'"
|
|
|
|
|
|
|
|
|
|
if [[ $# -eq 3 ]]; then
|
|
|
|
|
./run.sh --no-http --stop-after-init -d "$DATABASE" --uninstall "$THEME" -c "$3"
|
|
|
|
|
else
|
|
|
|
|
./run.sh --no-http --stop-after-init -d "$DATABASE" --uninstall "$THEME"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
retVal=$?
|
|
|
|
|
if [[ $retVal -ne 0 ]]; then
|
|
|
|
|
echo -e "${Red}Error${Color_Off} run.sh into uninstall_addons_theme.sh"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Ce que le déchargement ne prend pas : les pièces jointes que le thème a
|
|
|
|
|
# laissées sous son propre chemin. Elles ne cassent rien tant que ses vues
|
|
|
|
|
# sont parties, mais elles survivent à toutes les migrations suivantes et
|
|
|
|
|
# personne ne sait plus d'où elles viennent. On les signale, on ne les
|
|
|
|
|
# supprime pas : leur contenu peut être la seule trace d'une personnalisation.
|
[FIX] addons: stop calling a leftover report a failed command
« Command returned error code: 1 » followed a theme that was removed
correctly. 1 is this toolkit's « there are findings », but the report
was the uninstaller's last command, so its code became the script's;
and the COW check was still read through the capturing executor, which
announces any non-zero code as an error.
The leftovers can now be dealt with instead of only listed: keep by
default, or delete after their content is written to private/. Listing
fifteen attachments and stopping there meant composing an unlink() by
hand, mid-migration, from identifiers read off a screen.
--- FR ---
[FIX] addons : cesser d'appeler « erreur » un rapport de restes
« Command returned error code: 1 » suivait un thème correctement
retiré. 1 veut dire « il y a des constats » dans cet outillage, mais le
rapport était la dernière commande du désinstalleur, donc son code
devenait celui du script ; et la vérification COW passait encore par
l'exécuteur qui capture, lequel annonce tout code non nul comme une
erreur.
Les restes peuvent désormais être traités, pas seulement listés :
garder par défaut, ou effacer après écriture de leur contenu sous
private/. Lister quinze pièces jointes et s'arrêter là revenait à faire
composer un unlink() à la main, en pleine migration.
Assisted-by: Claude Opus 5
(cherry picked from commit 304ce32b2680e3d01e38c3224bb85c2798cd6f53)
2026-08-16 05:33:28 -04:00
|
|
|
# Son code de sortie dit « il reste des choses », pas « la désinstallation a
|
|
|
|
|
# échoué » : le laisser devenir celui du script faisait annoncer une erreur
|
|
|
|
|
# sur un thème correctement retiré.
|
|
|
|
|
./script/addons/theme_leftover.py -d "$DATABASE" -t "$THEME" -c "$CONFIG" || true
|
|
|
|
|
exit 0
|