Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
name: Check

on: pull_request
on:
pull_request:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
runs-on: ${{ matrix.os }}
timeout-minutes: 15

steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Set Up Java 17 for Compatibility Tests
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 17

- name: Save Java 17 Toolchain
shell: bash
run: echo "EMBED_CODE_JAVA_17_HOME=$JAVA_HOME" >> "$GITHUB_ENV"

- name: Set Up Java
- name: Set Up Java 25
uses: actions/setup-java@v5
with:
distribution: temurin
Expand All @@ -21,4 +45,8 @@ jobs:
uses: gradle/actions/setup-gradle@v6

- name: Build
run: ./gradlew build
shell: bash
run: >-
./gradlew
-Dorg.gradle.java.installations.paths="$EMBED_CODE_JAVA_17_HOME"
build :gradle-plugin:publishToMavenLocal
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.gradle/
.kotlin/
.idea/
*.iml
**/build/
Expand Down
147 changes: 147 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
[![Build on Ubuntu and Windows][build-badge]][gh-actions]
[![license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)

# Embed Code Gradle plugin

Gradle plugin for [Embed Code][embed-code], an application that keeps code
examples in Markdown and HTML synchronized with their source files.

The plugin downloads the released Embed Code executable for the current
platform, so developers and CI jobs do not have to install it manually. It
adds two tasks:

- `checkEmbedding` checks that embedded code is up to date.
- `embedCode` updates embedded code in place.

## Requirements

- Java 17 or a newer version supported by the selected Gradle version.
- Gradle 8.14.4 or newer.
- Linux AMD64, Windows AMD64, or macOS AMD64/ARM64.

Consumers do not need to install Kotlin or apply a Kotlin plugin.
The plugin is written in Kotlin, but uses the Kotlin runtime supplied by Gradle.

## How to use

This section describes how to use the plugin. For information about the Embed
Code application itself, see its [documentation][embed-code].

Add the following configuration to the project's `build.gradle.kts`:

```kotlin
plugins {
id("io.spine.embed-code") version "0.1.0" // Specify the actual version here.
}

embedCode {

// Specify the directory containing source files referenced by embedding instructions.
//
// This property is required unless `namedSource(...)` is used.
//
codePath.set(layout.projectDirectory.dir("src/main/java"))

// Specify the directory containing Markdown or HTML documentation.
//
// This property is required.
//
docsPath.set(layout.projectDirectory.dir("docs"))

// Configure documentation files to include and exclude.
//
// This section is optional. The default includes are `**/*.md` and
// `**/*.html`; the default excludes list is empty.
//
docIncludes.set(listOf("**/*.md", "**/*.html"))
docExcludes.set(listOf("drafts/**", "generated/**"))

// Configure other Embed Code command-line options.
//
// This section is optional. The values below are the defaults.
//
separator.set("...")
info.set(false)
stacktrace.set(false)
}
```

Use named source roots when documentation embeds code from multiple modules:

```kotlin
embedCode {
namedSource(
"model",
layout.projectDirectory.dir("model"),
)
namedSource(
"database",
layout.projectDirectory.dir("database"),
)
docsPath.set(layout.projectDirectory)
}
```

Embedding instructions refer to these roots with `$model/` and
`$database/`. `codePath` and `namedSource(...)` are mutually exclusive.

By default, the plugin checks the latest Embed Code release before running a task.
It reuses the executable in `build/embed-code/latest` while the release
version remains unchanged and downloads a new executable only after a new
release is published. When the release check fails, for example without
network access, the plugin reuses the previously installed executable.

To use a specific Embed Code application release, add its version to the extension:

```kotlin
embedCode {
version.set("1.2.4")
}
```

Check that documentation is up to date:

```bash
./gradlew :checkEmbedding
```

Update documentation:

```bash
./gradlew :embedCode
```

The plugin prefers the `checkEmbedding` and `embedCode` task names. If a name
is already occupied when the plugin is applied, underscores are prepended until
an available name is found, for example `_embedCode` or `__embedCode`.
The fallback cannot account for a conflicting task registered later.

## Development

Run compilation, plugin validation, and the complete test suite:

```bash
./gradlew check
```

Fast unit tests run under `test`. TestKit coverage runs separately under
`functionalTest`; the `check` task includes both.

To test the plugin in another project, publish it to the local Maven repository:

```bash
./gradlew :gradle-plugin:publishToMavenLocal
```

In this case, add `mavenLocal()` to `pluginManagement.repositories` in the
consuming project's `settings.gradle.kts`. Adding it only to the regular
`repositories` block does not make Gradle plugin markers available to the
`plugins` block.

## License

The plugin is available under the [Apache License 2.0](LICENSE).

[build-badge]: https://github.com/SpineEventEngine/embed-code-gradle-plugin/actions/workflows/check.yml/badge.svg
[embed-code]: https://github.com/SpineEventEngine/embed-code-go
[gh-actions]: https://github.com/SpineEventEngine/embed-code-gradle-plugin/actions
12 changes: 12 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,20 @@ plugins {
*/
val kotlinVersion = "2.4.10"

/**
* Version of the Gradle Plugin Publish plugin.
*
* `buildSrc` needs this version before its dependency objects are compiled.
* Keep in sync with `io.spine.embedcode.gradle.dependency.PluginPublish.version`.
*/
val pluginPublishVersion = "2.1.1"

dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
implementation(
"com.gradle.plugin-publish:com.gradle.plugin-publish.gradle.plugin:" +
pluginPublishVersion,
)
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@

package io.spine.embedcode.gradle

/** Build-wide Java and bytecode targets. */
/**
* Build-wide Java and bytecode targets.
*/
object BuildSettings {

/** Java toolchain version used to build and test the project. */
const val javaVersion = 25

/**
* JVM bytecode version produced for published code.
* JVM bytecode version produced by the project.
*
* Java 8 bytecode keeps the plugin loadable by the minimum supported Gradle
* version, 7.6.3, while builds and tests use Java 25.
* Java 17 is supported by Gradle 8.14.4 and required by Gradle 9.
*/
const val productionBytecodeVersion = 8
const val bytecodeVersion = 17
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@

package io.spine.embedcode.gradle.dependency

/** JUnit dependencies used by tests. */
/**
* JUnit dependencies used by tests.
*/
object JUnit {

const val version = "6.1.1"
const val version = "6.1.2"
private const val group = "org.junit.jupiter"

// https://github.com/junit-team/junit5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@

package io.spine.embedcode.gradle.dependency

/** Kotlin dependencies used by the project. */
/**
* Kotlin dependencies used by the project.
*/
object Kotlin {

const val version = "2.4.10"
Expand Down
26 changes: 15 additions & 11 deletions buildSrc/src/main/kotlin/jvm-module.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,14 @@
import io.spine.embedcode.gradle.BuildSettings
import io.spine.embedcode.gradle.dependency.JUnit
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion

plugins {
`java-library`
kotlin("jvm")
}

fun jvmTarget(version: Int): JvmTarget = JvmTarget.fromTarget(
if (version == 8) "1.$version" else version.toString(),
)
fun jvmTarget(version: Int): JvmTarget = JvmTarget.fromTarget(version.toString())

java {
toolchain {
Expand All @@ -45,18 +43,19 @@ java {
}

kotlin {
explicitApi()
compilerOptions {
jvmTarget.set(jvmTarget(BuildSettings.productionBytecodeVersion))
jvmTarget.set(jvmTarget(BuildSettings.bytecodeVersion))
// Gradle 8.14.4 embeds Kotlin 2.0.21. Keep plugin metadata and
// standard-library API usage compatible with that runtime.
languageVersion.set(KotlinVersion.KOTLIN_2_0)
apiVersion.set(KotlinVersion.KOTLIN_2_0)
freeCompilerArgs.add("-Xjsr305=strict")
}
}

tasks.named<JavaCompile>("compileJava") {
options.release.set(BuildSettings.productionBytecodeVersion)
}

tasks.named<KotlinJvmCompile>("compileTestKotlin") {
compilerOptions.jvmTarget.set(jvmTarget(BuildSettings.javaVersion))
tasks.withType<JavaCompile>().configureEach {
options.release.set(BuildSettings.bytecodeVersion)
}

dependencies {
Expand All @@ -66,4 +65,9 @@ dependencies {

tasks.test {
useJUnitPlatform()
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(BuildSettings.bytecodeVersion))
},
)
}
Loading