Error Accessing Project with Configuration from Custom plugin

To make my code gradle code more re-usable I am moving some of my tasks into plugins.
Below is a scaled down version of a plugin I created. I am unable to get Gradle to recognize the overloaded project(path,configuration) I keep getting the following error:

This line causes the error:

project.project(path: ‘:hooks:ah-foundation-hook’, configuration: ‘serviceJar’)

Error Message:

* What went wrong:
Execution failed for task ‘:preparePluginIvyConfig’.
Could not find method project() for arguments [{path=:hooks:ah-foundation-hook, configuration=serviceJar}] on root project ‘foundation’.

However that works perfectly fine in a regular build.gradle file. In addition this works fine as well

project.project(’:hooks:ah-foundation-hook’)

I even tried changing the project variable to something else like projectA just to make sure there was no scoping issue.

My plugin

class MyIvyPlugin implements Plugin<Project> {

            void apply(Project project) {
                    project.tasks.create('preparePluginIvyConfig') {
                        description = "Prepares the IVY file by adding the appropriate plugin configurations for consumption by config name instead of individual artifact."
                        
                        doFirst {
                                def projectPluginList = [project.project(':hooks'), project.project(':portlets'), project.project(':themes'), project.project(':webs'), project.project(':layouttpl'), project.project(':ext')]
                                        
                                project.dependencies {
                                        project.project(path: ':hooks:ah-foundation-hook', configuration: 'serviceJar')
                                     ....
                                 }
...
}

For reference here is the task from my original build.gradle that I am attempting to convert to a plugin. It was tested and has been in working condition.

task prepareIvyConfig {
    description = "Prepares the IVY file by adding the appropriate configurations for consumption by config name instead of individual artifact."

    doFirst {
        dependencies {
            logger.quiet('Preparing IVY File...')
            subprojects.each { subProject ->
                logger.info("ProjectName: ${subProject.getPath()}: ")
                subProject.configurations.findAll().each { projConfig ->
                    logger.info("ConfigName: ${projConfig.getName()}:")
    
                    if(logger.isEnabled(LogLevel.INFO))  {
                        projConfig.allArtifacts.getFiles().each { configFile -> logger.info('     File     : ' + configFile) }
                    }
                    
                    if(projConfig.allArtifacts.getFiles().size() > 0) {
                        if(projConfig.getName() == 'serviceJar') {
                            plugin_service_jars project(path: subProject.getPath(), configuration: projConfig.getName())
                        }
                        else if(projConfig.getName() == 'pluginZip') {
                            plugin_zips project(path: subProject.getPath(), configuration: projConfig.getName())
                        }
                        else if(projConfig.getName() == 'archives') {
                            plugin_archives project(path: subProject.getPath(), configuration: projConfig.getName())
                        }
                        else
                        {
                            logger.info("     Skipping configuration [${projConfig.getName()}] for ivy.")
                        }
                    }//If there are files to publish
                }//End for each configuration
            }//For each Sub Project
        }//dependencies
    }
}

artifactoryPublish {
        dependsOn prepareIvyConfig
        publishConfigs 'plugin_zips', 'plugin_service_jars', 'plugin_archives'
}

Taking a cue from Lance Java I’m trying to determine how the actual gradle code works.
I’m looking at dependencies { } to see how it parses project(path, configuration).

Ultimately it returns this

DefaultProjectDependency{dependencyProject=‘project ‘:hooks:ah-foundation-hook’’, configuration=‘serviceJar’}

I’m still struggling with how .gradle is parsed into groovy. So still hoping someone might be able to shed some light on the syntax required to get my above example to work. I’ll keep digging into the code as well.

It took some digging through the code We were able to find the answer. The issue is that I was using project instead the dependency handler. I’m still trying to grasp how the code is interpreted.

So what I did was get a hold of the dependenc handler itself and use that

project.dependencies { depClosure ->

So the solution below works within my custom plugin.

void apply(Project project) {
                    project.tasks.create('preparePluginIvyConfig') {
                        description = "Prepares the IVY file by adding the appropriate plugin configurations for consumption by config name instead of individual artifact."
                        
                        doFirst {
                                project.dependencies { depClosure ->                                        
                                        myConfig depClosure.project(path: ':hooks:ah-foundation-hook', configuration: 'serviceJar')
                                     ....
                                 }

I think you’ll find the magic is in the methodMissing implementation.

More info here