Is there an easy way to load in enviroment variabl...
# gradle
t
Is there an easy way to load in enviroment variables before my code runs? Im trying to get dotenv-java to work, but I see that it doesn't actually set env vars on System.getenv() where some of my dependent packages look (mainly google cloud stuff). Is there any way to export env vars inside the build.gradle.kts or its there another approach altogether?
c
Yes, you can pass additional environment variables to the
JavaExec
task in Gradle (https://docs.gradle.org/current/dsl/org.gradle.api.tasks.JavaExec.html#org.gradle.api.tasks.JavaExec:environment). the JVM has no support for setting variables at runtime
t
ah this is perfect... does that mean i can't use the application plugin?
c
The Application plugin creates a standard JavaExec task. Something like this should do it in a kts build script:
Copy code
val run by tasks.getting(JavaExec::class) {
    environment["myFlag"] = true
}
t
sorry i obs don't know enough about gradle yet! Does that augment the application plugin's run or use that instead of the application plugin?
ahh k it seems to augment it when i run via
./gradlew run
from the cli but not when i launch from inside intellij 🤯
c
IntelliJ might be set to use its own runner, and isn’t actually running Gradle. You can configure this in Preferences > Build, Execution and Deployment > Build Tools > Gradle https://www.jetbrains.com/help/idea/work-with-tests-in-gradle.html
t
thank you will check it out when I'm back at my desk
Perfect that works 🙏 My previous run configs were setup by IntelliJ when I hit the gutter's green arrow ... I've replaced them with the gradle run command and g2g now. Question regarding what this is doing:
val run by tasks.getting(JavaExec::class) { ... }
. Does it modify the JavaExec class by executing
{ ... }
before other calls? So that when JavaExec run later it has been modified? Does this then mean if i had multiple run commands they are all modified? Sorry brand new to gradle and struggling to wrap my head around it
c
No worries! yes, Gradle is a confusing beast to learn, but it’s very powerful and nice to work with once you wrap your mind around it, especially with the Kotlin DSL. But you’re exactly right,
val run by tasks.getting
looks up a task that has already been added by one of your Gradle plugins (from
plugins { ... }
), and then executes the lambda to configure that instance. This method specifically looks for a task named
run
(the variable name) of the given type (
JavaExec
). You may have multiple
JavaExec
tasks, and each one of them can be configured independently in a similar way. There are also facilities for configuring all tasks of a single type with one lambda (such as
tasks.withType<KotlinCompile>().configureEach { ... }
). I’m not sure exactly when it gets configured during the entire build lifecycle, and you generally don’t need to care about that. You can just feel safe knowing that the task gets configured at some point before it is executed. There’s a bunch of default configurations on it already, or other plugins may configure it, but I believe the configuration you apply in the buildscript takes precedence over all that
t
okay that all makes sense ... i started with the gradle docs on monday ... and most of it went over my head. I'm re-reading some of them now and they're making a bit more sense but obviously I'll have to keep with it. I'm going to try and create my own runTwo task 🤞
it defo doesn't help with a lot of the documentation in groovy!
c
I’d recommend their “Introduction to Gradle” courses (https://gradle.com/training/?_ga=2.135783473.1662296765.1582580423-1718840938.1566961185). I took it a couple years ago when I was getting started with it, too, and it helped me understand it so much. And once you have an idea of what Gradle itself is doing, you’ll be able to convert Groovy snippets to Kotlin fairly easily, but yeah, that does make it really confusing for beginners
t
thats exactly what I need thanks!
next one in March i'll get myself and some team members on it