I am trying to convert a gradle build from groovy ...
# gradle
e
I am trying to convert a gradle build from groovy to Kotlin but I am stumped here - groovy version:
gradle.ext.token = "foo"
This is in settings.gradle, so rootProject is not available. (I think?!) In Kotlin "gradle" is also available in settings.xml, but it seems it does not implement "ExtensionAware", so the "extra" properties do not seem to work here.
val token: String by gradle.extra("foo")
=> Unresolved reference (on "extra")
v
Try to cast to
ExtensionAware
, any object decorated by Gradle should be
ExtensionAware
But yes, you can also set it on the root project, just a little bit different than from a build script
But generally if you try to use
ext
or
extra
you should think about doing it properly
In almost all cases it is better to model an extension class and register it with the
ExtensionAware
object, then you also get type-safety
But either way, if you want to do it on the root project instead of the gradle instance, you need something like
Copy code
gradle.rootProject {
    // do your stuff to the root project here
}
that will register an action that is done when the root project becomes available
e
Thanks a lot for the answer. Casting seems to work (but I wonder why in gradle Kotlin DSL "Gradle" class does not implement ExtensionAware). Yeah, probably that could be cleaned up, but I am not sure how: Code in my pluginManagement{} block reads the credentials for our company's artifactory and configures it so, that gradle plugins are loaded from artifactory. I think that plugin repository configuration has to be done so early that "rootProject" is not already present/working, right? It also makes the credentials available to the rest of the build by settings them as extra properties on "gradle".
v
but I wonder why in gradle Kotlin DSL "Gradle" class does not implement ExtensionAware
Neither does it in the docs. Exactly like many other objects that are not explicitly declare being extension aware. But any object that is decorated by Gradle gets this automagically and the
Gradle
instance is one of them. In Groovy you have duck-typing, so declared interfaces are meaningless, the only thing that counts is what is available at runtime. But Kotlin is strongly-typed. As a small example, this works fine (in Groovy, for Kotlin you again need the cast to
ExtensionAware
):
Copy code
interface Foo {}
def foo = objects.newInstance(Foo)
foo.ext.tada = 'oh yes, it works!'
println foo.ext.tada
 Yeah, probably that could be cleaned up, but I am not sure how:
Code in my pluginManagement{} block reads the credentials for our company's artifactory and configures it so, that gradle plugins are loaded from artifactory.
I think that plugin repository configuration has to be done so early that "rootProject" is not already present/working, right?
As I said, use e. g.
gradle.rootProject { ... }
, the lambda is executed delayed as soon as the root project is available, so there cannot be a "too soon".
It also makes the credentials available to the rest of the build by settings them as extra properties on "gradle".
The cleaner way as mentioned is to model it as extension class and register that extension either on
gradle
or maybe better on the root project. Then you have clean type-safety access and don't need the extra properties crutch. Every time you use extra properties you should feel dirty. I do and then try to do it properly. 😄 Something like (again in Groovy because copy&paste):
Copy code
extensions.create('myExtension', MyExtension)
myExtension.myProperty = 'blah'
e
Thanks again! I'll try to clean it up as you described.