You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
grammar uses `*` to cross the `::` separator and `@` to match one segment —
36
+
respectively `scope`'s `**` and `*`, inverted — plus `!`-prefix exclusion and
37
+
a `.[attr]` predicate `scope` cannot express at all
38
+
(`GeneratorUtil.createRegexFromGlob` carries a `TODO` conceding its own
39
+
separator handling is wrong). Both are output filters over the same resolved
40
+
file set, so reconciling them is a separate, adopter-affecting decision
41
+
rather than a mechanical port. No cross-port behavior depends on `scope`.
42
+
-**Resolved file order, and the malformed-config error code, are deliberately
43
+
NOT cross-port contracts.** The ports' directory walks already differ and
44
+
always have (Java sorts by basename, C# by full-path ordinal, Python by
45
+
basename, TypeScript walks depth-first); the corpus compares file **sets**.
46
+
A malformed config must raise rather than silently degrade to "no config",
47
+
but which error is each port's own — verified empirically: TypeScript raises
48
+
a raw `ZodError` with no code at all, Python raises
49
+
`ERR_COLLECTION_NOT_FOUND`, C# and Java both raise `ERR_BAD_ATTR_VALUE`.
50
+
-**Directory expansion follows symlinked directories in all four ports** —
51
+
including when a declared `sources` path is itself a symlink, or a symlink
52
+
sits partway through a walked tree. TypeScript and C# already did; Java and
53
+
Python now match (a symlinked `sources` path previously resolved to zero
54
+
files in Java, silently, exit 0). A symlink cycle is a loud error rather
55
+
than a hang. Gated by two new `symlinks`-bearing corpus cases.
56
+
-**Behavior change (Java/Maven only): a `<loader>` naming neither
57
+
`<sourceDir>` nor `<sources>`, with no `.metaobjects/config.json``sources`
58
+
and no default `metaobjects/` directory, now FAILS the build**
59
+
(`ERR_COLLECTION_NOT_FOUND`) instead of silently producing an empty model
60
+
and passing. This is the one behavior change here that can break an
61
+
existing `mvn metaobjects:generate`/`:verify` — most likely to bite a
62
+
multi-module reactor where a parent pom configures `<loader>` and one child
63
+
module never adds its own `<sourceDir>`. To restore the old outcome, declare
64
+
`<sourceDir>`/`<sources>` explicitly in that module's pom, or give it a real
65
+
metadata source (a `metaobjects/` directory or a `.metaobjects/config.json`
66
+
`sources` entry).
67
+
68
+
### Changed — a committed migration chain must replay from empty, and `meta migrate` stops writing chains that cannot ([#313](https://github.com/metaobjectsdev/metaobjects/issues/313))
69
+
70
+
**`meta migrate --from-db` now REFUSES a drop for a table or view the committed schema
71
+
snapshot never contained**, exiting 2 and naming each object. This is the one change here
72
+
that can fail an existing project's `meta migrate`, so it leads. Pass
73
+
**`--allow drop-unmanaged`** when the drop is genuinely intended.
74
+
75
+
The refusal exists because the drop it blocks produces a migration nobody can replay. The
76
+
live migrate path diffs metadata against introspection and never reads the snapshot, so a
77
+
table another tool owns reads as "in the database, not in the model" and is proposed for a
78
+
`DROP TABLE`. Every incremental migrate then keeps succeeding against the database that
79
+
already has that table — the chain only fails the day someone provisions a fresh one, which
80
+
for the reporter was **three months later**, by which point the only working database left
81
+
was a leftover CI container. `drift/classify.ts` has always said objects present in the DB
82
+
but not the snapshot "must never be treated as actionable drift or auto-dropped"; this is
83
+
the first place that doctrine is enforced where it mattered.
84
+
85
+
It does not false-fire on brownfield projects, and the reason is structural rather than
86
+
special-cased: **both mechanisms ADD to the snapshot.** A `baseline --from-db` snapshot
87
+
contains the foreign table; a project declaring `migrate.scope` carries its out-of-scope
88
+
entries forward. The guard fires precisely when nothing ever claimed the object. It fails
89
+
OPEN with no snapshot on disk — refusing there would break the first `meta migrate` of every
90
+
greenfield project — and it lives on the live path only, because the offline path diffs
91
+
against the snapshot and so cannot propose a snapshot-absent drop at all.
92
+
93
+
**Emitted forward drops now carry `IF EXISTS`** — `drop-table`, `drop-view` (plain and
94
+
CASCADE), `drop-index` (both the plain form and #285's constraint-backed
95
+
`ALTER TABLE … DROP CONSTRAINT`), `drop-fk` and `drop-check` — in both dialects, so an
0 commit comments