Android Root Project to Custom Gradle Plugin

Hi, I am creating a custom gradle plugins for all my packages.

  1. Android App Custom Gradle
  2. Android Lib Custom Gradle
  3. Java Lib Custom Gradle
  4. Kotlin Lib Custom Gradle.

All these work fine.

Now, I am trying to create a Custom Gradle Plugin for my root project
plugins {
id ‘com.android.application’ version ‘7.2.2’ apply false
id ‘com.android.library’ version ‘7.2.2’ apply false
id ‘org.jetbrains.kotlin.android’ version ‘1.8.10’ apply false
}

I did not find a way to apply plugin with ‘false’ in Gradle custom plugins.

So, I am directly applying plugins to corresponding Plugins.

Example:
In Android App Custom Gradle I am directly adding the dependency:
dependencies.add(“implementation”, “com.android.application:com.android.application.gradle.plugin:7.2.2”)
plugins.apply(“com.android.application”)

But I get ‘implementation’ not found.

Can someone let me know , how I can create a CustomGradlePlugin for root project or apply it directly to my plugins?

In Android App Custom Gradle I am directly adding the dependency:
dependencies.add(“implementation”, “com.android.application:com.android.application.gradle.plugin:7.2.2”)
plugins.apply(“com.android.application”)

You try to add the AGP as dependency to your project.
That makes little sense.
Your actual android app does not depend on the AGP, your convention plugin does.
And that is where you need to add the dependency.
You add it in the build script of the project that is building your convention plugin as dependency of your convention plugin project, not as dependency of the project where you apply the plugin to.

And having a plugin in plugins { ... } block with apply falsehas only one use. That is to add that plugin to the build script classpath. So the according action with a convention plugin would be to declare those plugins asruntimeOnly` dependencies for that convention plugin build. The plugin itself would then not do any actions but will just be applied so that its dependencies are dragged into the classpath too.

I think I am following you.

So, in the Android App Custom Gradle plugin (this is my convention plugin)

I will add buildscript classpath

buildscript.dependencies.add(“classpath”, “com.android.application:com.android.application.gradle.plugin:7.2.2”)

Then just apply my plugin directly in the same convention plugin

plugins.apply(com.android.application).

–This one one worked-- Thank you

Can you elaborate on this line : “runtimeOnly` dependencies for that convention plugin build” ?

No, you do not modify buildscript in your convention plugin.
Your convention plugin is built in an own build.
This build has an own build script.
In that build script you define that your plugin code has a dependency on the AGP.

I can hardly be more concrete, as you did not provide information for that.

In the project level build level repositories I added all my build scripts and my convention plugin is pulling it from there.

This abstract description does not tell me too much.
Either just do what I recommended, or please provide more concrete information like an MCVE or at least a directory layout of your files.

Actually, it did not work. Gradle used old-cache and was running before. After I clear the cache, it failed again.

Here is what I am trying to do:

  1. Create a project with plugins. I have Android App Plugin, Android Lib Plugin, Kotlin Lib Plugin and Java Lib Plugin. When I apply these plugins to corresponding projects or submodule, then it all works. So, far it is good.

  2. Android has a root level build.gradle that only has classpath dependencies

And Android has an App level build.gradle where I apply my custom plugins and it works.

plugins {
    id 'com.android.application.sampleapplicationPlugin'
}
  1. Now, what I am trying to do is, I am trying to change Android root level project build.gradle also into a custom gradle plugin.

So, I did something like this:


class AndroidRootProjectPlugin: Plugin<Project>() {
override fun apply(target: Project) {
        target.repositories.maven {
            target.buildscript.dependencies.add(
                "classpath",
                "com.android.application:com.android.application.gradle.plugin:7.2.2"
            )
        }

        target.repositories.maven {
            target.buildscript.dependencies.add(
                "classpath",
                "com.android.library:com.android.library.gradle.plugin:7.2.2"
            )
        }

        target.repositories.maven {
            target.buildscript.dependencies.add(
                "classpath",
                "org.jetbrains.kotlin.android:org.jetbrains.kotlin.android.gradle.plugin:1.8.10"
            )
        }
    }
}

Now, I get this error " > Cannot change dependencies of dependency configuration ‘:classpath’ after it has been resolved."

  1. My settings.gradle has the correct repositories:
pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "My Application"
include ':app'

I cannot change settings,gradle because I want to give all my Android teams to use new AndroidRootPlugin that will define versions to apply at Android root level build.gradle.

Besides that doing what you do within repositories.maven { ... ] makes absolutely no sense, I told you not to try to modify buildscript.dependencies.
What is still unclear to me is, where do you define that plugin?
This AndroidRootProjectPlugin class must be built somewhere.
The build that builds this class should have a build script.
In that build script you define your dependencies as runtimeOnly dependencies.
Your apply method will be empty as its only sense is to drag in the declared dependencies transitively into the classpath.

I corrected my understanding on this buildscript.dependencies.

(Ignore my terminology that I used before)

I added dependencies in those custom plugins build scripts.

And just applied plugins in AndroidRootProjectPlugin and it works.

Again, you should not use any buildscripts blocks, but define dependencies in the build script of those plugins!

Thank you for @Vampire for helping me on this issue.