erplibre/script/odoo
Mathieu Benoit 00eb0a3c7a [ADD] migration: find the COW copies that drifted from their module view
Third COW incident of this migration, and the first two tools did not cover
it. A copy freezes the module view it came from; version after version the
MODULE view is modernised and the copy is not, until a child xpath lands on an
anchor the copy never had:

  Element '<xpath expr="//head/script[@id='web.layout.odooscript']">'
  cannot be located in parent view

On 14.0 -> 15.0 that was web.layout, copied in the 12.0 era: no id on the
script tag, QWeb still saying t-raw. It had survived only because the 14.0
module xpath carried a fallback — //head/script[@id='…'] | //head/script
[last()] — that 15.0 removed. The breakage was years old; 15.0 merely stopped
hiding it.

The test is DIFFERENTIAL, and it has to be. Resolving a child's xpath against
its parent's own arch proves nothing: Odoo resolves against the COMBINED arch
of the whole chain, so a child of website.layout legitimately targets //header
coming from an ancestor. Measured on the real database, that naive rule
reported 5 copies where only 1 had a problem. Resolving twice — against the
module twin and against the copy — and keeping only what the twin satisfies
and the copy cannot, isolates drift and nothing else.

Two accuracy fixes the real data forced:
  · inactive children are skipped; Odoo never applies them
  · a missing lxml is now a LOUD failure. The first version fell back to
    « everything resolves », so the checker answered « all clean » while
    checking nothing — the worst possible outcome for a checker. Verified: the
    bare system python3 has no lxml, .venv.erplibre does.

--reset copies the module arch over the copy, after saving the previous arch
to a timestamped file and printing the diff, because a copy can hold a real
customisation buried in the drift — on web.layout it was one <meta viewport>
among six differences.

Timing matters: drift only exists once the module views carry the new version,
so run this AFTER OpenUpgrade and BEFORE update_addons_all. Run on the 14.0
database it finds nothing about web.layout, and rightly so — there the module
view says t-raw too.

Verified end to end on a scratch database rebuilt from the real arches:
detection of the exact reported failure, dry-run changing nothing, --apply
resetting it, the backup holding the previous arch, and a clean re-check.
Then across the four migration databases, where it flags two latent drifts
(website_sale.product, website_blog.blog_post_complete) that no version bump
has surfaced yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 03:57:26 -04:00
..
migration [ADD] migration: find the COW copies that drifted from their module view 2026-08-02 03:57:26 -04:00
util [UPD] script Format 2026-03-14 23:26:31 -04:00