Skip to main content

Gradle Plugin

The plugin lives at dev.kensa.gradle-plugin on the Gradle Plugin Portal. It does three things:

  1. Applies the Kensa Kotlin compiler plugin to the configured sourcesets so @RenderedValue and @ExpandableSentence capture works at compile time.
  2. Adds an implicit dev.kensa:kensa-core runtime dependency to those compilations (so you don't have to declare it manually).
  3. When site mode is on, wires kensa.output.root / kensa.source.id system properties onto each sourceset's Test task and registers an assembleKensaSite task to produce a single multi-source viewable site.

Apply

build.gradle.kts — apply the plugin
loading...

The plugin embeds the kensa-core / kensa-compiler-plugin coordinates it was built against, so you don't need to declare them manually. Since plugin v0.9.0, plugin and kensa-core version independently — see the compatibility matrix below if you want to pin a different kensa-core.

kensa-core compatibility

PluginDefault kensa-coreMin kensa-coreNotes
0.9.30.8.30.8.0Adds multi-module site aggregation — applying the plugin to the rootProject with site = true aggregates every kensa-enabled subproject's sources into a single site at <rootDir>/build/kensa-site/. See Site Mode — Multi-module builds.
0.9.20.8.30.8.0Default kensaCoreVersion bumped to 0.8.3 so site-mode aggregation picks up the parameterised test display, sidebar tree expand/collapse toolbar, and absolute-path console banner without each project having to override.
0.9.0–0.9.10.8.00.8.0Plugin and kensa-core versioned independently; site-mode ergonomics (sourceTitles DSL, auto-assemble) added in 0.9.1
0.7.x0.7.xSame-version pairing (no override)

v0.8.0 was withdrawn from the Gradle Plugin Portal — its POM declared an unpublished dev.kensa:site-common dep. Use 0.9.0 or later.

Override the default with kensaCoreVersion:

kensa {
kensaCoreVersion.set("0.8.1")
}

No upper bound — newer kensa-core versions are assumed compatible until proven otherwise. A version below the minimum fails fast at apply time.

DSL

Configure via the kensa { … } extension:

PropertyTypeDefaultEffect
enabledBooleantrueMaster switch. When false, the compiler plugin is not applied and no kensa-core dep is added.
debugBooleanfalseForwards debug=true to the compiler plugin (verbose logs during compilation).
sourceSetsSet<String>setOf("test")Which sourcesets/test-tasks Kensa attaches to.
siteBooleanfalseEnable site mode (see Site Mode). On the rootProject of a multi-project build, also acts as the opt-in for multi-module aggregation (since 0.9.3).
siteRootDirectorybuild/kensa-siteSite-mode output root. In multi-module aggregator mode this is the rootProject's path; contributor subprojects' siteRoot is overridden to write into this shared directory.
kensaCoreVersionStringbundled defaultOverride the kensa-core / kensa-compiler-plugin version the plugin resolves. See compatibility matrix.
sourceTitlesMap<String, String>emptyPer-source display labels for site mode, keyed by source id. Entries override the titleText the test runtime wrote to that source's configuration.json. See Site-mode source titles. Added in 0.9.1.

Example with multiple sourcesets in site mode:

build.gradle.kts — kensa { } block
loading...

Behaviour

For each name in sourceSets, the plugin looks up a Test task with the same name. When found:

  • A dev.kensa:kensa-core dependency is added to that compilation's classpath via Kotlin's compiler-plugin support.
  • If site = true:
    • kensa.output.root / kensa.source.id are passed to the test task's JVM via a CommandLineArgumentProvider (since 0.9.1). The per-source bundle dir is declared as a Test @OutputDirectory — Gradle tracks it correctly, UP-TO-DATE checks become accurate, and absolute paths don't enter the cache key (friendly to shared / remote Gradle build caches).
    • kensa.source.id defaults to the sourceset name, unless you've already set it explicitly — see overrides.
    • The assembleKensaSite task is registered. Each configured Test task is finalizedBy(assembleKensaSite), so running any of them refreshes the site automatically (since 0.9.1). assembleKensaSite itself uses mustRunAfter (not dependsOn) — invoking it standalone aggregates whatever bundles are on disk without re-running tests.

The compiler plugin is only applied to compilations whose name appears in sourceSets. Other sourcesets compile normally without Kensa.

Site-mode source titles

Set per-source display labels via the sourceTitles map. Entries here override whatever the test runtime wrote to that source's configuration.json (and rewrite the file so the standalone per-source HTML page <title> matches the manifest sidebar label).

kensa {
site = true
sourceSets = setOf("test", "uiTest")
sourceTitles["uiTest"] = "UI Tests"
sourceTitles["test"] = "Unit Tests"
}

Or set the whole map at once:

kensa {
site = true
sourceSets = setOf("test", "uiTest")
sourceTitles = mapOf(
"uiTest" to "UI Tests",
"test" to "Unit Tests",
)
}

Precedence when more than one path declares a title for the same source id:

  1. kensa { sourceTitles.put(id, ...) } — build DSL, wins
  2. Kensa.konfigure { titleText = "..." } in code (e.g. a per-sourceset base class) — wins when no build entry. Works in site mode because each Gradle Test task forks its own JVM, so per-sourceset Configuration singletons are isolated.
  3. kensa.source.title system property — legacy, soft-deprecated since 0.9.1.
  4. "Index" / source id fallback when none of the above is set.

Per-source overrides

Any per-task systemProperty you set in your build script flows through to the test task's JVM as a -D argument. Source-id overrides still work the same way — useful for CI-driven id schemes:

tasks.named<Test>("uiTest") {
systemProperty("kensa.source.id", "${System.getenv("BUILD_NUMBER") ?: "local"}-uiTest")
}

For per-source titles, prefer the sourceTitles extension map over systemProperty("kensa.source.title", ...) — declarative, build-cache-friendly, and works for downstream consumers without a per-task hook.

Tasks added

TaskGroupDescription
assembleKensaSiteverificationAggregates all per-source bundles in siteRoot/sources/<id>/ into a single viewable site. mustRunAfter every configured Test task (since 0.9.1 — was dependsOn prior). Only registered when site = true.

assembleKensaSite is @CacheableTask — its inputs are the per-source configuration.json files plus the resolved kensa-core jar's content. Re-running with no changes is UP-TO-DATE; republishing kensa-core to your local maven invalidates the cache and re-extracts the new shell.

Since 0.9.1, every configured Test task is finalizedBy(assembleKensaSite)gradle test (or any configured Test task) refreshes the aggregated site automatically as a finalizer. The finalizer runs once after all participating tests complete, regardless of pass/fail (a partial site is useful when triaging failures). Standalone gradle assembleKensaSite aggregates from disk without forcing a Test re-run.

Source ID collisions

If two configured Test tasks resolve to the same kensa.source.id, the build fails fast with an actionable error pointing at how to disambiguate:

Kensa site mode: source id collision on 'foo' (multiple sourcesets / test tasks resolve to the same kensa.source.id).
Override one explicitly: tasks.named<Test>("<name>") { systemProperty("kensa.source.id", "<unique>") }

In a multi-module aggregator build, contributors' source ids are automatically prefixed by a slug derived from the project path (:webweb__test), so two subprojects can both have a test source set without colliding. See Site Mode — Namespaced source ids.

Maven plugin

Maven users — see the Maven plugin page. The assemble-site mojo provides the same site-mode aggregation; per-source bundles are driven by systemPropertyVariables on each surefire/failsafe execution.