All skills
kotlin avatar

/kotlin-tooling-gradle-to-kotlin-toolchain-plugin

@c2f9069 official
by kotlinkotlin/kotlin-agent-skills1.1k stars
42

Load when porting, converting, or reimplementing a single Gradle plugin as a Kotlin Toolchain local plugin, or when mapping Gradle plugin concepts (Task, Extension, project.version, dependsOn, -P properties, afterEvaluate) to Toolchain analogs. Skip for migrating a whole Gradle project or authoring a plugin from scratch.

Use this Skill: https://skilld.dev/gh/kotlin/kotlin-agent-skills/kotlin-tooling-gradle-to-kotlin-toolchain-plugin

This session only. Nothing lands on disk.

referencesexamples.md

≈929 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Conversion patterns — concrete code

Lifted from a real conversion: allegro/axion-release-plugin ported to a Kotlin Toolchain local release plugin. Adapt names, types, and imports. The constructs themselves (project.yaml, Settings, @TaskAction, plugin.yaml) are in the skill body.

1. plugins/<name>/module.yaml

Declare the Maven coordinates of every library the plugin uses, including transitive optionals that only fire at runtime. pluginInfo.id is what tasks are addressed by (...@release) and what consumers key their plugins: block on; pluginInfo.settingsClass is the fully-qualified @Configurable interface.

product: jvm/amper-plugin

dependencies:
  - org.eclipse.jgit:org.eclipse.jgit:7.0.0.202409031743-r
  - org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.0.0.202409031743-r
  # MINA SSHD (pulled in by jgit.ssh.apache) declares BouncyCastle as optional
  # at compile time but builds its random factory from it at runtime. Pin to
  # the version contemporary with MINA SSHD 2.13.x.
  - org.bouncycastle:bcprov-jdk18on:1.78.1: runtime-only
  - org.bouncycastle:bcpkix-jdk18on:1.78.1: runtime-only
  - org.slf4j:slf4j-nop:2.0.13

pluginInfo:
  id: release
  settingsClass: com.example.release.Settings

settings:
  jvm:
    jdk:
      version: 21
  kotlin:
    languageVersion: 2.1

2. File-based publication — the project.version analog

The Gradle idiom version = scmVersion.version shares one value across the whole build. Replace it with a @TaskAction that writes a file. ExecutionAvoidance.Disabled is required because the real input (Git history, branch name, working-tree state) cannot be fingerprinted.

package com.example.release.tasks

import com.example.release.Settings
import com.example.release.git.GitRepo
import com.example.release.version.VersionPipeline
import org.jetbrains.amper.plugins.ExecutionAvoidance
import org.jetbrains.amper.plugins.Input
import org.jetbrains.amper.plugins.Output
import org.jetbrains.amper.plugins.TaskAction
import java.nio.file.Path
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.createParentDirectories
import kotlin.io.path.deleteRecursively
import kotlin.io.path.div
import kotlin.io.path.writeText

@OptIn(ExperimentalPathApi::class)
@TaskAction(executionAvoidance = ExecutionAvoidance.Disabled)
fun writeVersion(
    @Input moduleRootDir: Path,
    @Output outputDir: Path,
    settings: Settings,
) {
    val pipeline = VersionPipeline(settings)
    val inferred = GitRepo.open(moduleRootDir, settings.repoDir).use { pipeline.infer(it) }

    outputDir.deleteRecursively()
    val versionFile = outputDir / "META-INF" / "release" / "version.txt"
    versionFile.createParentDirectories()
    versionFile.writeText(inferred.version + "\n")
}

That one @Output directory feeds two consumption paths.

Build-time. Any other task — in this plugin, another plugin, or user code — declares @Input on the same path, and the dependency is inferred from the match:

@TaskAction
fun packageWithVersion(
    @Input versionFile: Path,
    // ...
) {
    val version = versionFile.readText().trim()
    // ...
}
tasks:
  packageWithVersion:
    action: !com.example.packageWithVersion
      versionFile: ${tasks.writeVersion.action.outputDir}/META-INF/release/version.txt

Runtime. The directory is registered under generated.resources, so the file lands on the JAR classpath:

fun version(): String? =
    object {}.javaClass.getResourceAsStream("/META-INF/release/version.txt")
        ?.bufferedReader()?.use { it.readText().trim() }

One publication point, two consumption channels, no Toolchain-side shared state.

Source: SKILL.md on GitHub

1 warning20d3 checks · Risk SAFE
  • Gen Agent Trust Hub20d

    The skill provides instructions for converting Gradle plugins to a Kotlin Toolchain format. It includes a potential surface for indirect prompt injection as it requires the agent to analyze untrusted source code and documentation, though the skill correctly identifies these inputs as untrusted and includes a safety warning.

  • Socket20d

    No alerts

  • Snyk20d

    Risk: MEDIUM · 1 issue

Signed by skilld at c2f9069. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 weeks ago.

Activeupdated last month
metadata
{
  "author": "github:@singleton11",
  "version": "0.1.0"
}

README badge

README badge for kotlin/kotlin-agent-skills/kotlin-tooling-gradle-to-kotlin-toolchain-plugin