Skip to content

Repository files navigation

ktc-to-gradle

ktc-to-gradle converts a Kotlin Toolchain 0.13 project into a Gradle Kotlin DSL build in place. It finds project.yaml or module.yaml, resolves modules and templates, and generates a build pinned to Gradle 9.8.0.

Intent

This project exists to make trying Kotlin Toolchain a low-risk, reversible decision. A team should be able to start a real project with the simpler declarative Toolchain model, evaluate it in practice, and keep using it when it fits. If Toolchain does not yet cover the project's requirements, ktc-to-gradle provides an escape hatch to a conventional Gradle Kotlin DSL build instead of forcing the team to rewrite its build from scratch.

The goal is not to move projects away from Kotlin Toolchain. The Gradle converter is a safety net intended to reduce fear of lock-in, so more developers feel comfortable adopting and testing Kotlin Toolchain today.

For AI-assisted work with module.yaml, project.yaml, templates, dependencies, platforms, and the kotlin CLI, see the version-aware Kotlin Toolchain skill in Heapy/kortex. The kortex plugin packages this skill for Codex, Claude Code, and Junie.

The converter and its integration-test harness are built by Kotlin Toolchain. Gradle is invoked only as the system under test: each fixture is converted and then built with the generated Gradle 9.8.0 wrapper.

Getting Started

Run the latest GitHub Release binary directly. The bootstrap script detects the current OS and architecture, downloads the archive and its SHA-256 checksum, verifies it, caches the executable, and forwards all arguments:

curl -fsSL https://raw.githubusercontent.com/Heapy/ktc-to-gradle/main/run.sh | bash -s -- /path/to/toolchain-project

To download, verify, and install the native binary in ~/.local/bin:

curl -fsSL https://raw.githubusercontent.com/Heapy/ktc-to-gradle/main/install.sh | sh
ktc-to-gradle /path/to/toolchain-project

Windows PowerShell:

irm https://raw.githubusercontent.com/Heapy/ktc-to-gradle/main/install.ps1 | iex
ktc-to-gradle C:\path\to\toolchain-project

Set KTC_TO_GRADLE_VERSION=0.13.0 to pin a release or KTC_TO_GRADLE_REPOSITORY=owner/repository when using a fork. Native release binaries are published for macOS arm64, Linux x64/arm64, and Windows x64. Kotlin Toolchain native app products do not support macOS Intel.

Use --dry-run to validate without writing. Existing Gradle files that were not generated by this tool are protected; pass --force only after reviewing them.

The converter lays down the standard Gradle wrapper — gradlew, gradlew.bat and gradle/wrapper/ — so no manual Gradle installation is required. These are Gradle's own files, not a launcher of ours: they are carried inside the converter binary and written out verbatim, with one comment added to each script so the converter recognises its own output. Change the Gradle version the way you would in any Gradle project, by editing distributionUrl in gradle/wrapper/gradle-wrapper.properties — and update distributionSha256Sum in the same edit, or the wrapper refuses the download it no longer recognises. Remove the line to skip verification. The generated project needs a JVM on PATH, which Gradle needs anyway, and xargs, which Gradle's launcher uses to parse quoted arguments.

gradle-wrapper.jar is the one file the converter writes that cannot carry that comment, so it inherits the ownership of the gradle-wrapper.properties beside it: a rerun replaces the jar while that properties file is still the converter's own, and refuses when it is foreign or missing. A jar you replaced by hand — a corporate-signed or security-patched build — is therefore overwritten by the next conversion, exactly as a hand-edited build.gradle.kts that kept its header is. Keep such a jar outside the converter's reach, or put it back afterwards; --force overrides the refusal in the other direction.

Maintainers: tools/update-gradle-wrapper.sh is the only thing that rewrites the embedded wrapper, and a scheduled workflow runs it and opens a pull request when a new stable Gradle is released.

Conversion coverage

  • single-module projects and project.yaml multi-module projects, including one-component globs;
  • nested module templates with Toolchain precedence;
  • default and maven-like JVM layouts;
  • jvm/app, jvm/lib, android/app, kmp/lib, JS, Wasm, and native app products;
  • root-relative and relative local module dependencies;
  • Maven coordinates, BOMs, dependency scopes, exported dependencies, repositories, and libs.versions.toml catalogs;
  • Kotlin/JVM compiler settings, JDK/release settings, settings.junit in all three forms, test process settings, Kotlin serialization, third-party Kotlin compiler plugins, and the Ktor BOM;
  • settings.publishing as maven-publish and signing: the coordinate, the POM, sources jars, and the repositories a module publishes to;
  • platform-qualified KMP source, resource, test, and dependency sections.

Toolchain build plugins and Maven plugins have no automatic Gradle equivalent. The converter does not stop for them: it writes the rest of the build, reports each dropped section and each left-out module as an error: line, and exits 1 so a partial conversion is never reported as a success. It still stops with an explanation for ios/app and for built-in technologies whose Gradle behavior cannot yet be reproduced safely. An Android target nested in a kmp/lib is converted, as an androidLibrary { } target. Original YAML and source files are never removed.

For Toolchain 0.13, use layout: default (or omit the key); the obsolete layout: amper is rejected with a migration hint. Android applications must declare settings.android.namespace. Android library namespaces follow Toolchain’s publication coordinates or its module-name hash fallback. New features such as SwiftPM dependencies, settings.kotlin.explicitApi, and Android ABI filters still produce diagnostics when they cannot be converted. See the Toolchain 0.13 release notes.

Build and test

The code uses the io.heapy.ktctogradle package and kotaml for YAML 1.2 parsing. The checked-in Kotlin Toolchain 0.13.0 wrapper provisions everything needed by the application build:

./kotlin test -m core -p jvm
./kotlin build -m macos -p macosArm64 -v release  # choose the host module/platform

The project pins Kotlin 2.4.20, matching Toolchain 0.13.0. Generated builds use the same compiler by default and Ktor 3.6.0 when Ktor is enabled without an explicit version. Explicit module versions are preserved, subject to Gradle’s single plugin version per build.

The core suite includes whole-output golden snapshots under core/testResources@jvm/golden. AGENTS.md describes the four pipeline stages, where to place coverage, and how the baselines are regenerated.

Run the Kotlin Toolchain integration-test module separately:

./kotlin test -m integration-tests -p jvm

The suite copies twelve Toolchain fixtures. Each one is first built and tested by the Kotlin Toolchain itself, then converted, then built with the generated Gradle 9.8.0 wrapper; every JVM and Android test the Toolchain ran has to run again under Gradle. A fixture the Toolchain refuses is not evidence about the converter, so that step fails the case. The three Android fixtures are skipped when no Android SDK is available. GitHub Actions also smoke-tests run.sh and install.sh on Linux/macOS and install.ps1 on Windows, including checksum-failure paths. Native archives with SHA-256 checksum files are published for v* tags.

Licence

Apache License 2.0; see LICENSE.

The converter binary embeds the Gradle wrapper — gradle-wrapper.jar, gradlew and gradlew.bat — and writes it into every converted project. Those files are Copyright the original authors and are licensed under the Apache License 2.0. tools/update-gradle-wrapper.sh verifies the jar against the wrapperChecksum that services.gradle.org publishes for the release before embedding it, and refuses to write it when they differ.

About

Converts a Kotlin Toolchain 0.12 project into a Gradle Kotlin DSL build in place

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages