Slackbot
01/05/2023, 3:41 PMJavi
01/05/2023, 3:41 PMREADME.md
https://github.com/Reproducers/repro-gradle-dslJavi
01/05/2023, 3:43 PMconfigure
function when they are being created and later with the "manual" accessor modify them.
repro {
nestedRepro {
someProperty.set("foo")
}
}
Javi
01/05/2023, 3:46 PMrepro
extension is using the()
to fetch a extension which for some reason it doesn't exist yet, ReproNestedExtension
open class ReproExtension
@Inject
constructor(
project: Project,
objects: ObjectFactory,
) : BaseReproExtension(project, objects) {
val reproNested: ReproNestedExtension
get() = the()
fun reproNested(action: Action<ReproNestedExtension> = Action {}) {
action.execute(reproNested)
}
}
abstract class BaseReproExtension
@Inject
constructor(
project: Project,
objects: ObjectFactory,
) : Project by project, ObjectFactory by objects {
internal open fun configure() {
val className = this::class.simpleName ?: "Unknown"
val configurationName =
if (name.endsWith("_Decorated")) className.substringBefore("_Decorated") else className
println("Configuring $configurationName")
}
}
Javi
01/05/2023, 3:48 PMplugins {
id("com.javiersc.repro.plugin") version "0.1.0"
}
// Those both works
the<ReproExtension>()
the<ReproNestedExtension>()
// This works
repro {
}
// This doesn't work, the reported error is
// > Extension of type 'ReproNestedExtension' does not exist.
// > Currently registered extension types: [ExtraPropertiesExtension]
repro {
reproNested {
}
}
Javi
01/05/2023, 3:51 PMProject
delegation in the BaseReproExtension
? Each extension is a "different" project so they haven't the extension registered? It is weird to me but I haven't used the Kotlin delegation feature a lotMartin
01/05/2023, 3:53 PMEach extension is a "different" projectHow are they different projects?
Javi
01/05/2023, 3:53 PMJavi
01/05/2023, 3:54 PMMartin
01/05/2023, 3:54 PMMartin
01/05/2023, 3:55 PMJavi
01/05/2023, 3:55 PM@Inject
to confirm, one secondJavi
01/05/2023, 3:57 PMMartin
01/05/2023, 3:58 PMMartin
01/05/2023, 3:58 PMthis.extensions
goes to your extension extensions (!) and not the project extensionsMartin
01/05/2023, 3:58 PMJavi
01/05/2023, 3:59 PMMartin
01/05/2023, 4:03 PMMaybe your extension is itself ExtensionAwareLooks like your extension itself isn't ExtensionAware but Gradle might decorate it into something that is ExtensionAware
Martin
01/05/2023, 4:05 PMReproExtension_Decorated
Javi
01/05/2023, 4:08 PMnestedExtension
inside the reproExtension
but it doesn't work too
open class ReproPlugin : Plugin<Project> {
override fun apply(target: Project) {
val reproExtension = target.extensions.create<ReproExtension>("_InternalRepro")
reproExtension.configure()
val reproNestedExtension =
reproExtension.extensions.create<ReproNestedExtension>("_InternalReproNested")
reproNestedExtension.configure()
}
}
Martin
01/05/2023, 4:13 PMJavi
01/05/2023, 4:13 PMJavi
01/05/2023, 4:14 PMMartin
01/05/2023, 4:14 PMconfigured eagerlywhat do you mean by that?
Javi
01/05/2023, 4:15 PMobjects.newInstance()
, but that mean if a user doesn't call the parent wrapper, it will not be created, so that is the reason I need to create them eagerly.Javi
01/05/2023, 4:16 PMReproPlugin
class, all extension are eagerly created, then the default configuration is executed. Later the user can modify it via the custom accessor
fun Project.repro(action: Action<ReproExtension>) {
action.execute(the())
println("After configuration `someProperty`: ${the<ReproNestedExtension>().someProperty.get()}")
}
Javi
01/05/2023, 4:17 PMMartin
01/05/2023, 4:19 PMval repoExtension = target.extensions.create<ReproExtension>("repo")
repoExtension.configure()
?Martin
01/05/2023, 4:20 PMMartin
01/05/2023, 4:20 PMJavi
01/05/2023, 4:23 PMprintln
part, in the real example it is not a println
, it does some configurations and lazy configurations, check the total state of all configuration is correct, and so on.
hubdle {
kotlin {
// disallowed more than one Kotlin at the same time
android()
jvm()
multiplatform()
}
}
fun Project.hubdle(action: Action<HubdleExtension>) {
action.execute(the())
checkOnlyOneKotlinIsEnabled()
for (applicablePlugin in applicablePlugins) applicablePlugin.apply()
for (configurable in configurables) configurable.configure()
for (lazyConfigurable in lazyConfigurables) lazyConfigurable.get().configure()
...
}
Martin
01/05/2023, 4:24 PMJavi
01/05/2023, 4:25 PMMartin
01/05/2023, 4:26 PMhubdle {
someArtificialFunction {
kotlin {
// disallowed more than one Kotlin at the same time
android()
jvm()
multiplatform()
}
}
}
Martin
01/05/2023, 4:26 PMsomeArtificialFunction
is a function you control where you have the action
and can do checks before/afterJavi
01/05/2023, 4:27 PMkotlin
is indeed my extension. It could be that too, but I think it is easier to remove delegation to get it working. I would like to bypass it tho.Javi
01/05/2023, 4:31 PMthe
based on the below one would workJavi
01/05/2023, 4:32 PMJavi
01/05/2023, 4:36 PMextensions
solves my problem, anyway, thank you for all your help as it was caused by ExtensionAware
and you give me the hint 😄Martin
01/05/2023, 4:48 PM