https://gradle.com/ logo
#community-support
Title
# community-support
r

Roberto Fuentes

05/18/2023, 8:24 PM
Hi, I was wondering if there’s a way to reuse code when using
kts
. I want to not duplicate the repositories by extracting them into an extension function and using this function in
pluginManagement
&
dependencyResolutionManagement
repositores. Does anyone know if this is even possible? If yes maybe some docs/example?
c

Chris Lee

05/18/2023, 8:29 PM
one approach is to create a Setting plugin that applies the repository
r

Roberto Fuentes

05/18/2023, 8:46 PM
And does Settings plugin work for this other use case?: • Reuse a function that returns something
I see it’s something like this:
class SettingsPlugin implements Plugin<Settings> {..}
Where you override this
apply
function, doesn’t seem to be a place where you can expose functions and use it in other places
a

Adam

05/18/2023, 8:58 PM
if you want to add a dependency that will be available in a build script (be it
settings.gradle.kts
or
build.gradle.kts
) there are basically two ways Either you add a dependency using the buildscript block
Copy code
buildscript {
    dependencies {
        classpath("org.apache.commons:commons-lang3:jar:3.12.0")
    }
}
This is good for dependencies that are published to a Maven repo you can add, but it’s not so convenient for project-local utilities that you don’t want to publish The alternative is to use a composite build. This is probably what you want. 1. create a new directory in your project,
my-settings-utils
, and because this is going to be an independent Gradle build (not a subproject) create a
build.gradle.kts
and a
settings.gradle.kts
2. in
build.gradle.kts
, apply the kotlin-dsl plugin 3. Create your utility class -
my-settings-utils/src/main/kotlin/RepoUtils.kt
4. add
includeBuild("./my-settings-utils")
in the base project settings file, as detailed in the docs 5. my memory is vague here, but I think you need to create a settings plugin, else Gradle won’t add the
my-settings-utils.jar
to the
settings.gradle.kts
buildscript classpath. So just create a dummy precompiled script plugin -
my-settings-utils/src/main/kotlin/my-repos.settings.gradle.kts
- which can be empty, it doesn’t need any content 6. Now apply the plugin in
settings.gradle.kts
Copy code
plugins {
  id("my-repos")
}
And the JAR will be added to the buildscript classpath, and because
RepoUtils.kt
will be compiled into the same JAR as the dummy plugin those functions will be available
v

Vampire

05/18/2023, 9:14 PM
Copy code
// the plugin management block is evaluated first separately, do not change this to
// listOf(pluginManagement.repositories, dependencyResolutionManagement.repositories)
// instead that would change the semantics
pluginManagement {
    listOf(repositories, dependencyResolutionManagement.repositories).forEach { repositories ->
        repositories.apply {
            maven("<https://nexus.company.com/repository/maven>") {
                name = "Company Nexus"
            }
        }
    }
}
r

Roberto Fuentes

05/18/2023, 9:28 PM
Thank you both @Adam & @Vampire 🙇 It seems that Vampire solution works for my
settings.gradle.kts
and can use the repositories function without duplicating them! And now I have another small question So if this block is evaluated first separately it means that it cannot access anything outside of
pluginManagement
? And neither someone can access any function found inside this block, right? So let’s say in my
build.gradle.kts
. it’s impossible to access any function I’ve created there in my
settings.gradle.kts
right? And I guess
gradle.settingsEvaluated
doesn’t add anything here
v

Vampire

05/18/2023, 9:31 PM
Almost correct. The effects of
pluginManagement
are seen outside too. That's why you can confiugre the
dependencyResolutionManagement.repositories
inside the block while you would usually do it outside. So you could define some function and store it in an
ext
property within
pluginManagement
and then also use it outside, retrieving it from the extra properties.
r

Roberto Fuentes

05/18/2023, 10:13 PM
I’m trying to verify this statement but that doesn’t seem to work, am I doing it wrong? I’m setting in the
pluginManagement
block this:
extra.set("dummy", "dummy")
And on
build.gradle.kts
I read it like this:
extra.get("dummy") as String
And it says, it cannot get property “dummy” So I’m not sure if I’m doing something wrong or I can’t get it in the
build.gradle.kts
at project level
v

Vampire

05/18/2023, 10:15 PM
All extension-aware objects have extra properties. So you probably do read it from a different object than you set it to
r

Roberto Fuentes

05/19/2023, 6:36 AM
Ok, I woke up today and realized that outside means outside of the scope (This case:
pluginManagement
) not in different files. (It helps to re-read again after 8h of sleep 😂) Got it, thank you! Although my problem has been partially solved by not duplicating repos (Which is amazing 🙇) I have the feeling that there’s no way to share the function nor results or use the same function in both places:
pluginManagement
&
build.gradle.kts
root level.
v

Vampire

05/19/2023, 6:46 AM
Actually, it means both. It also works in different files, if you use the same object, like the
Gradle
instance. It just gets more dirty to do so. :-D especially as there should be no reason to do so. The only thing could be repositories and when defining them centrally using
dependencyResolutionManagement
, there is not much point in declaring them in the build script again. I even usually forbid project repositories.
r

Roberto Fuentes

05/19/2023, 9:50 AM
Oh you’re right, I was able to share the value I set in
settings.gradle.kts
to my
build.gradle.kts
buildscript block!! In my
settings.gradle.kts
pluginManagement block I set it like this:
Copy code
(gradle as ExtensionAware).extensions.extraProperties.set("dummy", "dummy")
Then on my
build.gradle.kts
buildscript block i do the same:
Copy code
println("Buildscript: ${(gradle as ExtensionAware).extensions.extraProperties.get("dummy")}")
Damn that was a nice finding, thank you!! 🙇
I guess it’s not recommended/or dirty as you said… But I dislike a lot duplicating code… And I guess since this is available in my buildscript it should also be available to other subprojects so it’s kind of reusing the code… (I think)
v

Vampire

05/19/2023, 11:28 AM
Yes, code duplication is bad. 🙂
s

Shaun Reich

05/19/2023, 10:21 PM
@Roberto Fuentes trying to understand what you're solving, because I have\am running into what sounds similar. I have realized that settings.gradle, for say...a custom Maven host repo, can't put it in a project because it won't know where to find the Conventions Plugin. But I don't think there's a good way to consolidate it. I'd still end up with extra code in settings.kts... Maven had a settings.xml that would specify this and you wouldn't have to do it for every perfect... I considered putting it into init gradle or something. It's all just used internally in the company, so "host it externally"isn't an option Probably not worth much effort for me to do it either way I guess, versus just copy paste a bunch. Should be set it and forget
r

Roberto Fuentes

05/22/2023, 6:32 PM
Hey @Shaun Reich, sorry for the delay, it definitely sounds similar to my issue Maybe some reproducible code or example code would be nice to visualize your issue. What I did is use @Vampire’s solution and leverage all the repositories into the
pluginManagement
block. Inside there I define the •
repositories
block (Which is for conventions plugin) •
dependencyResolutionManagement
repositories
block for dependencies
s

Shaun Reich

05/23/2023, 1:10 PM
okay, that is what i m doing too
180 Views