Applying Java and Idea plugin in a custom plugin


(Sa'ad) #1

Hi Everything,

First, I am newbie when it comes to creating a custom plugin. But I have played around and was able to create a custom plugin that in turn applies the Java plugin.

I do few things with this Java plugin, that I want share with all the projects I am working with. One of the thing I wanted to do is to add an integration test sourceSet and task. This seemed work fine with the following

class GwappsJavaPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.pluginManager.apply(JavaPlugin)
        project.sourceSets {
            integrationTest {
                java.srcDir new File('src/it/java')
                resources.srcDir new File('src/it/resources')
                compileClasspath = project.sourceSets.main.output + project.configurations.testRuntime
                runtimeClasspath = output + compileClasspath
            }
        }

        project.task("integrationTest", type: Test) {
            testClassesDir = project.sourceSets.integrationTest.output.classesDir
            classpath = project.sourceSets.integrationTest.runtimeClasspath
        }

       project.check.dependsOn project.integrationTest
    }
}

The above seems work fine. Please do tell me if I am doing anything wrong here. I simply copy the build script in my plugin (appending project) and it seemed to work.

I can use the plugin in my project, I get integrationTest task, I can run the tests under src/it/java. When I build, I get the tests run as well.

But I use IntelliJ. So if I want to run the tests in IntelliJ with code coverage, I have to mark the directory src/it/java explicitly as test sources (by default inteliJ marks it as sources root and miscalculates coverage by including the test files). I wanted automate the marking with gradle idea plugin.

If I use the idea plugin in my project where I use the above plugin, things are fine. That is, in my project, I apply my custom plugin, then apply idea, and the do

idea {
    module {
        testSourceDirs += file('src/it/java')
    }
}

All is fine. I get the src/it/java marked as test sources (IntelliJ paints the folder as green), and everything works as expected. But I want to do this in my custom plugin, so tried the following:

class GwappsJavaPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.pluginManager.apply(JavaPlugin)
        project.pluginManager.apply(IdeaPlugin)
        project.sourceSets {
            integrationTest {
                java.srcDir new File('src/it/java')
                resources.srcDir new File('src/it/resources')
                compileClasspath = project.sourceSets.main.output + project.configurations.testRuntime
                runtimeClasspath = output + compileClasspath
            }
        }

        project.task("integrationTest", type: Test) {
            testClassesDir = project.sourceSets.integrationTest.output.classesDir
            classpath = project.sourceSets.integrationTest.runtimeClasspath
        }
       
        project.check.dependsOn project.integrationTest
        
        project.idea {
            module {
                testSourceDirs += new File('src/it/java')
            }
        }
    }
}

it does not work. That is, in IntelliJ src\it\java remains as sources root, rather than test sources. Note that if I use

project.idea {
    module {
        testSourceDirs += new File('src/it/monkey')
    }
}

the directory src/it/monkey does get marked as test sources, so I can assume that applying idea from my custom plugin works. It’s just somehow both sourceSet definition and idea testSourceDirs clashes when applied within a custom plugin and default sourceSet definition wins.

Any help?


(René Groeschke) #2

you want to do java.srcDirs = [new File('src/it/java\'] here. otherwise you assign an additional source folder to the sourceset.

What I usually recommend is to do the following:

plugins.withType(org.gradle.plugins.ide.idea.IdeaPlugin) { // lazy as plugin not applied yet
    idea {
        module {
            testSourceDirs += sourceSets.it.java.srcDirs
            testSourceDirs += sourceSets.it.resources.srcDirs
            scopes.TEST.plus.add(configurations.itCompile)
            scopes.TEST.plus.add(configurations.itRuntime)
        }
    }
}

this allows you to let the developer choose the IDE and only apply the logic IF the idea plugin is used.


(Sa'ad) #3

fantastic. that worked!!! thanks a ton