# Kotlin Syntax for PluginManager

**URL:** <https://discuss.gradle.org/t/kotlin-syntax-for-pluginmanager/46184>\
**Category:** Help/Discuss\
**Created:** [August 4, 2023, 3:50am UTC](https://discuss.gradle.org/t/kotlin-syntax-for-pluginmanager/46184 "2023-08-04T03:50:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![austinarbor](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@austinarbor](https://discuss.gradle.org/u/austinarbor)\
**Post date:** [August 4, 2023, 3:50am UTC](https://discuss.gradle.org/t/kotlin-syntax-for-pluginmanager/46184/1 "2023-08-04T03:50:31Z")

</div>

What’s the Kotlin syntax for programmatically configuring plugins from the parent project?

In groovy, I have something like the below in my `build.gradle`

```groovy
subprojects {
 pluginManager.withPlugin('com.github.johnrengelman.shadow') {
        jar {
            enabled = false
        }

        shadowJar {
            mergeServiceFiles()
            archiveBaseName.set("${it.name}")
            archiveClassifier.set('')
            archiveVersion.set('')
        }
    }
}

```

I converted this to what I thought would be the equivalent `build.gradle.kts`

```plaintext
subprojects {
  val project = this
  pluginManager.withPlugin("com.github.johnrengelman.shadow") {
        project.tasks.withType<Jar>().configureEach {
            enabled = false
        }
        project.tasks.withType<ShadowJar>().configureEach {
            mergeServiceFiles()
            archiveBaseName = project.name
            archiveClassifier = ""
            archiveVersion = ""
        }
    }
}

```

But the shadow jar isn’t being built. I also tried without `project.tasks...` but that doesn’t work either. Any ideas?

---

<div class="post-metadata">

**Author:** ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)\
**Post date:** [August 4, 2023, 9:30am UTC](https://discuss.gradle.org/t/kotlin-syntax-for-pluginmanager/46184/2 "2023-08-04T09:30:33Z")

</div>

To start with, using `subprojects { ... }` is a code smell.  
Practically any usage of it is bad practice and should be avoided.  
You should instead write convention plugins that you then apply to the projects where you want them to take effect, directly.  
With using `subprojects { ... }` you introduce project coupling which is bad for more sophisiticated and also some upcoming features of Gradle that make your build faster. Besides that it makes the build better readable and also better maintainable.

`ShadowJar` extends `Jar`.  
So by disabling all `Jar` tasks, you are also disabling the `shadowJar` task, as well as sources jar tasks, javadoc jar tasks and all other jar tasks you might have.  
What you meant was `tasks.named("jar") { enabled = false }` or `val jar by tasks.existing; jar { enabled = false }`.

---

<div class="post-metadata">

**Author:** ![austinarbor](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@austinarbor](https://discuss.gradle.org/u/austinarbor)\
**Post date:** [August 4, 2023, 1:57pm UTC](https://discuss.gradle.org/t/kotlin-syntax-for-pluginmanager/46184/3 "2023-08-04T13:57:31Z")

</div>

@Vampire thanks for the help! I’ve been having a hard time trying to figure out when to use `configure `vs `tasks.`… (probably a lack of understanding on my part).

I think the convention plugin will solve that problem as well so I’ll look into that to decouple the projects.

Appreciate the quick response

---

<div class="post-metadata">

**Author:** ![austinarbor](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@austinarbor](https://discuss.gradle.org/u/austinarbor)\
**Post date:** [August 6, 2023, 11:12pm UTC](https://discuss.gradle.org/t/kotlin-syntax-for-pluginmanager/46184/4 "2023-08-06T23:12:03Z")

</div>

@Vampire is there an easy way to keep the dependency versions in sync between buildSrc for the conventions and the parent project?

- I have a platform module in the project, but buildSrc can’t seem to find it
- I can’t seem to access extra properties set in parent project from `buildSrc`

Are there other approaches that can be used? Ideally the solution would also be compatible with dependabot if possible

Also, the Gradle docs recommend using `buildSrc` for convention plugins, but other comments around the web mention that `includeBuild` may be a better choice. Do you have any opinion on the two?

EDIT:  
After playing around some more, I can probably use `library.versions.toml` to share the versions between the two. In the convention plugin’s `settings.gradle.kts` I can do

```plaintext
dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

```

to import the parent project’s versions so I only have to define it in one place. In addition, dependabot supports versions from this file. I guess my only remaining question would be on `buildSrc` vs `includeBuild`

---

<div class="post-metadata">

**Author:** ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)\
**Post date:** [August 7, 2023, 2:24pm UTC](https://discuss.gradle.org/t/kotlin-syntax-for-pluginmanager/46184/5 "2023-08-07T14:24:29Z")

</div>

> I can’t seem to access extra properties set in parent project from `buildSrc`

That’s correct, especially as `buildSrc` is built before your main build it of course cannot access anything from the main build.  
But using “extra” properties is bad practice anyway. In almost all cases it is just a work-around for not doing something properly, or just copy & past from bad advices.  
As you found out, using version catalogs is a better strategy to define versions and libraries.

> Also, the Gradle docs recommend using buildSrc for convention plugins, but other comments around the web mention that includeBuild may be a better choice. Do you have any opinion on the two?

My personal opinion is an included build.  
Some of the differences between using `buildSrc` and an included build are mitigated in Gradle 8 where `buildSrc` is made more similar to an included build.  
In many cases it does not make much difference anymore, but there are cases where an included build is better, so I just always use an included build except for the rare cases where only `buildSrc` works like monkey-patching an existing 3rd party plugin which you usually do not need.

But if you only have convention plugins that you practically use in all projects’ builds anyway, you could also use `buildSrc`. If you have many projects and use some things only in some projects, an included build could improve performance, if you also separate the code into multiple projects within the included build or into multiple included builds. Or if you need conflict resolution because you do only some things in convention plugins and apply other plugins directly in the build scripts, it might be preferable to use an included build as you then get conflict resolution.

So there are a few nuances that might lean to one approach or the other, but I personally always prefer an included build unless I have concrete reason to use `buildSrc` instead.
