🍏 iOS / Mac OSInstall iOS 27 today — there’s no reason to wait(12.09.2026 um 15:00 Uhr)
🔧 AI Nachrichten How I’m using Codex and ChatGPT on my Mac(01.09.2026 um 00:00 Uhr)
🕵️ SicherheitslückenProFTPD mod_sql post-authentication SQLi RCE(06.09.2026 um 18:21 Uhr)
🕵️ Sicherheitslücken[remote] CVE-2026-42167 - ProFTPD mod_sql post-authentication SQLi - RCE(25.08.2026 um 02:00 Uhr)
🕵️ Sicherheitslücken[webapps] C-MOR 6.0104 - Cross-Site Scripting (XSS)(31.08.2026 um 02:00 Uhr)
🕵️ Sicherheitslücken[webapps] CubeCart 6.7.4 - Stored XSS(31.08.2026 um 02:00 Uhr)
🍏 iOS / Mac OSInstall iOS 27 today — there’s no reason to wait(12.09.2026 um 15:00 Uhr)
🔧 AI Nachrichten How I’m using Codex and ChatGPT on my Mac(01.09.2026 um 00:00 Uhr)
🕵️ SicherheitslückenProFTPD mod_sql post-authentication SQLi RCE(06.09.2026 um 18:21 Uhr)
🕵️ Sicherheitslücken[remote] CVE-2026-42167 - ProFTPD mod_sql post-authentication SQLi - RCE(25.08.2026 um 02:00 Uhr)
🕵️ Sicherheitslücken[webapps] C-MOR 6.0104 - Cross-Site Scripting (XSS)(31.08.2026 um 02:00 Uhr)
🕵️ Sicherheitslücken[webapps] CubeCart 6.7.4 - Stored XSS(31.08.2026 um 02:00 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 4 Min Lesezeit
0

Gradle extensions part 2: Now with shenanigans

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Photo by



Welcome to the spiritual successor to



As part of my long-running quest to Destroy buildSrc With Fire, I have recently had occasion to learn how to add extensions to other kinds of types, such as tasks. We have code like this duplicated across many many repos that are under our care:




CODE
// buildSrc/src/main/kotlin/magic/Magic.kt
package magic

object Magic {
fun shouldPracticeTheDarkArts(): Boolean {
return System.getenv("DO_ANCIENT_MAGIC")?.toBoolean()
?: System.getenv("DO_SLIGHTLY_MORE_MODERN_MAGIC")?.toBoolean()
?: false
}
}






This code is used in build scripts like this:




CODE
// build.gradle.kts
import magic.Magic

tasks.withType<Test>().configureEach {
if (Magic.shouldPracticeTheDarkArts()) {
logger.quiet("👻")
}
}






There are several things about this that I'd like to improve:




  1. I don't want this code in buildSrc. I want a version of it in our build-logic that is under test and which is shared widely (instead of duplicated in a dozen different repos).

  2. I don't like the import. It is Unclean. (Build scripts should be simple, declarative, easy for tools to parse.)

  3. I'm not a big fan of calling System.getenv() in a Gradle context. I prefer to use the . This means they all have an ExtensionContainer available on which new extensions can be created and added.




    CODE
    package magic

    abstract class TestMagicExtension @Inject constructor(
    private val providers: ProviderFactory
    ) {

    internal companion object {
    const val NAME = "magic"

    fun create(
    testTask: Test,
    providers: ProviderFactory,
    ) {
    testTask.extensions.create(
    NAME,
    TestMagicExtension::class.java,
    providers,
    )
    }
    }

    fun shouldPracticeTheDarkArts(): Boolean {
    return providers
    .environmentVariable("DO_ANCIENT_MAGIC")
    .orElse(providers.environmentVariable("DO_SLIGHTLY_MORE_MODERN_MAGIC"))
    .map { it.isNotEmpty() }
    .getOrElse(false)
    }






    And in our plugin, we can add this to all our Test tasks:




    CODE
    project.tasks.withType<Test>().configureEach { t ->
    TestMagicExtension.create(t, project.providers)
    }






    And now we can update our build scripts:




    CODE
    // build.gradle.kts
    import magic.TestMagicExtension

    tasks.withType<Test>().configureEach {
    // the "extensions" call is on the Test instance,
    // not the project instance
    val magic = extensions.getByType(TestMagicExtension::class.java)
    if (magic.shouldPracticeTheDarkArts()) {
    logger.quiet("👻")
    }
    }






    ...that's not better at all!






    Groovy: An interlude



    First of all, let's take a step back and remind ourselves that "we love Kotlin, type safety is great, I don't care that performance is worse..." We can say that over and over again a few times while rocking in a fetal position on the floor till we feel better. Now, here's the same build script but in Groovy:




    CODE
    // build.gradle
    tasks.withType(Test).configureEach {
    if (magic.shouldPracticeTheDarkArts()) {
    // I'm being cheeky by also omitting the
    // "redundant" parentheses
    logger.quiet "👻"
    }
    }






    Groovy isn't supposed to be better! Damnit!






    Sprinkle on some shenanigans



    How the heck does Gradle Kotlin DSL do it? Why isn't it generating "typesafe accessors" for my test task extension? Well, that second one is a good question and I have no answer. But for the first... let's just "generate" (that is, write) our own typesafe accessors!



    We add some code in a new (to us) package:




    CODE
    package org.gradle.kotlin.dsl

    import magic.TestMagicExtension

    public val Test.magic: TestMagicExtension
    get() = extensions.getByType(TestMagicExtension::class.java)

    public fun Test.magic(configure: TestMagicExtension.() -> Unit) {
    configure(TestMagicExtension.NAME, configure)
    }






    And now we can update our Kotlin DSL build script:




    CODE
    // build.gradle.kts
    tasks.withType<Test>().configureEach {
    if (magic.shouldPracticeTheDarkArts()) {
    logger.quiet("👻")
    }
    }






    Here we're (ab)using the fact that Gradle automatically imports everything in the org.gradle.kotlin.dsl package into build scripts, so all those functions are Just There (in a global namespace, so be careful!).



    This is a common enough pattern that Gradle itself uses it in its (from, er, 2018) on Gradle's issue tracker with a feature request to permit custom plugins to add their own default imports with resorting to using split packages like this.



    Now go forth and be merry, for it is that time of year.

    Vollständiger Original-Bericht
    Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
    ↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Windows 10 und 11: Update zerschießt Druckfunktion und PDF-Export
1 Quelle
Nvidia killt Windows-10-Support - Bald keine Game-Ready-Treiber mehr
1 Quelle
Windows 10 weiter stabil - die Nutzerzahlen im August 2026
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Gradle extensions part 2: Now with shenanigans

Thematisch verwandte Begriffe: Gradle, extensions, part, with · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...