# Adding task extensions and typesafe accessors in Gradle Kotlin DSL

DevFeed: [Adding task extensions and typesafe accessors in Gradle Kotlin DSL](<https://devfeed.tech/articles/gradle-extensions-part-2-now-with-shenanigans-30461.md>)

Original publisher: [Read original article](<https://dev.to/autonomousapps/gradle-extensions-part-2-now-with-shenanigans-12m6>)

Author: Tony Robalik

Published: 2024-12-11T23:05:12Z

Content type: tutorial

Language: en

Sources: [DEV Community: Tony Robalik](<https://devfeed.tech/sources/dev-community-tony-robalik.md>)

Topics: [Gradle](<https://devfeed.tech/topics/gradle.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [build](<https://devfeed.tech/tags/build.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [extensions](<https://devfeed.tech/tags/extensions.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [software](<https://devfeed.tech/tags/software.md>)

## AI overview

This tutorial explains how to add extensions to Gradle tasks and create custom typesafe accessors for use in Kotlin DSL build scripts. It discusses moving shared logic into build-logic, using ProviderFactory, and relying on Gradle's default package imports.

## Source excerpt

Photo by Karsten Würth on Unsplash Welcome to the spiritual successor to Gradle plugins and extensions: A primer for the bemused (one of my most popular posts, such that it competes for space with actual Gradle documentation at the top of a Google search). 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: // 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: // 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: 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). I don't like the import. It is Unclean. (Build scripts should be simple, declarative, easy for tools to parse.) I'm not a big fan of calling System.getenv() in a Gradle context. I prefer to use the ProviderFactory. Extending Test tasks Many Gradle types, including all Tasks (and of course the Project type), are ExtensionAware. This means they all have an ExtensionContainer available on which new extensions can be created and added. // build-logic/src/main/kotlin/magic/TestMagicExtension.kt 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 shouldPracticeTheDar