Repository navigation
feat: publish shared models from Java, Kotlin and C# projects - #540
Merged
Merged
Conversation
Adds a shared-model generator to the Java/Kotlin Maven goals and to the C# CLI, each ejectable, byte-identical to the TypeScript publisher and gated by the shared-model publish corpus. The registry now lists java, kotlin and csharp.
C#: read the project <Version> property only (not a PackageReference's), resolve Files against an input root so verify --codegen matches gen, and classify any re-load failure as non-core-vocabulary. Java/Kotlin: a blank version arg falls back to the project version.
The Maven mojo supplies the project version as a default 'version' arg, so the ProjectVersionAware hook goes away; path resolution and closure check tidied.
…ersion/files args
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Changed
shared-modelgenerator to the Javacodegen-basemodule and the C#MetaObjects.Codegenpackage. Each writes<name>.metaobjects.jsonandmetaobjects.pkg.json, byte-identical to the TypeScriptsharedModelFile()and gated byfixtures/shared-model-conformance/. The engines (SharedModelin Javametadata,MetaObjects.Config.SharedModelin C#) stay in the package and out of the ejected copy.KotlinSharedModelGenerator, a thin Kotlin wrapper over the Java engine. Java and Kotlin run it throughmetaobjects:generate(version from<version>) and eject it withmvn metaobjects:eject. C# declaresSharedModelGenerator(version from<Version>) and ejects it withdotnet meta eject shared-model.generator-registry-conformancelistsjava,kotlinandcsharpundershared-model. The sweep tests skip the Java/Kotlin shared-model generator because it writes no code and needs file arguments. Also updates the CHANGELOG Unreleased section,docs/ports/{csharp,java,kotlin}.md, and the Java/Kotlin/C# rows inmetadata-dependencies.mdandCONFORMANCE.md.Validation
Risk Assessment
✅ Low: The fix round is small and correct: the C# generator now rejects MSBuild
$(...)versions, and the new Maven mojo tests coverfilesandversionhandling. The changed generators are thin and delegate artifact bytes to the in-package engines. I did not read the engines or the other changed files, so low risk covers only what I reviewed.Testing
Baseline ts-fast/ts-unit given. Targeted Java and C# shared-model tests pass. Live driving: Java SharedModelGenerator and C# SharedModelGenerator both publish the acme-common model with bytes matching fixtures/shared-model-conformance (artifact exact, manifest exact after placeholder substitution). Adversarial refusals verified live: C# rejects MSBuild-expression version (the review fix), both ports refuse a missing version and a missing include. Full C# solution and full Java reactor suites pass. Not live: Maven mojo default-version and relative-files resolution (unit tests only; running the plugin needs installing into the local Maven repository, outside the worktree), Kotlin KotlinSharedModelGenerator (unit tests only), and dotnet/mvn eject round trips (contract tests only). Overall: pass.
Evidence: C# MSBuild-version harness project (refused live)
Evidence: Java targeted test log
The raw log is left out of this description: it only repeated local scratch paths. The result is in the summary above.
Pipeline
Updates from git push no-mistakes
✅ **Intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 4 issues found → auto-fixed ✅
server/csharp/MetaObjects.Codegen/Generators/SharedModelGenerator.cs:115- SharedModelGenerator.VersionIn takes the raw text of <Version> with no MSBuild evaluation. A project that writes <Version>$(VersionPrefix)-beta</Version> or <Version>$(Major).$(Minor).0</Version> gets the literal string "$(VersionPrefix)-beta" in metaobjects.pkg.json. No error is raised, so the manifest records a wrong version silently. Fix: treat a value that contains "$(" as not a version (return null). The existing "no version available" error then asks for an explicit Version.server/java/maven-plugin/src/main/java/com/metaobjects/mojo/AbstractMetaDataMojo.java:599- The real Maven path depends on two new behaviours in AbstractMetaDataMojo, and no test covers either one. First, mergeAndOverwriteArgs defaultsversionfrom ${project.version} with putIfAbsent (line 599). Second,filesis resolved element by element against the module basedir through PATH_LIST_ARGS (line 626). The generator tests passversionand absolutefilesby hand, so they skip both. RelativeGeneratorArgPathsTest exists but was not extended. If the putIfAbsent is lost, everymetaobjects:generatepublish fails with "no version available". If the list resolution regresses, a relativefilesentry resolves against the shell's working directory, and the generator reads the wrong files or none. Fix: add mojo-level cases that use a stub project. Assert that a relative comma-separatedfilesresolves under basedir. Assert thatversiondefaults to the project version, and that an explicit arg overrides it.server/csharp/MetaObjects.Codegen.Tests/SharedModelGeneratorTests.cs:73- Three SharedModelGeneratorTests cases check the version with a raw substring over the emitted manifest JSON:Assert.Contains("\"version\": \"2.3.4\"", manifest)at lines 73, 112 and 123. This is the substring-over-JSON pattern that the test-quality rule flags. A version that appears elsewhere in the manifest would also pass, and a formatting change would fail with no change in meaning. Fix: parse the manifest (JsonDocument) and assert that theversionproperty equals the expected value.server/java/codegen-kotlin/src/test/kotlin/com/metaobjects/generator/kotlin/EjectContractTest.kt:231- In the Kotlin EjectContractTest, modelFiles() was inserted between the existing KDoc "Loaded once and shared by both sides. A loader's name is an identifier." and theloaderproperty that KDoc documents. That KDoc is now orphaned in front of modelFiles' own KDoc. Fix: move the new function above theloaderKDoc.🔧 Fix applied.
✅ Re-checked - no issues remain.
server/java/codegen-base/src/main/java/com/metaobjects/generator/SharedModelGenerator.java:65- Java shared-model accepts an explicit version arg such as "$(VersionPrefix)-beta" and writes it verbatim. The review fix that rejects MSBuild-expression versions landed only in the C# generator, which is the port the finding named. The Maven path is unaffected because ${project.version} is already interpolated by Maven.scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchainsBaseline (given): scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchainscd server/csharp && dotnet test --filter FullyQualifiedName~SharedModel (9 passed)cd server/java && mvn -o -pl metadata,codegen-base,maven-plugin,codegen-kotlin -am test -Dtest='SharedModel*,RelativeGeneratorArgPathsTest,EjectContractTest,EjectRuntimeRoundTripTest,NoMagicPhysicalNamesTest,ReportingInertTest,GeneratorRegistry*' (all pass)LIVE Java: javac a scratch driver against codegen-base/target/classes; ran SharedModelGenerator.execute via a MetaDataLoader over fixtures/shared-model-conformance with version-ok, version-msbuild, no-include, no-version. Artifact cmp == fixtures/dependency-conformance/artifacts/acme-common-v1.json; manifest cmp == expected manifest after @@METAMODEL_VERSION@@ -> 1.3.LIVE C#: disposable console harness a scratch directory referencing MetaObjects.Codegen.csproj; ran SharedModelGenerator.Generate with project <Version>1.0.0</Version> (artifact and manifest byte-match fixtures), <Version>$(VersionPrefix)-beta</Version> (refused: no version available), and no <Version> (refused).cd server/csharp && dotnet test (full solution: Render 364, Conformance 2331, Cli 370, Codegen 1315 passed, 1 skipped, 0 failed)cd server/java && mvn -o test (full reactor, excluding nothing; BUILD SUCCESS, 0 failures; integration-tests not in reactor so not run)agent-context/skills/metaobjects-codegen/references/dependencies-and-shared-models.md- Still says only the TypeScript toolchain publishes a shared model. Skills/agent-context close-out is S10, which the user placed out of scope for this change.✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
no-mistakes gate: 1 run (review fixes applied in-run; CI step skipped, local CI is the result).