0

Scenario:

  • A gradle project, using the org.jetbrains.kotlin.jvm plugin
  • The project has some *.kts kotlin script files located inside src/main/kotlin. The scripts do various tasks, for instance there is a script for loading test data from a set of CSV files into a local H2 database, a script for creating a test user in the database etc.
  • I currently run these scripts using IntelliJ IDEA run configurations
  • The gradle build file is using kotlinscript (build.gradle.kts)

To make things easier to set up for new developers, I would like to configure gradle so I can run the scripts directly using gradle. That would simplify my README.md, instead of "use IntelliJ to execute the script xxx.kts with arguments yyy and zzz, then nnn.kts", I could write "execute gradle loadTestDataIntoLocalH2Database".

Questions/issues:

  • Is there a simple way to execute a *.kts script from gradle?
codeape
  • 97,830
  • 24
  • 159
  • 188
  • Related question: https://stackoverflow.com/q/42320216/3571 (alas, no good answers - the answers given miss the point completely) – codeape May 03 '22 at 22:00
  • Is the gradle build file using kotlinscript or groovy? And is the kotlin compiler (kotlinc) installed and on the PATH on the device that this is running on? – somethingsomething May 04 '22 at 13:48
  • 1. Kotlinscript (also updated the question with this info) 2. I currently do not have kotlinc installed (I use the compiler bundled in the IntelliJ kotlin plugin and/or the one bundled in the gradle kotlin plugin). – codeape May 04 '22 at 14:11
  • 1
    See my answer here: https://stackoverflow.com/a/76505455/4161471 – aSemy Jun 19 '23 at 09:49

1 Answers1

2

Puzzled my answer together from https://docs.gradle.org/current/userguide/plugins.html#sec:script_plugins , https://kotlinexpertise.com/execute-kotlin-scripts-with-gradle/ and https://stackoverflow.com/a/52139585/9936828

Although I didn't try it, the second link seems like the best solution if you are ok with adding the scripts to your projects package instead of keeping them as loose scripts.

Tested with gradle 7.2.

First option is the most straightforward with no changes to code, but requires you to install the kotlin compiler CLI (kotlinc), gradle can then call it to execute the scripts:

task<Exec>("MyTask") {
    commandLine("kotlinc", "-script", "foo.gradle.kts")
}

Then call it with gradle -q MyTask. Or obviously you could also provide the direct instructions to run kotlinc for the user without wrapping it in gradle.

Second option would be to load your script as a plugin. This however causes the kotlinscript annotations such as external imports (@file:Import, etc) to not work.

Wrap your code in your script in a task:

tasks.create("MyTask") {
    doLast {
        <do your stuff here>
    }
}

load as plugin in your build script:

apply(from = "foo.kts")

Then call it with gradle -q MyTask.

somethingsomething
  • 1,746
  • 6
  • 8
  • Some of the scripts import code from the main project. Using the invoke-kotlinc option: How would I set the class path automatically? Using the implement-in-buildscript option: How can the build script depend on the main project's build output? – codeape May 05 '22 at 06:27
  • The classpath can be set using the -cp command line option of kotlinc, where you can link to the relevant jar or class files. But a simpler solution might be to use the @file:DependsOn("myLib.jar") annotation on the first line(s) of your scripts to import a local jar. I don't think this is straightforward with the gradle plugin method, but someone with better knowledge of gradle would need to answer that. – somethingsomething May 05 '22 at 07:39