1

I'm writing a gradle plugin to generate Java code. My plugin generates code that's based on the Android R class, so it's dependent on the

processVariantResources

Task. In my plugin, I'm using this code to do that:

class MyPlugin : Plugin<Project> {
override fun apply(project: Project) {

    val extension = project.extensions.create<MyPluginExtension>(PLUGIN_NAME, MyPluginExtension::class.java)
    project.tasks.whenTaskAdded { task ->
        if (task.name.startsWith("process") && task.name.contains("Resources") && !task.name.contains("Test")) {
            val index = task.name.indexOf("Resources")
            val variantName = task.name.substring(7, index)

            //Create my task and add it to the project, make it dependent on processResources
            project.task("my${variantName}ResourceTask") {
                it.doLast {
                    generateSomeCodeForVariant(project, extension, variantName)
                }
                taskList.add(it)
            }.dependsOn(task)
        }
    }

    project.afterEvaluate {
            val appExtension = project.extensions.findByType(AppExtension::class.java)
            appExtension?.applicationVariants?.all { variant ->
                val myTask = project.tasks.getByName("my${variant.name.capitalize()}ResourcesTask")
                    val outputDir = "${project.buildDir}/generated/source/myplugin/${variant.name}"

                    //register my task as java generating
                    variant.registerJavaGeneratingTask(myTask, File(outputDir))
            }
    }
}

then, in the build.gradle of the project where I'm using this plugin, I've added

android {
    sourceSets {
        main {
            java.srcDirs += ['build/generated/source/myplugin']
            kotlin.srcDirs += ['build/generated/source/myplugin']
        }
    }
}

My plugin actually generates source code to the directory:

build/generated/source/myplugin/com/mygroup/myartifact

Anyway, the code gets generated correctly, and put in the correct place, but I can't get the compiler to recognize my generated code. Any help would be appreciated.

1 Answer 1

1

I refactored the code and implemented the strategy describe here:

my new code looks like this:

project.afterEvaluate {
        val appExtension = project.extensions.findByType(AppExtension::class.java)
        appExtension?.applicationVariants?.all { variant ->

            val processResourcesTask = project.tasks.getByName("process${variant.name.capitalize()}Resources")
            val myTask = it.task("my${variant.name.capitalize()}ResourceTask") {
                it.doLast {
                    doSomeStuff(project, extension, variant.name.capitalize())
                }
            }.dependsOn(processResourcesTask)

            val outputDir = "${project.buildDir}/generated/source/myplugin/${variant.name}"
            variant.registerJavaGeneratingTask(myTask, File(outputDir))
            val kotlinCompileTask = it.tasks.findByName("compile${variant.name.capitalize()}Kotlin") as? SourceTask
            if (kotlinCompileTask != null) {
                kotlinCompileTask.dependsOn(myTask)
                val srcSet = it.objects.sourceDirectorySet("myplugin", "myplugin").srcDir(outputDir)
                kotlinCompileTask.source(srcSet)
            }
        }
    }

I also removed the sourceSets definition from the client build.gradle file, and now everything works correctly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.