2

I have gradle build script for a multi module project.

For better readability I'd like to extract some methods, but when I do the script fails with an exception:

Cannot add task ':signArchives' as a task with that name already exists.

Full reproducable example: Have an otherwise empty directory, with two files in it:

settings.gradle

include 'eins', 'zwei'

build.gradle

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

allprojects {
    apply plugin: 'signing'
}

subprojects {
    signing {
        sign configurations.archives
    }
}

private Object signIt() {
    signing {
        sign configurations.archives
    }
}

In that directory execute the following:

gradle wrapper

gradlew tasks

You'll get a list of available tasks as a result.

Change the build.gradle file to the following

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

allprojects {
    apply plugin: 'signing'
}

subprojects {
    signIt()
}

private Object signIt() {
    signing {
        sign configurations.archives
    }
}

execute again:

gradlew tasks

Now you (or at least I) get:

> Cannot add task ':signArchives' as a task with that name already exists.
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348

1 Answers1

2

The subproject context is lost in the refactoring.

If you add a println project.name into the signing closure, you can see that you're signing each subproject once in the first variant, while the root project is signed twice in the second variant.

You can fix it by for instance passing the subproject as a parameter to the signing method:

subprojects {
    signIt(project)
}

private Object signIt(project) {
    project.with {
        signing {
            sign configurations.archives
        }
    }
}
Steinar
  • 5,860
  • 1
  • 25
  • 23
  • How does that subproject context gets passed along, in the inline version? – Jens Schauder Mar 08 '15 at 14:43
  • In this case `project` would refer to the root project instance and not the specific subproject. You'll need to use a Closure parameter. – Benjamin Muschko Mar 08 '15 at 15:02
  • Hi @BenjaminMuschko I understand that. But how does gradle pass that context along? It isnt visible any where ... – Jens Schauder Mar 08 '15 at 15:18
  • 1
    Can you elaborate? I don't quite understand the question. Which context, which method? Are you asking about the subproject instances? If yes, they are set as [delegate](http://groovy.codehaus.org/api/groovy/lang/Closure.html#setDelegate(java.lang.Object)). – Benjamin Muschko Mar 08 '15 at 15:53