Hi, how do I pass environment variables in a Gradl...
# intellij
a
Hi, how do I pass environment variables in a Gradle Configuration that runs the
:run
task to the Kotlin project of this task ?
j
Similar to
BuildConfig
on Android? Check out https://github.com/yshrsmz/BuildKonfig.
a
Hum, I don't think so, I don't know what is BuildConfig, but it looks like it's not what I meant You can set up environment variables for a run configuration inside intellij, but for a Gradle run configuration running the
:run
Gradle task, how do I set environment variables to be set for the kotlin code and not for Gradle itself ?
j
What do you mean by "set for the kotlin code"? Like exposed as a static reference? Or are you wanting to accept run arguments through the entry point of your program?
a
I mean that I can access those variables in my code using
System.getenv("variable")
j
And you want to get the environment value of "variable" in a Kt file?
a
Yes exactly !
j
Look at BuildKonfig again. It does exactly that.
You set it up on your
build.gradle
and it generates a class with those values that you can reference in code.
a
Ah, I think I'll stick with using a
.env
file then, it looks like it's simpler to install than BuildKonfig, but thanks for the information, it's still interesting to know !
j
it should ultimately only be 4 or 5 lines you need to add to your
build.gradle
to get exactly what you want using BuildKonfig. Add the dependency, apply the plugin, then add the field you want though its config.
e
This should do:
Copy code
tasks.run {
    environment("MY_ENV_VAR", "some-value")
}
t
@eskatos In
build.gradle.kts
(Gradle 8.5)
Copy code
tasks.run {
    environment("MY_ENV_VAR", "some-value")
}
Results in:
Copy code
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
public inline fun <T : AbstractExecTask<*>> AbstractExecTask<TypeVariable(T)>.environment(vararg environmentVariables: Pair<String, Any?>): TypeVariable(T) defined in org.gradle.kotlin.dsl
public inline fun JavaExec.environment(vararg environmentVariables: Pair<String, Any?>): JavaExec defined in org.gradle.kotlin.dsl
public inline fun Test.environment(vararg environmentVariables: Pair<String, Any?>): Test defined in org.gradle.kotlin.dsl
public inline fun ProcessForkOptions.environment(vararg environmentVariables: Pair<String, Any?>): ProcessForkOptions defined in org.gradle.kotlin.dsl
e
Ah, sorry I typed this from memory, a failing memory it seems 🙂
Try:
Copy code
tasks.run {
    environment("MY_ENV_VAR" to "some-value")
}
t
@eskatos Thanks for following up! 🙂 I'm afraid that the same error appears when I try it on the default minimal app created by the IntelliJ Ktor plugin. build.gradle.kts
Copy code
val ktor_version: String by project
val kotlin_version: String by project
val logback_version: String by project

plugins {
    kotlin("jvm") version "1.9.22"
    id("io.ktor.plugin") version "2.3.8"
}

group = "com.example"
version = "0.0.1"

application {
    mainClass.set("com.example.ApplicationKt")

    val isDevelopment: Boolean = project.ext.has("development")
    applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment")
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("io.ktor:ktor-server-core-jvm")
    implementation("io.ktor:ktor-server-netty-jvm")
    implementation("ch.qos.logback:logback-classic:$logback_version")
    testImplementation("io.ktor:ktor-server-tests-jvm")
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
}

tasks.run {
    environment("MY_ENV_VAR" to "some-value")
}
Copy code
$ ./gradlew --version

------------------------------------------------------------
Gradle 8.4
------------------------------------------------------------

Build time:   2023-10-04 20:52:13 UTC
Revision:     e9251e572c9bd1d01e503a0dfdf43aedaeecdc3f

Kotlin:       1.9.10
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          17.0.9 (Private Build 17.0.9+9-Ubuntu-122.04)
OS:           Linux 6.5.0-21-generic amd64
Copy code
$ ./gradlew build

Script compilation error:

  Line 33:     environment("MY_ENV_VAR" to "some-value")
               ^ Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
                   public inline fun <T : AbstractExecTask<*>> AbstractExecTask<TypeVariable(T)>.environment(vararg environmentVariables: Pair<String, Any?>): TypeVariable(T) defined in org.gradle.kotlin.dsl
                   public inline fun JavaExec.environment(vararg environmentVariables: Pair<String, Any?>): JavaExec defined in org.gradle.kotlin.dsl
                   public inline fun Test.environment(vararg environmentVariables: Pair<String, Any?>): Test defined in org.gradle.kotlin.dsl
                   public inline fun ProcessForkOptions.environment(vararg environmentVariables: Pair<String, Any?>): ProcessForkOptions defined in org.gradle.kotlin.dsl

1 error
I wonder if there are some other dependencies that need to be installed?
e
Ahh it might be a conflict with Kotlin's
run
function.
Try
(tasks.run) { ... }
🙌 1
😀 1
t
Wow! Thank you! That solved it! 😀 Is there a reference where I can read more about how the parentheses signal that it should be interpreted as a kotlin.dsl method instead of a kotlin method?
e
Not really. It'a Kotlin language thing. The same issue arise if you have tasks named like a stdlib extension on
Any
like
apply
,
let
,
also
etc..
By using the parenthesis we tell the Kotlin compiler that we want to first resolve
tasks.run
which is a property on
tasks
for the
run
Gradle task. And then we call the
invoke
operator on it with
{ ... }
.
🙂 1
t
Oh, ok! That makes sense! Thanks for taking the time to explain it so clearly! 😀
366 Views