Gradle Plugin

The Gradle plugin contributes three tasks to any Gradle build: kumlRender, kumlGenerate, and kumlValidate. All three are @CacheableTask with proper @InputDirectory / @OutputDirectory annotations — incremental builds skip unchanged scripts.

The dev.kuml Gradle plugin is published on the Gradle Plugin Portal and on Maven Central (group dev.kuml, artefact kuml-gradle-plugin) since v0.32.0.

Apply the plugin

// build.gradle.kts
plugins {
    id("dev.kuml") version "{kuml-version}"
}

That’s all you need to get the three tasks registered. Defaults are sensible:

  • Source directory: src/main/kuml/

  • Output directory: ${buildDir}/kuml/

  • Format: svg

  • Theme: kuml

  • Generator: kotlin

Override any of these in the kuml { …​ } extension block.

Configuration block

kuml {
    sourceDir.set(file("src/main/kuml"))
    outputDir.set(layout.buildDirectory.dir("kuml"))
    format.set("svg")                         // "svg" | "png"
    theme.set("elegant")                      // any ThemeRegistry name
    widthPx.set(2048)                         // PNG width (ignored for SVG)
    generator.set("java")                     // "kotlin" | "java" | "sql" | custom
    generatePackage.set("com.example.domain") // Java/Kotlin package
    generateOptions.put("java-style", "records")
    generateOptions.put("sql-dialect", "postgres")
    failOnValidationViolations.set(true)      // fail the build on OCL violations
}

Every property is a Gradle lazy Property / DirectoryProperty / MapProperty — you can wire them to project conventions, settings, or other tasks.

kumlRender

./gradlew kumlRender

Walks sourceDir for *.kuml.kts files and renders each to outputDir, mirroring the source’s directory structure:

src/main/kuml/
├── order.kuml.kts
└── billing/
    └── invoice.kuml.kts

# →

build/kuml/
├── order.svg
└── billing/
    └── invoice.svg

Inputs (cacheable):

  • sourceDir (PathSensitive=RELATIVE)

  • format, theme, widthPx

Outputs:

  • outputDir

A second ./gradlew kumlRender with no source changes is UP-TO-DATE.

kumlGenerate

./gradlew kumlGenerate

Runs the configured generator over every diagram in sourceDir. C4 scripts are skipped automatically (only UML diagrams produce code). Output goes to outputDir/generated/ by default.

Wire into other tasks:

tasks.named<JavaCompile>("compileJava") {
    dependsOn("kumlGenerate")
    source(layout.buildDirectory.dir("kuml/generated"))
}

For Kotlin source, point srcDirs of the main source set at the same directory.

kumlValidate

./gradlew kumlValidate

Runs OclValidator over every *.kuml.kts in sourceDir. Hangs on to the build’s check lifecycle:

plugins {
    id("dev.kuml")
    java
}
// check automatically depends on kumlValidate

If failOnValidationViolations = true (default), violations fail the build with a human-readable error listing each violation. If false, the same information is logged as a warning but the build continues — useful for grace-period rollouts.

Multi-project builds

In a multi-project build, apply the plugin only to the projects that own kUML scripts:

// settings.gradle.kts
include(":app", ":domain", ":docs")

// docs/build.gradle.kts
plugins {
    id("dev.kuml")
}
kuml {
    sourceDir.set(file("src/main/kuml"))
    outputDir.set(layout.buildDirectory.dir("kuml"))
}

The plugin is self-contained — no parent project configuration needed.

Reproducibility

The Gradle plugin uses the same scripting host, layout engines, themes, and generators as the CLI. Outputs are byte-identical:

diff <(kuml render src/main/kuml/order.kuml.kts) build/kuml/order.svg
# (no output — files are identical)

That makes CI cache invalidation straightforward: a commit that changes a *.kuml.kts invalidates the corresponding output; everything else stays cached.

Building the plugin from source

The published plugin (see above) is the recommended path for consumers. If you need an unreleased fix or are developing the plugin itself, publish a local copy instead:

./gradlew :kuml-gradle:kuml-gradle-plugin:publishToMavenLocal

Then in your consumer build’s settings.gradle.kts:

pluginManagement {
    repositories {
        mavenLocal()
        gradlePluginPortal()
    }
}

Apply as usual: id("dev.kuml") version "X.Y.Z-SNAPSHOT".