Languages and Ecosystems
How one Kotlin core writes four languages and reaches the JVM, .NET and Node. The reasons are recorded in ADR 007 and ADR 014; modules and layers are on Architecture.
Two ways into core
Every language is written in core; an entry point only chooses one.
- Directly. The Gradle plugin, the Maven plugin and the web app run on the JVM anyway and call core's
*Pluginclasses in their own process. - Through the command-line tool. Everything outside the JVM starts the CLI
bpmn-to-code, which calls the same*Pluginclasses. The .NET and npm packages contain no generator, only the CLI jars and a launcher that starts them on Java 21 fromJAVA_HOMEor thePATH:
| Package | Launcher | How a project uses it |
|---|---|---|
Miragon.BpmnToCode | Program.cs of a .NET tool | dotnet tool exec, or the MSBuild package, which runs it before the project compiles and brings the runtime of the same version |
@miragon/bpmn-to-code | launcher.js, registered under bin | bpmn-to-code generate-api … in a package.json script; the runtime is a peer dependency of exactly the same version |
| Release archive, Homebrew | bin/bpmn-to-code | Anywhere else; the archive bundles its own Java runtime (jlink) |
Per language
| Language | Rendered by | Runtime types | Generated in its ecosystem by | Checked by |
|---|---|---|---|---|
| Kotlin | builder/kotlin, templates/kotlin | io.miragon:bpmn-to-code-runtime (Maven Central) | Gradle or Maven plugin | Golden files; compiled in NestedSubProcessCompilationTest |
| Java | builder/java, templates/java | io.miragon:bpmn-to-code-runtime (Maven Central) | Gradle or Maven plugin | Golden files; compiled in JavaProcessApiBuilderTest |
| C# | builder/csharp, templates/csharp | Miragon.BpmnToCode.Runtime (NuGet) | Miragon.BpmnToCode.MSBuild during dotnet build, or the .NET tool Miragon.BpmnToCode | Golden files; dotnet test in packages/nuget/BpmnToCode.Runtime.Tests |
| TypeScript | builder/typescript, templates/typescript | @miragon/bpmn-to-code-runtime (npm) | @miragon/bpmn-to-code in an npm script | Golden files; npm test in packages/npm/bpmn-to-code-runtime |
A builder maps the language-neutral graph to a template model and handles keywords, escaping and imports; the FreeMarker template writes the code around it. CodeGenerationAdapter picks the builders of a language from one map.
Where the parts live
text
bpmn-to-code-core/src/main/
├─ kotlin/io/miragon/bpmn/adapter/outbound/codegen/
│ ├─ flow/, definitions/ language-neutral graphs
│ └─ builder/<language>/ graph → template model, syntax, imports
└─ resources/io/miragon/bpmn/codegen/templates/<language>/ FreeMarker templates
bpmn-to-code-core/src/test/resources/api/ golden files per language
bpmn-to-code-runtime/ runtime types for Kotlin and Java
bpmn-to-code-cli/ command-line tool and its archives
packages/nuget/ BpmnToCode.Runtime (+ .Tests), BpmnToCode.Tool, BpmnToCode.MSBuild
packages/npm/ bpmn-to-code-runtime (+ test/), bpmn-to-codeBuild and release
| Workflow | What it does |
|---|---|
build-backend.yml | Runs the Gradle build on the JVM alone and smoke-tests the CLI archive |
build-packages.yml | When core, the CLI or packages/ change: builds the CLI and runs the package tests, which generate C# and TypeScript with it and compile and run them against the runtime packages |
publish-cli.yml | Builds and starts one archive per platform and attaches it to the release |
publish-homebrew.yml | Updates the formula in Miragon/homebrew-tap for a stable release |
publish-to-nuget.yml | Packs the three NuGet packages, smoke-tests tool and MSBuild, pushes them only once the repository variable PUBLISH_NUGET is true |
publish-to-npm.yml | Stages both npm packages, smoke-tests them on three operating systems, publishes them only once PUBLISH_NPM is true |
release-please.yml calls all of them; every artifact carries the one version of gradle.properties (ADR 011). Details in Releasing.
Adding a language
- A value in
OutputLanguage, which Gradle, Maven and the CLI accept from then on, and an option in the form of the web app. - A package
builder/<language>and a foldertemplates/<language>, registered inCodeGenerationAdapter. - Golden files under
src/test/resources/api/, and tests next to the runtime package that compile the output with the language's own compiler. - A runtime package in the language's registry, if the output refers to runtime types, and a package that starts the CLI there.
- A getting-started page and a line in ADR 007.