Skip to content

Commit 66056ae

Browse files
authored
feat(maven-plugin)!: one way to generate in Java and Kotlin; api-docs is a declared generator and the docs goal is removed (#437)
* feat(eject): hand over the Java and Kotlin emitters; api-docs and four Java docs generators eject An ejected Java or Kotlin generator was one file over packaged emitters, so a defect in the enum, record-builder, extraction-mirror or prompt-format writers waited for a release. Eject now copies those emitters with the generator, into its package, and points the imports the copies have of one another at the copies. - Java dto and value-object take Fr019SharedEnum and SpringRecordBuilder, output-parser takes Fr019SharedEnum, output-prompt takes OutputFormatSpecEmitter, and entity takes ExtractorCodeGenerator, so an owned entity writes its extractors through the owned copy. - Kotlin entity takes KotlinEnumEmitter, output-parser takes KotlinExtractSchemaEmitter and output-prompt takes KotlinOutputFormatSpecEmitter. Kotlin Fr019SharedEnum stays in the package as engine: it writes nothing and the type mapper takes its config as an argument. - api-docs is a generator in Java and Kotlin, run through a new DocsGenerator marker. metaobjects:docs runs the one the project lists for a surface in place of the packaged one; generate and verify skip it. Eject copies the page model, builder, renderer and path math, and for Java the page templates, with the copied template provider pointed at them. - plantuml, html-docs, ai-docs and json-schema ship eject source, each with its writer. SingleHtmlDirectGeneratorBase drives the new HtmlDirectWriter, and the JSON Schema and AI documentation attributes move to CodeGenMetaDataProvider, with deprecated forwarders left on the two generators. The eject contract's pending list holds no java or kotlin entry. Packaged output is unchanged. * fix(eject): keep the 1.0 GeneratorInfo constructor and the HTML writeHtml hook; verify the emitter recipe - Kotlin GeneratorInfo keeps its six-argument constructor for JVM callers (@jvmoverloads), with a Java caller test. - SingleHtmlDirectGeneratorBase still calls a subclass's writeHtml(MetaDataHtmlDocumentationWriter) through a deprecated bridge, with a test. - The recipe for owning the emitters of an older owned copy is run against copies made by the last released artifacts, in Java and in Kotlin, and the docs say what it took: the copied Kotlin emitters import one another through the scratch package. * no-mistakes(review): fix(eject): per-port api-docs subpackage, shared docs wiring note * no-mistakes(review): fix(eject): print pom changes a second port needs * no-mistakes(review): fix(eject): two-port pom builds both source trees * no-mistakes(document): Fix Java ejectable-exemption sentence to exclude deprecated mustache * feat(eject): hand over the Java and Kotlin emitters; api-docs and four Java docs generators eject An ejected Java or Kotlin generator was one file over packaged emitters, so a defect in the enum, record-builder, extraction-mirror or prompt-format writers waited for a release. Eject now copies those emitters with the generator, into its package, and points the imports the copies have of one another at the copies. - Java dto and value-object take Fr019SharedEnum and SpringRecordBuilder, output-parser takes Fr019SharedEnum, output-prompt takes OutputFormatSpecEmitter, and entity takes ExtractorCodeGenerator, so an owned entity writes its extractors through the owned copy. - Kotlin entity takes KotlinEnumEmitter, output-parser takes KotlinExtractSchemaEmitter and output-prompt takes KotlinOutputFormatSpecEmitter. Kotlin Fr019SharedEnum stays in the package as engine: it writes nothing and the type mapper takes its config as an argument. - api-docs is a generator in Java and Kotlin, run through a new DocsGenerator marker. metaobjects:docs runs the one the project lists for a surface in place of the packaged one; generate and verify skip it. Eject copies the page model, builder, renderer and path math, and for Java the page templates, with the copied template provider pointed at them. - plantuml, html-docs, ai-docs and json-schema ship eject source, each with its writer. SingleHtmlDirectGeneratorBase drives the new HtmlDirectWriter, and the JSON Schema and AI documentation attributes move to CodeGenMetaDataProvider, with deprecated forwarders left on the two generators. The eject contract's pending list holds no java or kotlin entry. Packaged output is unchanged. * fix(eject): keep the 1.0 GeneratorInfo constructor and the HTML writeHtml hook; verify the emitter recipe - Kotlin GeneratorInfo keeps its six-argument constructor for JVM callers (@jvmoverloads), with a Java caller test. - SingleHtmlDirectGeneratorBase still calls a subclass's writeHtml(MetaDataHtmlDocumentationWriter) through a deprecated bridge, with a test. - The recipe for owning the emitters of an older owned copy is run against copies made by the last released artifacts, in Java and in Kotlin, and the docs say what it took: the copied Kotlin emitters import one another through the scratch package. * no-mistakes(review): fix(eject): per-port api-docs subpackage, shared docs wiring note * no-mistakes(review): fix(eject): print pom changes a second port needs * no-mistakes(review): fix(eject): two-port pom builds both source trees * no-mistakes(document): Fix Java ejectable-exemption sentence to exclude deprecated mustache * feat(maven-plugin)!: api-docs is an ordinary generator entry; remove the docs goal Every generator, documentation included, is a <generator> entry in the list metaobjects:generate runs, and nothing is written that <generators> does not declare (ADR-0034 Amendment 9). - JavaApiDocsGenerator and KotlinApiDocsGenerator read outputDir, apiSubDir, layout, projectName and modelBaseUrl from <args>. The DocsGenerator marker and the skips in metaobjects:generate and metaobjects:verify are deleted. - metaobjects:docs only fails, with a line naming metaobjects:generate and the migration section. generate and verify refuse a pom that still sets the old goal's <language>, <apiSubDir>, <layout> or <modelBaseUrl>, so a build never passes while writing no documentation. - The Java entity generator writes no <Name>Extractor; the extractor generator is the one entry that does, and entity no longer copies it on eject. EmitsObjectExtractors and the emitExtractors arg are removed (both were new in this unreleased version). - Tests: api-docs through generate and verify, the removed goal and the refused 8.0 configuration, and a pom that declares nothing writes zero files (Java and Kotlin). * docs: ADR-0034 Amendment 9 and the Java/Kotlin migration to declared docs generators Amendment 9 is the cross-port rule: every generator, docs included, is an entry in the project's native generator list; one command runs it; no docs command, goal, marker, skip, second list or default set. It fixes, per port, where the list lives, the option names that replace the docs flags, the exact message a removed docs command prints, the exact error a gen command prints for 1.0-shape configuration, and the shape of the migration guide. It supersedes Amendment 7's docs seam, ADR-0021 D1, ADR-0022 Part 2 D1 and the docs-door parts of ADR-0025. - docs/features/migrations/docs-are-generators.md: the "Java and Kotlin" section, with before and after pom.xml and a parameter table. - Java and Kotlin port pages, own-your-codegen, the agent-context codegen references and their conformance fixtures, and the CHANGELOG 1.1.0 entries for these two ports. * no-mistakes(review): Restore docs goal phase; qualify Java/Kotlin docs pointer * no-mistakes(test): Name api-docs generator entry in Java/Kotlin Not-there line * no-mistakes(document): Drop removed docs goal from Java README and CLI table
1 parent 4bbd6cc commit 66056ae

88 files changed

Lines changed: 3190 additions & 1134 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,56 @@ generator catalog and the Atlas evaluation are 1.2 work.
125125
pages `meta docs` writes) and `agent-docs` (the pages `meta docs --agent` writes), both
126126
neutral and both still run by `meta docs`; a `generators` entry naming either string is
127127
refused the way `"docs"` is. Java: `plantuml`, `html-docs`, `ai-docs`, `json-schema` and the
128-
deprecated `mustache`, each by the class name a pom already uses. None of the seven ships
129-
eject source yet; `mustache` will not.
128+
deprecated `mustache`, each by the class name a pom already uses. `mustache` will not ship
129+
eject source. The four Java generators that can ship it do: see **Java and Kotlin** below.
130+
131+
- **Java and Kotlin: eject hands over the emitters a generator writes through, and
132+
`api-docs`, `plantuml`, `html-docs`, `ai-docs` and `json-schema` are ejectable.** An ejected
133+
Java or Kotlin generator used to be one file over packaged emitters, so a defect in the enum,
134+
record-builder, extraction-mirror or prompt-format writers still waited for a release. Eject
135+
now copies those emitters with the generator, into its package, and points the imports the
136+
copies have of one another at the copies. Java `dto` and `value-object` take
137+
`Fr019SharedEnum` and `SpringRecordBuilder`; Java `output-parser` takes `Fr019SharedEnum`;
138+
Java `output-prompt` takes `OutputFormatSpecEmitter`; Kotlin `entity` takes
139+
`KotlinEnumEmitter`; Kotlin `output-parser` takes `KotlinExtractSchemaEmitter`; Kotlin
140+
`output-prompt` takes `KotlinOutputFormatSpecEmitter` and `KotlinExtractSchemaEmitter`. A
141+
class two generators share is written once and never overwritten. The naming and type-mapping
142+
tables, the model walks and the generator bases stay in the package as the engine. Kotlin
143+
`Fr019SharedEnum` is engine: it writes nothing, and the type mapper takes its
144+
`ProvidedEnumConfig` as an argument, so its `providedInDeclarationPackage` and
145+
`DECLARATION_PACKAGE` members are now public. Packaged output is unchanged. A copy you ejected earlier keeps compiling with the packaged
146+
emitters; own them with the recipe in
147+
[own-your-codegen](docs/features/own-your-codegen.md#ejecting-a-generator-hands-over-the-emitters-it-writes-through-java-and-kotlin).
148+
- **`api-docs` is a generator, and ejectable, in Java and Kotlin.** The api reference is
149+
`JavaApiDocsGenerator` / `KotlinApiDocsGenerator`, a `<generator>` entry like any other:
150+
`metaobjects:generate` runs it and `metaobjects:verify` checks it, with `outputDir`,
151+
`apiSubDir`, `layout`, `projectName` and `modelBaseUrl` in its `<args>`. It replaces the
152+
`metaobjects:docs` goal (see **Removed**). Eject
153+
copies the generator, the page model, the builder, the renderer and the path math into a
154+
subpackage per port, `<package>.apidocs.java` or `<package>.apidocs.kotlin`: the two ports
155+
name those classes alike, so one `codegen/` module can hold both without a class declared
156+
twice. Eject prints the class name to list. Eject writes `codegen/pom.xml` for the ports
157+
the module holds at that moment and never edits it afterwards. One call that ejects for
158+
both ports now gets a pom that builds both source trees; it used to leave `src/main/java`
159+
out. When a later call adds a port, the pom does not declare what that port needs (the
160+
`metaobjects-codegen-*` dependency, `kotlin-maven-plugin`, or `src/main/java` as a source
161+
root after a Kotlin-first eject), and eject now warns and prints what to add. For Java the page templates come too, into
162+
`codegen/src/main/resources/<package path>/apidocs/java/templates/`, with the copied
163+
template provider pointed there. What the Java reference documents is still what the
164+
packaged generators emit for (`GeneratorApplicability.packaged()`): an owned `routes` whose
165+
`appliesTo` you changed is documented as the packaged one behaves, unless you change the
166+
line of your `JavaApiDocsGenerator` copy that builds it. The pages are the ones 8.0's
167+
docs goal wrote, given the same options.
168+
- **The Java `plantuml`, `html-docs`, `ai-docs` and `json-schema` generators ship eject
169+
source**, each with the writer that emits its file. `SingleHtmlDirectGeneratorBase` now
170+
drives the new `HtmlDirectWriter`, as the JSON base drives `JsonDirectWriter`, so a copied
171+
HTML generator pairs with the copy of its writer. A subclass that overrode
172+
`writeHtml(MetaDataHtmlDocumentationWriter)` keeps being called, through a deprecated bridge the
173+
base still calls; one that returns the stock writer from `getWriter` still compiles. A subclass
174+
compiled against 1.0.x needs a recompile, because the method's return type changed. The attributes the JSON Schema and AI documentation generators
175+
add to the metamodel moved to `CodeGenMetaDataProvider`, where the loader registers them,
176+
so a copy owns emit code only; the old static methods and constants on the two generators
177+
stay as deprecated forwarders.
130178

131179
- **The Java `entity` and `extractor` generators can be ejected.**
132180
`mvn metaobjects:eject -Dnames=entity,extractor -Dport=java` copies each generator, with
@@ -139,25 +187,21 @@ generator catalog and the Atlas evaluation are 1.2 work.
139187
Amendment 6.
140188
- **The owned `entity` includes the class body.** Eject copies seven files into one
141189
package: `JavaObjectCodeGenerator`, the two bases it extends (`JavaCodeGenerator`,
142-
`BaseObjectCodeGenerator`), and the four writers that emit each class
190+
`BaseObjectCodeGenerator`) and the four writers that emit each class
143191
(`BaseObjectCodeWriter`, `JavaCodeWriter`, `PojoAwareCodeWriter`,
144192
`ValueObjectCodeWriter`). The copies use one another, never the packaged classes: where
145193
one imports another, eject rewrites that import along with the package line. You change
146194
a field, a constructor or an accessor by editing the writer, with nothing to subclass.
147195
`-Dlist` gives `entity` one verdict over all seven files. Details:
148196
[own-your-codegen](docs/features/own-your-codegen.md#java-entity-and-extractor).
149-
- **`extractor` is a generator of its own (Java).** `ExtractorCodeGenerator` can be named
197+
- **`extractor` is a generator of its own (Java).** `ExtractorCodeGenerator` is named
150198
in `<generators>`, with the same `outputDir`, `pkgPrefix`, `pkgSuffix`, `namePrefix`,
151-
`nameSuffix` and `<filters>` as your `entity` generator. When it is, the plugin sets
152-
`emitExtractors=false` on `entity`, so each `<Name>Extractor` has one emitter; an
153-
`emitExtractors=true` in the pom does not override that. Outside Maven, set the arg
154-
yourself. Ejecting it also copies `JavaCodeWriter` and `BaseObjectCodeWriter`, where it
155-
reads class names from. In the same package as an owned `entity`, the two share that
156-
one copy.
157-
- **A pom that wires only `entity` still writes the extractors.** Its class files change
158-
once, in the header comment only: see **Changed** below.
159-
- New public API: in `metaobjects-codegen-base`, the `EmitsObjectExtractors` marker, whose
160-
`ARG_EMIT_EXTRACTORS` names the `emitExtractors` arg; in `metaobjects-codegen-spring`,
199+
`nameSuffix` and `<filters>` as your `entity` generator, and it is the one generator that
200+
writes `<Name>Extractor` classes (see **Removed**). Ejecting it also copies `JavaCodeWriter` and `BaseObjectCodeWriter`, where it
201+
reads class names from. In the same package as an owned `entity`, the two share those
202+
writers.
203+
- **`entity`'s class files change once**, in the header comment only: see **Changed** below.
204+
- New public API: in `metaobjects-codegen-spring`,
161205
`GeneratorRegistry.GeneratorInfo.ejectWith()`, the classes eject copies with a
162206
generator.
163207

@@ -947,6 +991,29 @@ until you regenerate.
947991

948992
### Removed
949993

994+
- **Java and Kotlin: the `metaobjects:docs` goal.** Documentation is generated the way code
995+
is: the api reference is a `JavaApiDocsGenerator` or `KotlinApiDocsGenerator` `<generator>`
996+
entry in the list `metaobjects:generate` runs, with its options in `<args>` (see
997+
**Added**), and nothing is written that `<generators>` does not declare. A pom that still
998+
binds the goal fails with a line naming `mvn metaobjects:generate` and the migration
999+
section. `generate` and `verify` refuse a pom that still sets the goal's parameters
1000+
(`<language>`, `<apiSubDir>`, `<layout>`, `<modelBaseUrl>`) instead of running and writing
1001+
no documentation. Ruling: ADR-0034 Amendment 9, which makes this the rule in all five ports
1002+
and numbers the release 1.1.0 (Maven 8.1.0) by the maintainer's explicit decision.
1003+
- **To upgrade**, replace the `docs` execution with one `<generator>` entry per language;
1004+
before and after `pom.xml`, and each parameter's new name, are in
1005+
[docs-are-generators.md, "Java and Kotlin"](docs/features/migrations/docs-are-generators.md#java-and-kotlin).
1006+
The page header's project label was the module's `artifactId`; set
1007+
`<projectName>${project.artifactId}</projectName>` to keep the pages byte for byte.
1008+
- **Java: `entity` no longer writes `<Name>Extractor` classes.** Through 8.0,
1009+
`JavaObjectCodeGenerator` wrote one beside each concrete class when the pom listed no
1010+
`extractor`: output no `<generator>` entry declared. Only `ExtractorCodeGenerator` writes
1011+
them now.
1012+
- **To upgrade**, if your code calls `<Name>Extractor` and your pom lists `entity` without
1013+
`extractor`: add an `ExtractorCodeGenerator` entry with the `entity` entry's `outputDir`,
1014+
naming args and `<filters>`
1015+
([migration](docs/features/migrations/docs-are-generators.md#java-and-kotlin)).
1016+
9501017
- **The standalone `mermaid-er` generator (TypeScript).** `mermaidErDiagram()`, its
9511018
`MermaidErOptions` type and the stable name `"mermaid-er"` are gone from
9521019
`@metaobjectsdev/codegen-ts/generators`, the generator catalog and the cross-port
@@ -1109,13 +1176,13 @@ until you regenerate.
11091176

11101177
- Every Kotlin generator that types an enum now takes `providedEnumNamespace` /
11111178
`providedEnumPackages`: the entity, Exposed table, Spring controller, relations and
1112-
output-parser generators, and the API pages `mvn metaobjects:docs` writes. Only the entity
1179+
output-parser generators, and `KotlinApiDocsGenerator`. Only the entity
11131180
generator read them before, so for a `@provided` enum the data class named your class while
11141181
the Exposed table and the controller named a class in the declaration's package that nothing
11151182
generates, and the output did not compile. They now all resolve it through one function. A
11161183
generator configured without the args fails at generate time for a model with a `@provided`
11171184
enum, naming the enum, its package and both args. Set them once in the plugin's `<globals>`
1118-
and every generator, and the docs goal, reads the same values.
1185+
and every generator reads the same values.
11191186
- **Upgrading an owned Kotlin generator.** A copy ejected before this release keeps compiling
11201187
unchanged. The helper signatures it calls remain as deprecated forms:
11211188
`KotlinTypeMapper.enumTypeName(field, entity)`, `KotlinEnumEmitter.emitEnumFile` without a

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ first-week wedge plan — and `meta init` picks up from there.
134134
|---|---|---|---|
135135
| TypeScript | **npm `1.0.13`** — the `@metaobjectsdev/*` packages | [`docs/ports/typescript.md`](docs/ports/typescript.md) | [`server/typescript/`](server/typescript/) · [`client/web/`](client/web/) |
136136
| Java | **Maven Central `8.0.13`** (`com.metaobjects:*` — the JVM major is npm major + 7) — loader + OMDB + render + Maven plugin all shipped; full conformance green | [`docs/ports/java.md`](docs/ports/java.md) | [`server/java/`](server/java/) |
137-
| Kotlin | **Maven Central `8.0.13`** — codegen tier on top of Java: 15 generators (entity, Exposed table, names, relations, repository, output-parser, output-prompt, render-helper, extractor, filter-allowlist, validator, Spring config, storedProc, Spring controller, requirement-tests); 24 / 24 persistence-conformance | [`docs/ports/kotlin.md`](docs/ports/kotlin.md) | [`server/java/codegen-kotlin/`](server/java/codegen-kotlin/) · [`server/java/metadata-ktx/`](server/java/metadata-ktx/) |
137+
| Kotlin | **Maven Central `8.0.13`** — codegen tier on top of Java: 16 generators (entity, Exposed table, names, relations, repository, output-parser, output-prompt, render-helper, extractor, filter-allowlist, validator, Spring config, storedProc, Spring controller, requirement-tests, api-docs); 24 / 24 persistence-conformance | [`docs/ports/kotlin.md`](docs/ports/kotlin.md) | [`server/java/codegen-kotlin/`](server/java/codegen-kotlin/) · [`server/java/metadata-ktx/`](server/java/metadata-ktx/) |
138138
| C# | **NuGet `1.0.13`** — loader + conformance + EF Core codegen + render engine + `dotnet meta` CLI all shipped | [`docs/ports/csharp.md`](docs/ports/csharp.md) | [`server/csharp/`](server/csharp/) |
139139
| Python | **PyPI `1.0.13`** — loader + conformance + render + entity-model codegen + ObjectManager runtime shipped; schema migrations are TS-owned (ADR-0015) | [`docs/ports/python.md`](docs/ports/python.md) | [`server/python/`](server/python/) |
140140

‎agent-context/servers/csharp.meta.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
"install": "install the MetaObjects .NET tool (dotnet tool install) + add the MetaObjects.Codegen package",
44
"codegenCommand": "dotnet meta gen",
55
"docsCommand": "dotnet meta docs",
6+
"docsCondition": "",
7+
"docsMissing": "",
68
"apiSubDir": "api/csharp"
79
}

‎agent-context/servers/java.meta.json‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
"displayName": "Java",
33
"install": "add com.metaobjects:metaobjects-metadata + metaobjects-codegen-spring + metaobjects-maven-plugin to your pom.xml",
44
"codegenCommand": "mvn metaobjects:generate",
5-
"docsCommand": "mvn metaobjects:docs",
5+
"docsCommand": "mvn metaobjects:generate",
6+
"docsCondition": " (when the project's generator list declares the api-docs generator)",
7+
"docsMissing": "Declare `com.metaobjects.generator.apidocs.JavaApiDocsGenerator` as a `<generator>` entry in the pom's `<generators>` if it is missing",
68
"apiSubDir": "api/java"
79
}

‎agent-context/servers/kotlin.meta.json‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
"displayName": "Kotlin",
33
"install": "add com.metaobjects:metaobjects-codegen-kotlin + metaobjects-metadata-ktx + metaobjects-maven-plugin to your pom.xml",
44
"codegenCommand": "mvn metaobjects:generate",
5-
"docsCommand": "mvn metaobjects:docs",
5+
"docsCommand": "mvn metaobjects:generate",
6+
"docsCondition": " (when the project's generator list declares the api-docs generator)",
7+
"docsMissing": "Declare `com.metaobjects.generator.kotlin.apidocs.KotlinApiDocsGenerator` as a `<generator>` entry in the pom's `<generators>` if it is missing",
68
"apiSubDir": "api/kotlin"
79
}

‎agent-context/servers/python.meta.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
"install": "pip install metaobjects",
44
"codegenCommand": "metaobjects gen",
55
"docsCommand": "metaobjects docs",
6+
"docsCondition": "",
7+
"docsMissing": "",
68
"apiSubDir": "api/python"
79
}

‎agent-context/servers/typescript.meta.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
"install": "npm install -D @metaobjectsdev/cli @metaobjectsdev/codegen-ts",
44
"codegenCommand": "npx meta gen",
55
"docsCommand": "npx meta docs",
6+
"docsCondition": "",
7+
"docsMissing": "",
68
"apiSubDir": "api"
79
}

0 commit comments

Comments
 (0)