Grails gradle "a task with that name already exists"
Asked Answered
P

1

8

I'm trying to create a test task rule using the example provided in the grails gradle doc but I keep getting "a task with that name already exists" error.

My build script is as follows:

import org.grails.gradle.plugin.tasks.* //Added import here else fails with "Could not find property GrailsTestTask"

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath "org.grails:grails-gradle-plugin:2.0.0"
  }
}

version "0.1"
group "example"

apply plugin: "grails"

repositories {
  grails.central() //creates a maven repo for the Grails Central repository (Core libraries and plugins)
}

grails {
  grailsVersion = '2.3.5'
  groovyVersion = '2.1.9'
  springLoadedVersion '1.1.3'
}

dependencies {
  bootstrap "org.grails.plugins:tomcat:7.0.50" // No container is deployed by default, so add this
  compile 'org.grails.plugins:resources:1.2' // Just an example of adding a Grails plugin
}

project.tasks.addRule('Pattern: grails-test-app-<phase>') { String taskName ->
    println tasks //shows grails-test-app-xxxxx task. Why?
    //if (taskName.startsWith('grails-test-app') && taskName != 'grails-test-app') {
    //    task(taskName, type: GrailsTestTask) {
    //        String testPhase = (taskName - 'grails-test-app').toLowerCase()
    //        phases = [testPhase]
    //    }
    //}
}

Running $gradle grails-test-integration or in fact anything of the form $gradle grails-test-app-xxxxxxxx yields the error "Cannot add task 'gradle grails-test-app-xxxxxxxx as a task with that name already exists".

Can someone please advise how I can resolve this error? Thanks.

Powers answered 24/3, 2014 at 2:52 Comment(10)
Have you tried with a different task name pattern? Have you tried to check for existence of a task before adding it?Kleper
Hi Peter, yes I've tried different patterns it always fails with the error "Cannot add task... a task with that name already exists."Powers
Strange. Chances are the problem is somehow connected to the grails-gradle-plugin (which I'm not familiar with).Kleper
My best guess is that the grails-gradle-plugin itself adds a "catch all" task rule that delegates to the Grails build system. In that case, you may not be able to declare your own task rules when using this plugin.Kleper
@PeterNiederwieser: I think you are right. Looking through the plugin's source code, there is an addRule that creates tasks for patterns prefixed with 'grails-'. Is there a way I can create a task of the same pattern that precedes the plugin? I.e. in build.gradle how do I create a task of the form grails-XXX before the plugin does? Or is that ill-advised?Powers
You could try to add your own pattern before applying the grails plugin. Or you use a different pattern.Kleper
@PeterNiederwieser: Thanks. Creating my custom rule before applying the plugin did not work since the plugin will try to create the same rule. Like you mentioned, I'll probably have to use a different pattern. Thanks once again for your help.Powers
@PeterNiederwieser: I think there is an issue with addRule. I commented out the contents of the addRule block and replaced it with println tasks (pls see edited post above). The task with pattern grails-XXXX gets created with just the call to addRule. If addRule is removed, the task is never created. Somehow addRule is creating the task even though i do not explicitly call tasks.create in my build script.Powers
Try w/o applying the Grails plugin. It's more likely something about that plugin.Kleper
@PeterNiederwieser: I would like to debug this issue. Can you please advise how I can trace the addRule calls? Seems like the addRule was overriden in the plugin. Can it be overriden?Powers
E
12

If you don't mind overriding the task created by the plugin, you might want to try

task(taskName, type: GrailsTestTask, overwrite: true)

In general, when using task rules that can be called multiple times (for instance if you have multiple tasks depending on a task eventually added by your rules), I use the following test before actually creating the task:

if (tasks.findByPath(taskName) == null) {tasks.create(taskName)}

This will call the task() constructor only if this task name does not exists.

Evita answered 8/9, 2014 at 18:47 Comment(2)
What does it mean to "override a task"? Does it mean that the current execution of the task gets negated when another code calls it.Palaeozoology
It means that you replace the task provided by the plugin with your task definition. The one that gets executed is yours. See the documentation for more details: docs.gradle.org/current/userguide/…Evita

© 2022 - 2024 — McMap. All rights reserved.