Skip to content

Commit 0affc6a

Browse files
authored
feat(cli): one generator list and one gen command for C# and Python (#440)
* feat(csharp,python)!: one generator list per port; the docs commands are removed ADR-0034 Amendment 9 for C# and Python. Every generator, the api reference included, is an entry in the port's generator list, and the gen command runs exactly that list. C#: the list is codegen/Generators.cs, run by a two-line codegen/Program.cs. New `dotnet meta init` writes the codegen project; eject writes the three files when missing. `dotnet meta gen` and `verify --codegen` run the list and refuse a project without one. `--generators` only narrows declared entries. ApiDocsGenerator takes OutDir, ApiSubDir, ProjectName and ModelBaseUrl as init properties; IGenerator.OutDir lets an entry write outside --out, and the drift gate compares each directory. `dotnet meta docs` prints the removed-command line; 1.0 docs flags on gen fail before writing. Python: metaobjects.config.yaml is the list. gen and verify --codegen are config-only; the positional --out form and --template-spec are not read (targets gain templateSpec). api-docs is a target entry with a top-level apiDocs block. `metaobjects docs` and a 1.0 docs block fail with the fixed lines. Moved-module aliases warn with FutureWarning naming 2.0, and the owned-router eject test compares lines in order. Docs, skills, fixture copies, the showcase script and the CHANGELOG follow. * feat(csharp,python)!: a template spec is declared in the generator list, never discovered One list means one declaration (ADR-0034 Amendment 9). C#: the owned runner no longer reads --template-spec or discovers a project-root template-spec.json; a spec runs as a TemplateSpecGenerator entry in codegen/Generators.cs (Spec, TemplateRoot, OutDir). A run that finds the 1.0 configuration with no such entry fails before writing, with a fixed line naming the migration section. Python already required a target's templateSpec; a leftover template-spec.json that no target declares now fails gen and verify --codegen the same way instead of being skipped. The C# migration section gains the template-spec before and after, and the port, concepts, own-your-codegen, cli and skill pages follow. * docs: five-port text for the api-docs note and stale docs-command comments after rebase * no-mistakes(review): Refuse legacy C# Program.cs; narrow verify drift; requirement-tests OutDir * no-mistakes(review): Fix narrowed verify, generators-key refusal, C# OutDir and template root * no-mistakes(review): Treat missing --out as empty tree; fix migration token, changelog * no-mistakes(review): Add generators: [] to Python templateSpec doc example * no-mistakes(review): Derive C# names gate from declared list, not narrowing * no-mistakes(document): Drop removed verify --docs flag; fix CHANGELOG garbled sentence; regen agent-context fixtures
1 parent c4a685c commit 0affc6a

124 files changed

Lines changed: 4565 additions & 2962 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.

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ PyPI has had no product change since `0.25.0` — nothing is broken.
6666
**All five ports ship loader + canonical serializer + conformance + codegen + render + payload-VO + `verify`:**
6767

6868
- **TypeScript** — `codegen-ts` (Vite-style plugins; Drizzle, Zod, Fastify) + `runtime-ts` + `migrate-ts` + the universal web client packages (`runtime-web`, `react`, `tanstack`).
69-
- **C#** — `MetaObjects` (loader + canonical serializer + conformance) + `MetaObjects.Render` (Mustache + payload-VO + `verify`) + `MetaObjects.Codegen` (EF Core entities + `AppDbContext` + CRUD minimal-API routes). Schema migrations are TS-owned (ADR-0015): the C# migrate engine and the `migrate`/`--from-db` CLI surface were removed; the C# CLI is `gen`/`verify` only, packaged as a .NET tool invoked **`dotnet meta`** (not a bare `meta` — that name belongs to the Node schema CLI). EF Core runtime data-access stays per-port.
69+
- **C#** — `MetaObjects` (loader + canonical serializer + conformance) + `MetaObjects.Render` (Mustache + payload-VO + `verify`) + `MetaObjects.Codegen` (EF Core entities + `AppDbContext` + CRUD minimal-API routes). Schema migrations are TS-owned (ADR-0015): the C# migrate engine and the `migrate`/`--from-db` CLI surface were removed; the C# CLI is codegen (`init`/`gen`/`eject`), `verify` and `fmt` only, packaged as a .NET tool invoked **`dotnet meta`** (not a bare `meta` — that name belongs to the Node schema CLI). EF Core runtime data-access stays per-port.
7070
- **Java** — `metadata` + `omdb` + `om` + `core-spring` + `metadata-ktx` (Kotlin facade) + `codegen-spring` (Spring controllers + DTOs + repositories + filter allowlists + payload records + output parsers) + `codegen-mustache` + `codegen-plantuml` + `render` + `maven-plugin` (`metaobjects:generate`/`metaobjects:editor` + a `metaobjects:verify` **codegen-drift** goal — distinct from the removed live-DB `metaobjects:verify`; Kotlin generators run through `metaobjects:generate` via the shared SPI). FR-003 (OMDB runtime persistence + binding registry + typed jsonb + Spring-tx + source/origin metamodel) fully shipped, including Plan 4 (engine-debt remediation: atomic mapping cache, JDBC codec registry, `inTransaction` template). **Schema migrations are owned by the TypeScript toolchain** (`@metaobjectsdev/cli migrate`); the Java port's diff-and-converge migration engine and its `metaobjects:migrate` / live-DB-drift `metaobjects:verify` Maven goals were removed, and per ADR-0015 Decision 2 the dev/test runtime auto-create path (`MetaClassDBValidatorService` + the drivers' `createTable`/`createIndex`/`createForeignKey`/`createSequence` DDL) is **also** removed — **OMDB is pure data-access** (CRUD/query/codec/transactions only).
7171
- **Python** — `metaobjects` (loader + canonical serializer + conformance + render + verify + codegen) + an `ObjectManager` runtime layer. The `migrate` module was removed (schema is TS-owned, ADR-0015); Python is pure data-access (codegen + ObjectManager runtime), with a **`metaobjects` console-script** (`gen`/`verify` codegen — no `migrate`). All five conformance corpora green.
7272
- **Kotlin** — `codegen-kotlin` (KotlinPoet on JVM): entity + Exposed table + Spring controller + payload + relations + filter allowlist + validator + stored-proc + output-parser generators. `integration-tests-kotlin` runs the persistence-conformance corpus through Exposed against Testcontainers Postgres.

‎CHANGELOG.md‎

Lines changed: 101 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -282,18 +282,17 @@ generator catalog and the Atlas evaluation are 1.2 work.
282282
the model (`FindInbound`, `TphPlan`, `InstanceArtifacts`, `ReportRows`). `template` is not
283283
ejectable: it has no emit logic of its own. Packaged output is unchanged and gated to be.
284284
- **`api-docs` is a generator you can own.** `dotnet meta eject api-docs` copies the page
285-
generator with its page model, builder, renderer and path math. `dotnet meta docs` hands
286-
off to `dotnet run --project codegen -- docs` once `codegen/generators/ApiDocsGenerator.cs`
287-
exists, so your copy writes the reference. What the reference documents is still what the
288-
packaged generators emit for (`GeneratorApplicability.Packaged`): an owned `routes` whose
285+
generator with its page model, builder, renderer and path math. The api reference is an
286+
entry in `codegen/Generators.cs` like any other (see **Removed**: `dotnet meta docs` is
287+
gone), with `OutDir`, `ApiSubDir`, `ProjectName` and `ModelBaseUrl` as init properties;
288+
`dotnet meta gen` writes the pages and `verify --codegen` checks them. List your copy in
289+
place of the packaged entry. What the reference documents is still what the packaged
290+
generators emit for (`GeneratorApplicability.Packaged`): an owned `routes` whose
289291
`AppliesTo` you changed is documented as the packaged one behaves, unless you edit the
290292
owned builder.
291-
`dotnet meta gen` and `verify --codegen` leave a docs generator out. `gen` says so only
292-
when a `--generators` selection names `api-docs`; an owned `Program.cs` that lists it runs
293-
without a warning.
294-
New public API in `MetaObjects.Codegen`: `IDocsGenerator`, `DocsRunFacts`,
295-
`GeneratorApplicability`, `GenContext.Applicability` and `GenContext.Docs`,
296-
`CodegenCli.RunDocs`, and `ValueObjectNames.ResolveValueObject` (moved from
293+
New public API in `MetaObjects.Codegen`: `GeneratorApplicability`,
294+
`GenContext.Applicability`, the `ApiDocsGenerator` init properties and
295+
`ApiDocsGenerator.DefaultApiSubDir`, and `ValueObjectNames.ResolveValueObject` (moved from
297296
`RenderHelperGenerator`, where it was `internal`). `CSharpStringLiteral` moved from
298297
`Fr010FieldMapping` to `CSharpNaming`, so `names` needs no emitter; the old member stays as an
299298
`[Obsolete]` forwarder (see **Deprecated**).
@@ -340,13 +339,14 @@ generator catalog and the Atlas evaluation are 1.2 work.
340339
`instance_artifacts`). `template` is not ejectable: it has no emit logic of its own. Packaged
341340
output is unchanged and gated to be.
342341
- **`api-docs` is a generator you can own.** `metaobjects eject api-docs` copies the page
343-
generator with its page model, builder, renderer and path math. The api reference is now a
344-
generator (`docs_surface = "api"`) that `metaobjects docs` runs: an owned copy is listed
345-
under the new `docs.generators` block of `metaobjects.config.yaml` and runs in place of the
346-
packaged one. `gen` and `verify --codegen` skip a docs generator they find under a target
347-
and say so: the packaged `api-docs` name is to be removed (`metaobjects docs` already runs
348-
it), an owned copy is to be listed under `docs.generators`. The reference asks `shared_predicates` which objects get a router (the new
349-
`emits_writable_router` and the moved `is_read_only_routed`, beside `emits_router`), the
342+
generator with its page model, builder, renderer and path math. The api reference is an
343+
ordinary generator listed in a target's `generators` (see **Removed**: `metaobjects docs`
344+
is gone), with its options in the new top-level `apiDocs` block of
345+
`metaobjects.config.yaml` (`apiSubDir`, `projectName`, `modelBaseUrl`); `metaobjects gen`
346+
writes the pages into that target's `outDir` and `verify --codegen` checks them. An owned
347+
copy is listed in place of `api-docs`. The reference reads `shared_predicates` to decide
348+
which objects get a router (the new `emits_writable_router` and the moved
349+
`is_read_only_routed`, beside `emits_router`), the
350350
module your owned `routes` and `filter-allowlist` read, so one edit to the owned predicate
351351
moves the router, the allowlist and the pages together. The cross-port manifest lists
352352
`api-docs` for `python`.
@@ -356,9 +356,10 @@ generator catalog and the Atlas evaluation are 1.2 work.
356356
`fr019_shared_enum`, `m2m_codegen`, and the api reference as `api_docs_model`,
357357
`api_docs_builder`, `api_docs_renderer` and `api_docs_paths`. `metaobjects.apidocs` keeps
358358
`naming` and exports `PythonApiModelBuilder`, `PythonApiDocsRenderer` and the path
359-
functions as before. New public API: `DocsRunFacts`, `GenContext.docs`, `DEFAULT_API_SUBDIR`
360-
and `DOCS_SURFACE_API` in `metaobjects.codegen.generator`, `ProjectConfig.docs_generators`,
361-
`GeneratorEntry.docs_surface`, and `metaobjects.codegen.docs_run`.
359+
functions as before. New public API: `DEFAULT_API_SUBDIR` in
360+
`metaobjects.codegen.generator`, `ApiDocsGenerator(api_subdir, project_name, model_base_url)`,
361+
`GeneratorBuildContext.api_docs`, and `ApiDocsConfig`, `ProjectConfig.api_docs` and
362+
`TargetConfig.template_spec` in `metaobjects.codegen.project_config`.
362363
- **A copy you ejected before this release** keeps running: it imports the emitters from
363364
their old paths, which are deprecated aliases (see **Deprecated**), so it calls the
364365
packaged emitters as it always did. `metaobjects gen --list` marks it `DIFFERS: N behind`.
@@ -383,7 +384,7 @@ generator catalog and the Atlas evaluation are 1.2 work.
383384
one documented difference). Another fails on a helper module no registry entry hands over,
384385
or a generator module no registry entry names.
385386
The nine Python entries of the shared eject contract's `eject.pending` list are closed, and the
386-
contract test runs `api-docs` through `metaobjects docs`, the way it is run.
387+
contract test runs `api-docs` through `metaobjects gen`, the way it is run.
387388

388389
- **The stock `entity`, `queries`, `routes` and `barrel` generators are importable again
389390
(TypeScript).** `entityFile`, `queriesFile`, `routesFile` and `barrel` are exported from
@@ -1070,15 +1071,92 @@ until you regenerate.
10701071
`metaobjects.codegen.extract_delegate_emitter`, `.fr010_field_mapping`,
10711072
`.output_format_spec_emitter`, `.extract_schema_emitter`, `metaobjects.codegen.generators.fr019_shared_enum`,
10721073
`.m2m_codegen`, and `metaobjects.apidocs.api_model`, `.builder`, `.renderer`, `.paths` are
1073-
each one-line modules that become the new module and warn (`DeprecationWarning`) on import.
1074+
each one-line modules that become the new module and warn (`FutureWarning`, which Python
1075+
shows by default, unlike a `DeprecationWarning` raised inside an imported module) on import.
10741076
Same objects, so nothing else changes; import from `metaobjects.codegen.runtime` (the api
10751077
reference modules are `api_docs_model`, `api_docs_builder`, `api_docs_renderer` and
1076-
`api_docs_paths` there). The old paths will be removed in a later release.
1078+
`api_docs_paths` there). The old paths will be removed in 2.0.
10771079
`metaobjects.codegen.generators.router_generator.is_read_only_routed` moved to
10781080
`metaobjects.codegen.runtime.shared_predicates`; the router module still re-exports it.
10791081

1082+
- **C#: `CodegenCli.ComposeGenerators` is `[Obsolete]`.** It composed an owned list with a
1083+
`--generators` selection by ADDING packaged generators the list did not name. Since 1.1.0 a
1084+
selection only narrows the declared list (`CodegenCli.SelectDeclared`, ADR-0034 Amendment 9),
1085+
and `CodegenCli.Run` no longer calls it. It still behaves as in 1.0 for a caller of its own.
1086+
10801087
### Removed
10811088

1089+
- **C#: `dotnet meta docs`, and `dotnet meta gen` without a generator list.** Every generator,
1090+
the api reference included, is an entry in `codegen/Generators.cs`, and `dotnet meta gen`
1091+
runs that list and nothing else (ADR-0034 Amendment 9). `dotnet meta docs` prints a line
1092+
naming `dotnet meta gen` and the migration section, and exits 2. `dotnet meta gen` and
1093+
`dotnet meta verify --codegen` in a project with no `codegen/Generators.cs` exit 2 with
1094+
`no codegen/Generators.cs` and write nothing: the in-process `gen <dir> --out <dir>
1095+
--generators <names>` form, which chose the generators on the command line, is gone. `gen`
1096+
given `--project` or `--model-base-url` (1.0 docs flags) fails with `found 1.0 docs
1097+
configuration` before writing anything.
1098+
- **New:** `dotnet meta init` writes `codegen/Generators.cs` (the list, a static `All`),
1099+
`codegen/Program.cs` (two lines: `using MetaObjects.Codegen;` and
1100+
`return CodegenCli.Run(args, Generators.All);`) and `codegen/Codegen.csproj`, each only
1101+
when missing; `dotnet meta eject` writes the same three files when they are missing, with
1102+
the copies it ejected already listed. `--generators` now narrows a run to declared entries
1103+
and refuses a name the list does not declare. Each entry may name its own output directory
1104+
(`IGenerator.OutDir`, a default interface member returning `null`, which writes under
1105+
`--out`), and `verify --codegen` compares each entry's directory; `RequirementTestsGenerator`
1106+
takes one (`OutDir`), so the xUnit tests go to the test project in the same run. A
1107+
`verify --codegen --generators` narrowing compares only what the named entries write. A
1108+
blank `--generators` exits 2 rather than running the whole list. The
1109+
owned runner now also refuses an unknown flag and an unknown `--baseline` value, as
1110+
`dotnet meta gen` did.
1111+
- **A 1.0 `codegen/Program.cs` is refused.** One that does not run `Generators.All` would
1112+
ignore the list, so `dotnet meta gen` and `verify --codegen` exit 2 with
1113+
`codegen/Program.cs does not run Generators.All` and write nothing; `init` and `eject` say
1114+
to replace it, and warn when `codegen/Codegen.csproj` pins an older `MetaObjects.Codegen`.
1115+
- **A template spec is an entry too.** `MetaObjects.Codegen.TemplateCodegen.TemplateSpecGenerator`
1116+
(`Spec`, `TemplateRoot`, `OutDir`) declares one in `codegen/Generators.cs`. `gen` and
1117+
`verify --codegen` no longer read `--template-spec` or discover a project-root
1118+
`template-spec.json`; a run that finds either with no such entry fails with
1119+
`found 1.0 template-spec configuration` before writing anything.
1120+
- Removed public API, all added after 1.0.13 and never released: `IDocsGenerator`,
1121+
`DocsRunFacts`, `GenContext.Docs`, `CodegenCli.RunDocs`, `CodegenCli.DocsOutcome`,
1122+
`CodegenCli.DocsGeneratorSkipped`, `CodegenHandoff.HasOwnedDocs`. `MetaObjects.Cli.DocsCommand`
1123+
(the removed command's logic) is gone with the command.
1124+
- **To upgrade**, run `dotnet meta init`, move each generator you ran into
1125+
`codegen/Generators.cs` with the api reference's flags as `ApiDocsGenerator` init
1126+
properties, and replace `dotnet meta docs` with `dotnet meta gen` in scripts: before and
1127+
after, and each flag's new home, are in
1128+
[docs-are-generators.md, "C#"](docs/features/migrations/docs-are-generators.md#c).
1129+
- **Python: `metaobjects docs`, and `metaobjects gen` without a config.** Every generator, the
1130+
api reference included, is an entry in a target's `generators` in `metaobjects.config.yaml`,
1131+
and `metaobjects gen` runs that list and nothing else (ADR-0034 Amendment 9). `metaobjects
1132+
docs` prints a line naming `metaobjects gen` and the migration section, and exits 2.
1133+
`metaobjects gen` and `metaobjects verify --codegen` with no `metaobjects.config.yaml` exit 2
1134+
with `no metaobjects.config.yaml` and write nothing: the positional
1135+
`gen <metadata_dir> --out <dir> --generators <names>` form and the no-config fallback are gone,
1136+
and with a config the positional `<metadata_dir>` and `--out` are refused with a line naming
1137+
`metadata` and the targets' `outDir`. A config with a top-level `docs` block fails `gen` and
1138+
`verify --codegen` with `found 1.0 docs configuration` before anything is written.
1139+
- **New:** the top-level `apiDocs` block (`apiSubDir`, `projectName`, `modelBaseUrl`) carries
1140+
the api reference's options, and a target's `templateSpec: <path>` declares a template-spec
1141+
whose generators write into that target, replacing the `--template-spec` flag, which is now
1142+
refused. A project-root `template-spec.json` that no target declares, which the 1.0 flag form
1143+
found on its own, fails `gen` and `verify --codegen` with
1144+
`found 1.0 template-spec configuration`. `--generators` narrows a run to declared entries and refuses a name no target
1145+
declares; `--column-naming`, `--entities`, `--provider`, `--templates` and `--baseline` now
1146+
apply to the config's list.
1147+
- **New refusals.** A target with no `generators` key exits 2 with the migration line
1148+
(`generators: []` still writes nothing and says so). An `--entities` name that matches no
1149+
object exits 2, where it used to warn and exit 0. A blank `--generators` (an unset shell
1150+
variable) exits 2 rather than running the whole list. A `generators` entry holding a comma
1151+
(`"entity, routes"`) is refused: list each generator as its own entry.
1152+
- Removed public API, all added after 1.0.13 and never released: `DocsRunFacts`,
1153+
`GenContext.docs`, `DOCS_SURFACE_API`, `ProjectConfig.docs_generators`,
1154+
`GeneratorEntry.docs_surface` and the `metaobjects.codegen.docs_run` module.
1155+
- **To upgrade**, list each generator in a target of `metaobjects.config.yaml`, `api-docs` in a
1156+
target whose `outDir` is the docs directory, move the docs flags into `apiDocs`, and replace
1157+
`metaobjects docs` with `metaobjects gen` in scripts: before and after, and each flag's new
1158+
home, are in
1159+
[docs-are-generators.md, "Python"](docs/features/migrations/docs-are-generators.md#python).
10821160
- **Java and Kotlin: the `metaobjects:docs` goal.** Documentation is generated the way code
10831161
is: the api reference is a `JavaApiDocsGenerator` or `KotlinApiDocsGenerator` `<generator>`
10841162
entry in the list `metaobjects:generate` runs, with its options in `<args>` (see

0 commit comments

Comments
 (0)