Skip to content
Draft
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
8 changes: 7 additions & 1 deletion PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ them inside code fences, and checks whether existing snippets are up-to-date.
- `embedding/commentfilter/`: language-aware comment-retention filtering.
- `fragmentation/`: whole-file, named-fragment, and line-pattern extraction;
source lookup; partition assembly; encoding checks; and caches.
- `gradle-plugin/`: Gradle plugin build, automatic release-binary installation,
check/embed tasks, Kotlin DSL configuration, and TestKit tests.
- `files/`: filesystem validation and file helpers.
- `indent/`: shared indentation measurement and removal.
- `logging/`: `slog` handler, clickable file references, panic reporting, and
Expand All @@ -39,6 +41,8 @@ them inside code fences, and checks whether existing snippets are up-to-date.

- `README.md`: project entry point, short run/build instructions, and links to
the complete guide.
- `gradle-plugin/README.md`: Gradle plugin application, configuration, task,
compatibility, and development guide.
- `showcase/README.md`: complete user guide entry point and runnable workflow.
- `showcase/configuration/README.md`: command-line flags, YAML configuration,
source roots, include/exclude patterns, and multiple embedding targets.
Expand All @@ -56,7 +60,9 @@ this file. Keep the root README short.
This repository is configured with these GitHub workflows:

- `check`: runs linting, the normal Go test suite, and the showcase end-to-end
tests across supported platforms.
tests across supported platforms. It also verifies the Gradle plugin on each
supported runner platform and against the minimum Gradle version, then
assembles its Maven publications on Linux.
- `coverage`: uploads Go coverage to Codecov, where `codecov.yml` requires
90% patch coverage for pull requests. The workflow also runs on pushes to
`master` to populate base coverage for later pull-request diffs and the
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ Use `-mode=embed` when documentation should be rewritten with current source
content. See the [configuration guide](showcase/configuration/README.md) for
all command-line flags and YAML options.

Gradle projects can use the [Embed Code Gradle plugin](gradle-plugin/README.md)
to download the platform binary automatically and configure both modes in
`build.gradle.kts` without an additional YAML file.

## Build

Use Go `1.26.4`.
Expand All @@ -81,6 +85,13 @@ Run the executable showcase:
go test -tags showcase ./showcase
```

Run the Gradle plugin checks:

```bash
cd gradle-plugin
./gradlew check
```

## Documentation

The main user guide is the [showcase](showcase/README.md).
Expand Down
3 changes: 3 additions & 0 deletions gradle-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.gradle/
/.kotlin/
/build/
224 changes: 224 additions & 0 deletions gradle-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
# Embed Code Gradle Plugin

The `io.spine.embed-code` plugin runs Embed Code without requiring developers
or CI jobs to download an executable manually. It selects the released binary
for the current platform, installs it under the project's `build/` directory,
and exposes separate `checkEmbedding` and `embedCode` tasks.

## Apply and Configure

After the plugin is published, apply its released version:

```kotlin
plugins {
id("io.spine.embed-code") version "1.2.4"
}
```

Until then, test the plugin directly from this checkout by adding its build to
the consuming project's `settings.gradle.kts`:

```kotlin
pluginManagement {
includeBuild("../embed-code-go/gradle-plugin")
}
```

The consuming `build.gradle.kts` can then apply `id("io.spine.embed-code")`
without a version while using that included build.

Configure Embed Code directly in `build.gradle.kts`; no `embed-code.yml` file
is required:

```kotlin
embedCode {
codePath.set(layout.projectDirectory.dir("src/main/java"))
docsPath.set(layout.projectDirectory.dir("docs"))
docIncludes.set(listOf("**/*.md", "**/*.html"))
docExcludes.set(listOf("drafts/**", "generated/**"))
separator.set("...")
info.set(false)
stacktrace.set(false)
}
```

`docsPath` is required. Configure either one unnamed `codePath` or one or more
named sources. By default, the plugin downloads the Embed Code release with the
same version as the plugin. The other properties use the same defaults as the
Embed Code command-line application.

| Property | Default | Purpose |
| --- | --- | --- |
| `version` | Plugin version | Selects the executable release. |
| `codePath` | Required without named sources | Sets one unnamed source root. |
| `namedSource(name, directory)` | Required without `codePath` | Adds a `$name/` source root. |
| `docsPath` | Required | Sets the documentation root to scan. |
| `docIncludes` | `**/*.md`, `**/*.html` | Selects documentation files. |
| `docExcludes` | Empty | Skips matching documentation files. |
| `separator` | `...` | Separates joined fragment parts. |
| `info` | `false` | Enables informational logging. |
| `stacktrace` | `false` | Prints stack traces after panics. |
| `downloadBaseUrl` | GitHub Releases | Selects a release mirror or test repository. |

If a matching CLI release has a problem, override only the executable version
while keeping the applied plugin version unchanged:

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

### Named Source Roots

Use `namedSource` when documentation embeds code from multiple modules:

```kotlin
embedCode {
namedSource(
"company-site",
layout.projectDirectory.dir("company-site"),
)
namedSource(
"jxbrowser",
layout.projectDirectory.dir("browser"),
)
docsPath.set(layout.projectDirectory)
}
```

Embedding instructions select these roots with `$company-site/` and
`$jxbrowser/`. The plugin writes the corresponding Embed Code configuration
into the Gradle task's temporary directory and passes it to the executable;
the project does not need an `embed-code.yml` file.

`codePath` and `namedSource(...)` are mutually exclusive. Multiple independent
documentation targets are not exposed by this Gradle DSL.

## Run

Check that documentation already contains current source snippets:

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

Update documentation in place:

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

Both tasks belong to the `embed code` group. `installEmbedCode` is an ungrouped
internal preparation task, so it is hidden from the normal `tasks` report but
remains visible with `tasks --all`. Gradle runs it automatically before either
execution task and reuses its output until the requested version, platform,
download URL, or build directory changes.

The plugin prefers the `checkEmbedding` and `embedCode` task names. If one is
already occupied, it prepends underscores until it finds an available name, for
example `_checkEmbedding` or `__checkEmbedding`. Existing tasks are unchanged;
use the `tasks` report to see the selected names. The leading `:` in the
commands above selects the root task explicitly; without it, a multi-project
build may also run every subproject task with the same name.

The plugin supports the platforms for which Embed Code currently publishes
release assets:

- Linux AMD64.
- Windows AMD64.
- macOS AMD64 and ARM64.

## Compatibility

The published plugin implementation targets Java 8 bytecode. The tested range
is Gradle 6.9.4 through 9.5.0. The JVM used to run Gradle must also satisfy the
selected Gradle version's own Java compatibility requirements.

The plugin build uses Kotlin DSL and Kotlin tests, while its published classes
are Java. Keeping Kotlin 2.x off the consumer plugin classpath allows older
Gradle Kotlin DSL compilers to load the plugin.

The plugin declares support for Gradle's configuration cache. Functional tests
run plugin tasks with `--configuration-cache` and verify cache reuse.

## Develop

Run compilation, plugin validation, unit tests, and TestKit functional tests:

```bash
cd gradle-plugin
./gradlew check
```

The functional tests create local fake release assets. They do not download or
execute a real GitHub release.

Publish the current plugin version to the local Maven repository when testing
it from another checkout:

```bash
./gradlew publishToMavenLocal
```

Then make the local repository available to plugin resolution in the consuming
project's `settings.gradle.kts`:

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

The `mavenLocal()` declaration must be in `pluginManagement.repositories`.
Adding it only to the consuming project's regular `repositories` block does not
make locally published Gradle plugin markers available to the `plugins` block.
The consuming build can then apply the locally published version normally:

```kotlin
plugins {
id("io.spine.embed-code") version "1.2.4"
}
```

The plugin publication version and its default Embed Code executable version
are both read from the repository's root `VERSION` file.

## Publish

The plugin is configured for the [Gradle Plugin Portal][plugin-portal]. Before
publishing, verify that the matching `v<version>` GitHub release contains all
platform executables. The plugin uses its own version as the default executable
version, so publishing it before the binaries would leave new installations
without a downloadable asset.

Request validation from the Plugin Portal without publishing a version:

```bash
./gradlew publishPlugins --validate-only
```

The Portal task requires API credentials even in validation-only mode. Provide
them through `GRADLE_PUBLISH_KEY` and `GRADLE_PUBLISH_SECRET`. The regular CI
build uses `publishToMavenLocal` instead, which assembles the plugin marker,
implementation publication, POM metadata, sources, and Javadocs without
contacting the Portal.

To publish after validation, run:

```bash
./gradlew publishPlugins
```

The first publication of `io.spine.embed-code` requires manual Portal approval.
The publishing account must be able to establish ownership of the `io.spine`
namespace; this external approval cannot be validated by the local build.

## License

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

[plugin-portal]: https://plugins.gradle.org/docs/publish-plugin
Loading
Loading