Skip to content

Commit 3f2bec7

Browse files
committed
feat(java,kotlin): eject -Dundo, owned-copy notice; drop the dead api-docs model link
1 parent 54a44c1 commit 3f2bec7

9 files changed

Lines changed: 510 additions & 7 deletions

File tree

‎docs/ports/java.md‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@ or replaced (`<handEdits>overwrite</handEdits>`). `mvn metaobjects:eject -Dnames
3131
generator into your repo to own. Commit the manifest. Details:
3232
[Own your codegen](../features/own-your-codegen.md).
3333

34+
## Undo an eject, strict loading, and diagnostics
35+
36+
**Undo an eject.** `mvn metaobjects:eject -Dundo=true` deletes the owned copies under `codegen/`
37+
that are identical to the generator this plugin ships (the comparison `-Dlist` shows as
38+
`[owned — identical]`: the generator, the classes copied with it and its page templates, the
39+
`package` line and the other lines eject itself rewrites ignored). With `-Dnames=a,b` it removes
40+
those only, and a copy that differs is refused, with nothing removed, unless `-Dforce=true`; every
41+
name is checked before anything is deleted. It never edits `pom.xml`: for each generator removed it
42+
prints the `<classname>` to put back, owned to shipped. The shared support classes and helper
43+
runtime that eject also wrote stay (other owned generators may import them) and are named. While an
44+
identical copy exists, `mvn metaobjects:generate` logs one advisory line naming it and this command;
45+
it never changes the outcome of the build.
46+
47+
**Strict loading.** `metaobjects:generate` already loads strictly, exactly as `metaobjects:verify`
48+
does (ADR-0023): an attribute no registered provider declares fails the goal with
49+
`ERR_UNKNOWN_ATTR` before any generator runs, and no file is written. `-Dmeta.lax=true` is the
50+
opt-out for both goals. There is no separate `-Dstrict` switch.
51+
52+
**No `doctor` goal.** There is no `metaobjects:doctor`; `metaobjects:verify` (drift and the
53+
requirement gate) and `eject -Dlist` (owned-copy status) are the diagnostics the plugin has.
54+
3455
## Install
3556

3657
Set `${metaobjects.version}` to the current Maven Central release (`8.1.4`) — both
@@ -382,7 +403,7 @@ name in every port.
382403
| `report-export` | `SpringReportExportGenerator` | `metaobjects-codegen-spring` | Standalone export of a served report (`?format=csv\|json\|xml`, see [Report export](#report-export)): one `<R>Export` per served report beside its controller (columns in derived-field order, wire-form cells, `MAX_ROWS`, `csv(rows)` and `xml(rows)`) and one shared `ReportExportWriter` (CSV quoting, CRLF, the `EXPORT_CSV_BOM` constant, the formula-injection guard, XML over JDK StAX; no new dependency, Jackson is already there). Args: `outputDir` (required), `maxRows` (default `100000`), `xmlNulls` (`empty`, the default, or `nil`), `csvBom` (default `false`) and `writerPackage` (default: the package prefix the served reports share, else `export`). Never implied by a library. Ejectable. |
383404
| `trace-helper` | `LlmTraceHelperGenerator` | `metaobjects-codegen-spring` | One `<Entity>TraceHelper` per concrete entity that transitively `extends` `metaobjects::ai::LlmCallBase` **and** nests a `template.prompt` carrying `@responseRef` — a static `record<Entity>(...)` that extracts the typed response, builds the `LlmCallBase` trace row, and persists it. Emits nothing for any other entity. |
384405
| `template` | `TemplateScopeGenerator` | `metaobjects-codegen-base` | The generic Mustache primitive: walk the model by a named `scope`, render one shared template per walk result, write each file. The declarative alternative to writing a generator class — see [Declarative template-codegen](#declarative-template-codegen-templatescopegenerator) below. It renders through `render.templategen.TemplateGenerator`, the byte-pinned cross-port factory; that factory takes a walk callback and is not itself a `Generator`, so `TemplateScopeGenerator` is the class a pom names. |
385-
| `api-docs` | `JavaApiDocsGenerator` | `metaobjects-codegen-spring` | The Java SDK api reference: one page per entity, value object, projection, served report and template, an index and `AGENT-API.md`, under `<outputDir>/<apiSubDir>`. A `<generator>` entry like any other, run by `metaobjects:generate` and checked by `metaobjects:verify`. Args: `outputDir` (required; give it generated files only, since `verify` compares the whole tree), `apiSubDir` (default `api/java`), `layout` (`flat`, the default, or `package`), `projectName` (the agent page's header label, default `project`) and `modelBaseUrl` (absolute base for the links to the model pages; relative when unset). The `metaobjects:docs` goal was removed in 8.1.0 ([migration](../features/migrations/docs-are-generators.md#java-and-kotlin)). Ejectable: the copy takes the page IR, the builder, the renderer, the page paths and the page templates with it. |
406+
| `api-docs` | `JavaApiDocsGenerator` | `metaobjects-codegen-spring` | The Java SDK api reference: one page per entity, value object, projection, served report and template, an index and `AGENT-API.md`, under `<outputDir>/<apiSubDir>`. A `<generator>` entry like any other, run by `metaobjects:generate` and checked by `metaobjects:verify`. Args: `outputDir` (required; give it generated files only, since `verify` compares the whole tree), `apiSubDir` (default `api/java`), `layout` (`flat`, the default, or `package`), `projectName` (the agent page's header label, default `project`) and `modelBaseUrl` (absolute base for the links to the model pages; with none set the pages carry no `Model / metadata` link, since nothing writes a page for it to point at). The `metaobjects:docs` goal was removed in 8.1.0 ([migration](../features/migrations/docs-are-generators.md#java-and-kotlin)). Ejectable: the copy takes the page IR, the builder, the renderer, the page paths and the page templates with it. |
386407
| `plantuml` | `PlantUMLGenerator` | `metaobjects-codegen-plantuml` | One PlantUML class diagram of the object model (`outputDir`, `outputFilename`; `showAttrs`, `showFields`, `showAbstracts`, `drawKeys`, `drawRefs` choose what is drawn). Ejectable: the copy takes `PlantUMLWriter` with it. |
387408
| `html-docs` | `MetaDataHtmlDocumentationGenerator` | `metaobjects-codegen-base` | One HTML page describing the registered metamodel types (`outputDir`, `outputFilename`). It reads the type registry, not your model, so it documents the vocabulary your build loads, providers included. Ejectable: the copy takes `MetaDataHtmlDocumentationWriter` with it. |
388409
| `ai-docs` | `MetaDataAIDocumentationGenerator` | `metaobjects-codegen-base` | The same type reference as JSON, laid out for an AI reader (`outputDir`, `outputFilename`). Ejectable: the copy takes `MetaDataAIDocumentationWriter` with it. |

‎docs/ports/kotlin.md‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@ manifest (`.metaobjects/.gen-state/.hashes.json`) is overwritten, and an edited
2828
name (or replaced with `<handEdits>overwrite</handEdits>`). `mvn metaobjects:eject -Dnames=<name>`
2929
copies a generator into your repo to own.
3030

31+
## Undo an eject, strict loading, and diagnostics
32+
33+
**Undo an eject.** `mvn metaobjects:eject -Dundo=true` deletes the owned copies under `codegen/`
34+
that are identical to the generator this plugin ships (the comparison `-Dlist` shows as
35+
`[owned — identical]`: the generator, the classes copied with it and its page templates, the
36+
`package` line and the other lines eject itself rewrites ignored). With `-Dnames=a,b` it removes
37+
those only, and a copy that differs is refused, with nothing removed, unless `-Dforce=true`; every
38+
name is checked before anything is deleted. It never edits `pom.xml`: for each generator removed it
39+
prints the `<classname>` to put back, owned to shipped. The shared support classes and helper
40+
runtime that eject also wrote stay (other owned generators may import them) and are named. While an
41+
identical copy exists, `mvn metaobjects:generate` logs one advisory line naming it and this command;
42+
it never changes the outcome of the build.
43+
44+
**Strict loading.** `metaobjects:generate` already loads strictly, exactly as `metaobjects:verify`
45+
does (ADR-0023): an attribute no registered provider declares fails the goal with
46+
`ERR_UNKNOWN_ATTR` before any generator runs, and no file is written. `-Dmeta.lax=true` is the
47+
opt-out for both goals. There is no separate `-Dstrict` switch.
48+
49+
**No `doctor` goal.** There is no `metaobjects:doctor`; `metaobjects:verify` (drift and the
50+
requirement gate) and `eject -Dlist` (owned-copy status) are the diagnostics the plugin has.
51+
3152
## Install
3253

3354
Every version below comes from one `<properties>` entry. Set the Java level (Maven defaults to
@@ -156,7 +177,7 @@ The 17 generators registered in `codegen-kotlin` (`GeneratorRegistry.kt`):
156177
| `KotlinSpringControllerGenerator` | `<Entity>Controller.kt` — Spring `@RestController` (5 CRUD endpoints; cross-port API contract). **Select `KotlinRelationsGenerator` with it** when the model has a M:N relationship: the traversal routes call the `<rel>Query` helpers only that generator emits, and without it the controller does not compile | entities with `source.rdb @kind="table"` |
157178
| `KotlinRequirementTestsGenerator` | Per metamodel package that holds a tested requirement, two files in `testPackage`: `Requirements_<pkgKey>_Witnesses.kt` (an interface whose default members fail with `unimplemented requirement: ...`) and `Requirements_<pkgKey>_Test.kt` (one JUnit Jupiter `@Test` per requirement, calling a project-owned witness). See "Requirement tests" below | every tested `requirement.*` (functional, level 4 or above by default) |
158179
| `KotlinReportExportGenerator` | Standalone export of a served report (`?format=csv\|json\|xml`, see [Report export](#report-export)): one `<Report>Export.kt` per served report beside its controller and one shared `ReportExportWriter.kt`. Args: `outputDir` (required), `maxRows` (default `100000`), `xmlNulls` (`empty`, the default, or `nil`), `csvBom` (default `false`) and `writerPackage` (default: the package prefix the served reports share, else `export`). Never implied by a library. Ejectable | every served report |
159-
| `KotlinApiDocsGenerator` | The Kotlin SDK api reference, under `<outputDir>/<apiSubDir>`: `<Unit>.md` per entity, value object, projection, served report and template, a `README.md` index and `AGENT-API.md`. A `<generator>` entry like any other, run by `metaobjects:generate` and checked by `metaobjects:verify`. Args: `outputDir` (required, generated files only), `apiSubDir` (default `api/kotlin`), `layout` (`flat` or `package`), `projectName` and `modelBaseUrl`, as for the Java `api-docs`. The `metaobjects:docs` goal was removed in 8.1.0 ([migration](../features/migrations/docs-are-generators.md#java-and-kotlin)). Ejectable, with the page model, builder, renderer and path math | the whole model, once |
180+
| `KotlinApiDocsGenerator` | The Kotlin SDK api reference, under `<outputDir>/<apiSubDir>`: `<Unit>.md` per entity, value object, projection, served report and template, a `README.md` index and `AGENT-API.md`. A `<generator>` entry like any other, run by `metaobjects:generate` and checked by `metaobjects:verify`. Args: `outputDir` (required, generated files only), `apiSubDir` (default `api/kotlin`), `layout` (`flat` or `package`), `projectName` and `modelBaseUrl`, as for the Java `api-docs` (with no `modelBaseUrl` the pages carry no `Model / metadata` link). The `metaobjects:docs` goal was removed in 8.1.0 ([migration](../features/migrations/docs-are-generators.md#java-and-kotlin)). Ejectable, with the page model, builder, renderer and path math | the whole model, once |
160181

161182
Maven wiring. The plugin bundles `metaobjects-codegen-kotlin`, so it is not a dependency of your
162183
project. Keep `<configuration>` at plugin level and bind the goal in `<executions>`: without the

‎server/java/codegen-kotlin/src/main/kotlin/com/metaobjects/generator/kotlin/apidocs/KotlinApiDocsGenerator.kt‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ class KotlinApiDocsGenerator : FileEmittingGenerator() {
4747
}
4848
for (unit in model.units) {
4949
val pagePath = DocsPaths.docPageOutputPath(layout, unit.pkg, unit.node)
50-
val modelHref = DocsPaths.modelCrossHref("$subDir/$pagePath", pagePath, modelBaseUrl)
50+
// No model pages are written beside the api pages, so a relative link would be dead:
51+
// the link is emitted only against a <modelBaseUrl> that hosts them.
52+
val modelHref = if (modelBaseUrl.isNullOrEmpty()) null
53+
else DocsPaths.modelCrossHref("$subDir/$pagePath", pagePath, modelBaseUrl)
5154
add(pagePath, renderer.renderUnitPage(unit, modelHref))
5255
}
5356
add("README.md", renderer.renderIndex(model, layout))
@@ -65,7 +68,7 @@ class KotlinApiDocsGenerator : FileEmittingGenerator() {
6568
/** Arg: the page layout, `flat` (one file per unit, the default) or `package`. */
6669
const val ARG_LAYOUT: String = "layout"
6770

68-
/** Arg: when set, the base URL the pages' links to the model pages are written against. */
71+
/** Arg: the base URL the pages' links to the model pages are written against; with none set, the pages carry no such link. */
6972
const val ARG_MODEL_BASE_URL: String = "modelBaseUrl"
7073

7174
/** The api-surface subdirectory of the cross-port docs contract. */

‎server/java/codegen-spring/src/main/java/com/metaobjects/generator/apidocs/JavaApiDocsGenerator.java‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public final class JavaApiDocsGenerator extends FileEmittingGenerator {
4141
/** Arg: the page layout, {@code flat} (one file per unit, the default) or {@code package}. */
4242
public static final String ARG_LAYOUT = "layout";
4343

44-
/** Arg: when set, the base URL the pages' links to the model pages are written against. */
44+
/** Arg: the base URL the pages' links to the model pages are written against; with none set, the pages carry no such link. */
4545
public static final String ARG_MODEL_BASE_URL = "modelBaseUrl";
4646

4747
/** The api-surface subdirectory of the cross-port docs contract. */
@@ -67,7 +67,10 @@ protected List<EmittedFile> generate(MetaDataLoader loader) {
6767
Set<String> paths = new HashSet<>();
6868
for (ApiUnit unit : model.units()) {
6969
String pagePath = DocsPaths.docPageOutputPath(layout, unit.pkg(), unit.node());
70-
String modelHref = DocsPaths.modelCrossHref(subDir + "/" + pagePath, pagePath, modelBaseUrl);
70+
// No model pages are written beside the api pages, so a relative link would be dead:
71+
// the link is emitted only against a <modelBaseUrl> that hosts them.
72+
String modelHref = modelBaseUrl == null || modelBaseUrl.isEmpty() ? null
73+
: DocsPaths.modelCrossHref(subDir + "/" + pagePath, pagePath, modelBaseUrl);
7174
add(pages, paths, subDir, pagePath, renderer.renderUnitPage(unit, modelHref));
7275
}
7376
add(pages, paths, subDir, "README.md", renderer.renderIndex(model, layout));

0 commit comments

Comments
 (0)