Configuration based on plugin extension

I have an extension that creates some kind of build profiles, and I’d like to create configurations associated with them.

The build.gradle looks something like:

profiles {
    dev
    systemTest
}

dependencies {
    systemTestProfile 'junit:junit:4.12'
}

The plugin:

class BuildProfilePlugin implements Plugin<Project> {
    private static final String EXTENSION_NAME = "profiles"

    @Override
    void apply(Project project) {
        NamedDomainObjectContainer<BuildProfile> profileContainer = project.container(BuildProfile)
        project.extensions.add(EXTENSION_NAME, profileContainer)

        project.afterEvaluate {
            def profiles = project.extensions.getByName(EXTENSION_NAME)
            profiles.each { BuildProfile profile ->
                project.configurations.create("${profile.name}Profile")
                project.task("jar${profile.name.capitalize()}", type: Jar)
            }
        }
    }
}

class BuildProfile {
    String name
    String jarName

    BuildProfile(String name) {
        this.name = name
    }
}

The profiles get created and I can create tasks specific for them. However, I’m not able to use the configurations associated with the profiles, as they’re not available yet at the point where dependencies are defined.

I get the following error:
Could not find method systemTestProfile() for arguments [junit:junit:4.12] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

I can see the java plugin does something similar with sourcets, where configurations are created on the fly but I haven’t been able to work out how they do it yet.

I’ve realised that if I use profiles.all instead of each, I don’t need to use project.afterEvaluate.

Still trying to understand what all does differently.

each executes the closure against all existing objects in the collection, as it is at that moment. all executes the closure against all existing objects in the collection as well as any objects added in the future.

1 Like