Elye
Elye

Reputation: 60081

Gradle: Can't pass argument to class in plugin

I tried as per example in, and simplified it to just "message".

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        def extension = project.extensions.create('greeting', GreetingPluginExtension, project)
        project.tasks.create('hello', Greeting) {
            message = extension.message
        }
    }
}

class GreetingPluginExtension {
    def String message = "aa"

    GreetingPluginExtension(Project project) {
        message = project.property(String)
    }

}

class Greeting extends DefaultTask {
    @Input
    def String message = project.property(String)

    @TaskAction
    def testCoverageVerification() {
        logger.quiet("Message is")
        logger.quiet(message)
    }
}

apply plugin: GreetingPlugin

greeting {
    message = 'Hi from Gradle'
}

When I run ./gradlew -q hello, I got

Message is
value: null

I expect it to be

Message is
value: Hi from Gradle

Why did my String from the greeting fail to pass in?

Upvotes: 4

Views: 989

Answers (2)

Elye
Elye

Reputation: 60081

I manage to resolve my issue by directly getting it from project.greeting.message

@TaskAction
def testCoverageVerification() {
    message = project.greeting.message
    logger.quiet("Message is")
    logger.quiet(message)
}

Upvotes: 0

Opal
Opal

Reputation: 84786

Actually, it's quite easy to explain. The plugin (hence the task creation and variable value assignment) is applied and evaluated before the extension block is evaluated. So the task is created even before the extension's value is set. From the link you provided:

The extension declaration in the build script as well as the mapping between extension properties and custom task properties occurs during Gradle's configuration phase of the build lifecycle. To avoid evaluation order issues, the actual value of a mapped property has to be resolved during the execution phase.

To make it work you can change the plugin declaration to this:

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        def extension = project.extensions.create('greeting', GreetingPluginExtension, project)
        project.tasks.create('hello', Greeting) {
            doFirst {
              message = extension.message
            }
        }
    }
}

However it doesn't make much sense - so don't use it ;)

Upvotes: 1

Related Questions