# Gradle plugin

> Compile Java in an existing Gradle build with `elide javac`: the dev.elide settings and project plugins, runtime selection, persistent compilers, formatting tasks and dependency export.

The `dev.elide.settings` and `dev.elide` plugins make Gradle's `JavaCompile` tasks run `elide javac`, and add
formatting and dependency-export tasks. Gradle keeps dependency resolution, tests and packaging.

## Requirements

| | Version |
| --- | --- |
| Gradle | 7.6.4 or later |
| JDK running Gradle | 17 or later |
| Plugins | 1.2.0, from Maven Central |
| Elide | 1.6 |

## Install

`settings.gradle.kts` adds Maven Central to the plugin repositories and selects the Elide runtime for the whole build:

```kotlin
import dev.elide.gradle.ElideRuntimeMode

pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id("dev.elide.settings") version "1.2.0"
}

elide {
    runtime {
        mode = ElideRuntimeMode.MANAGED
        version = "1.6.0"
    }
}
```

Each project that should compile with Elide applies `dev.elide`, with no version:

```kotlin
// build.gradle.kts
plugins {
    id("dev.elide")
    java
}

elide {
    compiler = true
}
```

On Gradle 7.6, configure the settings extension with `configure<dev.elide.gradle.ElideSettingsExtension> { runtime { … } }`.

## Runtime selection

| `mode` | Uses |
| --- | --- |
| `AUTO` (default) | `runtime.executable` if set, then `elide` on `PATH` if it reports at least `version`, then the managed runtime |
| `PATH` | `elide` on `PATH`; fails if it is older than `version` |
| `MANAGED` | Downloads `version` once into `<GRADLE_USER_HOME>/caches/dev.elide/runtimes/`, verifies its SHA-256, reuses it offline |

```kotlin
elide {
    runtime {
        mode = ElideRuntimeMode.PATH
        executable = layout.projectDirectory.file("tools/elide")
    }
}
```

Managed downloads cover Linux x86_64 and arm64, macOS arm64 and Windows x86_64. Applying the plugin downloads and runs
nothing; the runtime is prepared when a task needs it.

## Configuration

Project `elide { }` block:

| Property | Default | Effect |
| --- | --- | --- |
| `compiler` | `true` | Compile `JavaCompile` tasks with `elide javac` |
| `persistentCompiler` | `false` | Keep up to four `elide javac` workers warm for the rest of the build |
| `dependencyMode` | `LEGACY` | `GRADLE`: Gradle owns resolution; `install` must stay off |
| `install` | `false` | Run `elide install` from `elide.pkl` before compiling |
| `maven` | `true` | With `install`, add `.dev/dependencies/m2` as a Maven repository |
| `manifest` | `elide.pkl` | Manifest `install` reads |

Gradle properties override the block for a run, in both directions:

| Property | Effect |
| --- | --- |
| `elide.builder.javac.enable=false` | Compile with stock `javac` |
| `elide.builder.maven.install.enable=true` | Force `elide install` on |

```bash
./gradlew build -Pelide.builder.javac.enable=false
```

## Tasks

| Task | Does |
| --- | --- |
| `prepareElideRuntime` | Downloads and verifies the managed runtime |
| `elideInstall` | Runs `elide install`; skipped unless `install = true` |
| `elideCheckFormat` | Fails when `.java`, `.kt` or `.kts` files under `src/` need formatting; changes nothing |
| `elideFormat` | Formats them in place |
| `elideExportDependencies` | Writes resolved coordinates and SHA-256 per source set to `build/elide/dependencies/` |

`compileJava` and `compileTestJava` keep their task types, so incremental compilation and the build cache work as
usual.

## Example

```text
settings.gradle.kts
build.gradle.kts
src/main/java/com/example/HelloWorld.java
src/test/java/com/example/HelloWorldTest.java
```

```kotlin
// build.gradle.kts
plugins {
    id("dev.elide")
    java
    application
}

application {
    mainClass = "com.example.HelloWorld"
}

repositories {
    mavenCentral()
}

elide {
    compiler = true
}

dependencies {
    implementation("com.google.guava:guava:33.4.8-jre")
    testImplementation("org.junit.jupiter:junit-jupiter:5.13.4")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

tasks.test {
    useJUnitPlatform()
}
```

With the `settings.gradle.kts` from [Install](#install):

```bash
./gradlew clean build run
```

```terminaloutput
> Task :prepareElideRuntime UP-TO-DATE
> Task :elideInstall SKIPPED
> Task :clean
> Task :compileJava
> Task :jar
> Task :run
Hello, World!
> Task :compileTestJava
> Task :test
> Task :build
BUILD SUCCESSFUL in 5s
Configuration cache entry stored.
```

The first run downloads Elide in `prepareElideRuntime`; later runs reuse it.

## OpenRewrite and dependency queries

For projects with an `elide.pkl`, see [OpenRewrite](https://elide.help/docs/toolchain/jvm/rewrite) and
[Dependency code index](https://elide.help/docs/toolchain/jvm/code-index). The Gradle plugin does not add rewrite or code-index tasks;
`elideExportDependencies` exports coordinates and checksums, but its output is not an input to `elide index`.
See [the project setup boundary](https://elide.help/docs/build-tools#openrewrite-and-dependency-queries) before using these commands
alongside Gradle.

## Limits

- Only Java compilation goes through Elide. Kotlin (`compileKotlin`) uses the Kotlin Gradle plugin's compiler.
- `persistentCompiler` does not support `forkOptions.jvmArgs`.
- `MANAGED` is unavailable on Intel macOS; use `PATH` there.
- `elideFormat` covers sources under `src/` only.
