In my root build.gradle file I pretty much just se...
# community-support
c
In my root build.gradle file I pretty much just setup some plugins. But at the bottom of the file I also just want to run another gradle file. Basically just for the purpose of "cleaning up" the root file so that there are less lines of code there. How can I just take like 10 lines, and put it into another file to be refrenced as if it was in my root build.gradle file? I ended up with
Copy code
apply(from = rootPoroject.file("scripts/blah.gradle.kts")
and then in my blah.gradle.kts (for testing purposes) I put a
println
in there, but I never actually see it printed. am I missing something on how to do this?
v
You should not use legacy script plugins. They have many quirks and are highly discouraged. Build a proper convention plugin instead, for example in
buildSrc
or an included build, for example implemented as precompiled script plugin. Then apply that in your your project.
☝️ 3
c
Okay. I will look at included build (i still have nightmares of buildSrc from a past project, so id like to avoid it) FWIW. my project only has one module (app) and it's a tiny app so we will likely never go multi module.
We just want a way to take like 30 lines of configuration for the ben-manes-dependency-plugin and tuck it away into another file
v
If you don''t like
buildSrc
(cannot imagine why) then use an included build, yeah (which I prefer anyway). But nowadays the differences between the two are rather subtle.
c
weird bugs like this https://issuetracker.google.com/issues/176079157 have me with nightmares lol.
v
That's not so much a weird bug or bug at all. It is just hot class loading works and probably not expected by you. And especially this has not so much to do with
buildSrc
. If you load one plugin in the root project build script classpath and the other in a subproject build script classpath, they are also in different class loaders and one can see the other but the other not the one. Or if you load one plugin in the settings script classpath and the other in a build script classpath, they are also in different class loaders and one can see the other but the other not the one. Using an included build might bear less surprises than
buildSrc
as
buildSrc
stuff is in a separate class loader that is the parent of the root build script class loader, while the included build is in the classpath and thus class loader where it is used from like any other plugin. But as I just described, such things can still happen, just like they can happen even without using any
buildSrc
or included build.
c
So. sorta related... In my app build.gradle.kts I have like 100 lines of the following
Copy code
buildConfigField("String", "XYZ1", getProperty("KEY1"))
buildConfigField("String", "XYZ2", getProperty("KEY2"))
buildConfigField("String", "XYZ3", getProperty("KEY3"))
buildConfigField("String", "XYZ4", getProperty("KEY4"))
...
if I want to just do that snippet of code in another file how would i do that? is that a good enough reason to use legacy script plugins, or should i also go down the route of a convention plugin?
v
I cannot make up any use-case where I would consider legacy script plugins a good idea 😄
c
so what would you do in my case above. i have a nice lean build.gradle.kts file... but its riddled with 100+ lines of trivial buildConfigField declarations.
v
If you want to move it to a different file, I'd use a precompiled script plugin or any other format for a convention plugin.
Or you could move the data of these calls to a CSV-file or similar and then iterate over it in your build script. That makes it a little bit less idiomatic as it is not declarative, but that's up to you to decide. 🙂
c
"precompiled script plugin" cool. ill look for that in the docs. thanks!
v
That's most probably the proper name of what you call "convention plugin" which unfortunately is a common misuasge of terms. A convention plugin is any plugin that employs your own conventions, no matter how they are implemented. Precompiled script plugins are just the most used way to implement them.
They are the
whatever.gradle
or
whatever.gradle.kts
files you put to
buildSrc
or an included build
c
gotcha. im still learning so appreciate the help. ive been on projects that had buildSrc/included build setup already so i will need to look into how to set that up first.
i feel like its a lot of work just to be able to extract a function to another file essentially. but so be it 😓
v
It's not at all "a lot of work" 🙂
It is creating 2 additional files and writing 1 line for an included build. (settings script, build script, and the line that includes it)
c
thanks for teaching. will try this now 😄
Alright. Just as a sanity check. This is what I added:
build.gradle.kts
Copy code
plugins {
    `kotlin-dsl` // Enables Kotlin precompiled scripts
}

repositories {
    mavenCentral()
    google()
}
settings.gradle.kts
Copy code
rootProject.name = "buildConfigFieldSetup"
root build.gradle.kts
Copy code
includeBuild("buildConfigFieldSetup")
Is that all I need?
v
The include build should be within plugin management block if it is about a plugin. And if you need other plugins add dependencies you might want
gradlePluginPortal()
as dependency. But other than that, it should be a sufficient setup to start with, yes. As I said, not too much effort :-)
😍 1
c
Wait. im confused again.
include build should be within plugin management block if it is about a plugin.
All I want to do is have buildConfigField("String", "XYZ1", getProperty("KEY1")) buildConfigField("String", "XYZ2", getProperty("KEY2")) buildConfigField("String", "XYZ3", getProperty("KEY3")) buildConfigField("String", "XYZ4", getProperty("KEY4")) Are you saying my root settings.gradle.kts should be
Copy code
rootProject.name = "MyProject"

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

pluginManagement {
  repositories {
    maven("<https://maven.pkg.jetbrains.space/public/p/compose/dev>")
    google()
    gradlePluginPortal()
    mavenCentral()
  }

  includeBuild("buildConfigFieldSetup")
}

dependencyResolutionManagement {
  repositories {
    google()
    mavenCentral()
    maven("<https://maven.pkg.jetbrains.space/public/p/compose/dev>")
  }
}

include(":app")
OR
Copy code
rootProject.name = "MyProject"

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

pluginManagement {
  repositories {
    maven("<https://maven.pkg.jetbrains.space/public/p/compose/dev>")
    google()
    gradlePluginPortal()
    mavenCentral()
  }

}

dependencyResolutionManagement {
  repositories {
    google()
    mavenCentral()
    maven("<https://maven.pkg.jetbrains.space/public/p/compose/dev>")
  }
}

include(":app")
includeBuild("buildConfigFieldSetup")
v
buildConfigFieldSetup
is a build where you build a plugin to be used in your main build, so you should do the
includeBuild
within
pluginManagement { ... }
. What the plugin you build there does and how it is implemented is not relevant. It also works outside as that is what was there before, as long as you do not build a settings plugin, but it is cleaner to also do it within the
pluginManagement
block for project plugins.
So the "either" one
c
got it. TIL
👌 1
Now I'm trying to add the buildConfigFields to the precompiled script, but no dice
Copy code
plugins {
    `kotlin-dsl`
    alias(libs.plugins.androidApplication) <----- error
    // or
    // id("com.android.application") <---- this errors too. Hmm
}

repositories {
    mavenCentral()
    google()
}

android {
    buildConfigField("String", "XYZ1", getProperty("KEY1"))
}
v
You cannot use version catalog accessors in precompiled Kotlin DSL script plugins. With a hack-around you can outside the
plugins
block, but not inside. You indeed need the
id
one, but you missed to add a dependency to that plugin in
buildConfigFieldSetup/build.gradle.kts
.
Ah, wait, is what you just showed the
buildConfigFieldSetup/build.gradle.kts
?
Doing your
buildConfigField
lines there makes no sense at all. That is the build script to build your plugins. You want to do that in a plugin which you then apply to your main build. The plugin is built by the included build and then applied, doing its actions.
c
lol. well. here i thought i knew what was going on. giving up on this for now. going to just go the "legacy" route with
apply(from = rootPoroject.file("scripts/blah.gradle.kts")
v
Why? Just create a precompiled script plugin now in
src/main/kotlin
. Why going the strongly discouraged way if you are almost there the proper way?
Besides that in the legacy script plugin way you even cannot use the extension through a type-safe accessor, as they are not available in legacy script plugins.
c
Because I've spent 4+ hours trying to get buildConfigField("String", "XYZ1", getProperty("KEY1")) into another file.
lol. thats disheartening