erplibre/script/odoo/migration
Mathieu Benoit 803f1ea8ce [ADD] migration: decode percent-encoded page anchors before the 13 bump
OpenUpgrade's website post-migration gathers the href of every page
anchor and glues them into a CSS selector:

    "selector": ", ".join([link.attrib["href"] for link in links])

An href is not a selector. A French anchor written #principes-mn%C3%A9-
moniques puts a % in it, which no CSS identifier may hold, and the whole
migration dies on SelectorSyntaxError.

Proven by replaying that exact code on the database: three views failed
before, one of them with the % at position 53 -- the very position in
the log. After the fix, three views processed, none failed. Decoding is
enough: the parser accepts #principes-mnémoniques and refuses the
encoded form.

Only page views, only anchor hrefs, only %XX in hex. A % elsewhere in a
URL is legitimate and stays. The decoder lives in pg_temp and leaves
nothing behind.

--- FR ---

La post-migration website d'OpenUpgrade ramasse les href des ancres
d'une page et les recolle en sélecteur CSS. Or un href n'est pas un
sélecteur : une ancre française encodée y met un %, interdit dans un
identifiant CSS, et la migration meurt.

Prouvé en rejouant ce code exact sur la base : trois vues échouaient,
dont une avec le % en position 53 — celle du journal. Après correctif,
trois vues traitées, zéro échec. Décoder suffit : le parseur accepte
#principes-mnémoniques et refuse la forme encodée.

Seulement les vues de page, seulement les href d'ancre, seulement les
%XX hexadécimaux. Un % ailleurs dans une URL est légitime et reste. Le
décodeur vit dans pg_temp et ne laisse rien derrière lui.

Assisted-by: Claude Opus 5
2026-08-23 02:20:19 -04:00
..
check_cow_views.py [FIX] migration: the COW tools speak the system language 2026-08-22 07:23:59 -04:00
check_hidden_models.py [ADD] migration: repair DMS at the 13 bump, and catch the whole class 2026-08-22 07:24:00 -04:00
check_stale_scss.py [ADD] migration: make Enter mean the answer you always give 2026-08-22 07:23:59 -04:00
check_stale_scss_tui.py [ADD] migration: read the stale SCSS, then fix it, without leaving the tool 2026-08-22 07:23:59 -04:00
cow_drift.py [FIX] script: make the analysis and migration tools executable 2026-08-22 07:23:59 -04:00
cow_drift_tui.py [FIX] script: make the analysis and migration tools executable 2026-08-22 07:23:59 -04:00
database_cleanup.py [FIX] database_cleanup: purge the batch, and say what you are doing 2026-08-22 07:23:59 -04:00
dms_access_repair.py [ADD] migration: repair DMS at the 13 bump, and catch the whole class 2026-08-22 07:24:00 -04:00
fix_migration_odoo120_to_odoo130.sql [ADD] migration: decode percent-encoded page anchors before the 13 bump 2026-08-23 02:20:19 -04:00
fix_migration_odoo130_to_odoo140.sql [ADD] migration: see and repair the website COW views 2026-08-10 03:10:50 -04:00
fix_migration_odoo140_to_odoo150.py [FIX] script: make the analysis and migration tools executable 2026-08-22 07:23:59 -04:00
fix_migration_odoo170_to_odoo180.sql [ADD] migration: offer the theme uninstall where the theme is blamed 2026-08-22 07:24:00 -04:00
fix_view_type.py [ADD] migration: convert the <tree> tags Odoo 18 renamed to <list> 2026-08-22 07:24:00 -04:00
neutralize_cow_views.py [FIX] migration: the COW tools speak the system language 2026-08-22 07:23:59 -04:00
README.base.md [ADD] migration: see and repair the website COW views 2026-08-10 03:10:50 -04:00
README.fr.md [ADD] migration: see and repair the website COW views 2026-08-10 03:10:50 -04:00
README.md [ADD] migration: see and repair the website COW views 2026-08-10 03:10:50 -04:00
reset_stale_cow_tui.py [ADD] migration: browse the drifted COW copies full screen 2026-08-22 07:23:59 -04:00
reset_stale_cow_views.py [FIX] smoke: judge the back office AFTER the repair, and say why it failed 2026-08-22 07:23:59 -04:00
smoke_internal_ui.py [FIX] smoke: judge the back office AFTER the repair, and say why it failed 2026-08-22 07:23:59 -04:00
smoke_public_url.py [FIX] smoke: two sites still unpacked three fields from the failure tuple 2026-08-23 02:07:42 -04:00
snapshot_cow_views.py [FIX] migration: the COW tools speak the system language 2026-08-22 07:23:59 -04:00
uninstall_module_list_odoo140_to_odoo150.txt [IMP] todo support odoo upgrade 2025-10-31 01:43:26 -04:00

Migration

Run this script when doing database migration. Example :

source ./.venv.odoo15.0_python3.8.20/bin/activate && cat ./script/odoo/migration/fix_migration_odoo140_to_odoo150.py | ./odoo15.0/odoo/odoo-bin shell -d DATABASE

Check uninstall_module_list_odoo140_to_odoo150.txt

Module lists to uninstall

Before a version bump, the migration uninstalls the modules listed in uninstall_module_list_odoo<from>_to_odoo<to>.txt. Two locations are read, the private one first, and the results are merged (duplicates dropped):

  1. private/odoo/migration/<database>/uninstall_module_list_odooXX0_to_odooYY0.txt — specific to ONE database, not versioned. Which modules must be dropped depends on the data, so this is where nearly every entry belongs.
  2. script/odoo/migration/uninstall_module_list_odooXX0_to_odooYY0.txt — shared defaults, versioned, valid for every database.

Syntax: one module per line, with a justification after #. Commas and several names per line are accepted; blank lines and full-line comments are ignored. A module without a stated reason is flagged at runtime: removing a module is a decision someone must be able to review later.

queue_job                        # blocks 12->13, trigger queue_job_notify
mgmtsystem_hazard                # not ported to 13.0
web_syncer                       # dropped upstream