gradleprojectsubproject

Gradle project, sub projects executed repeatedly


I have a project with sub projects. The layout:

rootproj
--subproj1
----mybuild.number
--subproj2
--build.gradle
--gradle.properties
--settings.gradle

mybuild.number

#Build Number for ANT. Do not edit!
#Wed Nov 210 2121:210:2121 PST 2102121
build.number=1

settings.gradle

include ('subproj1', 'subproj2')

build.gradle

allprojects {

    repositories {
        mavenLocal()
        maven {url "http://repo1.maven.org/maven2"}
    }


}

subprojects {

    project (':subproj1')   { 

        def oldN = new File("D:/rootproj/subproj1/mybuild.number").text.split("=")[1]
        def newN = (oldN.toInteger() + 1).toString()
        ant.replace(
            file: "mybuild.number",
            token: "${oldN}",
            value: "${newN}"
        )
        println "From subproj1 : ${newN}"
        task hello(overwrite: true){
            doLast{
                println "hello from subproject 1"
            }
        }

    }
    project (':subproj2'){

        println "the build Dir: $buildDir"
        task hello(overwrite: true){
            doLast{
                println "hello from subproject 2"
            }
        }

    }
}

when I run

gradle -q subproj1:hello

or

gradle -q subproj2:hello

or

gradle

from the rootproj, I always get e.g.

....
From subproj1 : 24
the build Dir: D:\rootproj\subproj2\build
From subproj1 : 25
the build Dir: D:\rootproj\subproj2\build

1. Why the two sub projects always get executed twice, therefore the build number is incremented twice, instead of once?
2. why all sub projects get executed even though I explicitly specified the project:task in the command line?
I have searched the Internet, could not find useful information.
Thanks for your help in advance.

EDIT: Change build.gradle as @JB Nizet suggested:

  1. move the ant.replace to task incr
  2. comment out subprojects

It works exactly as I expected.

    allprojects {
    repositories {
        mavenLocal()
        maven {url "http://repo1.maven.org/maven2"}
    }
}

//subprojects {
    def oldN = new File("E:/hqin/build/gradle/rootproj/subproj1/mybuild.number").text.split("=")[1]
    def newN = (oldN.toInteger() + 1).toString()
    project (':subproj1')   { 

        task incr {
            doLast{

                ant.replace(
                    file: "mybuild.number",
                    token: "${oldN}",
                    value: "${newN}"
                )
            }
            println "From subproj1 : ${newN}"
        }
        task hello(overwrite: true, dependsOn: 'incr'){
            doLast{
                println "hello from subproject 1"
            }
        }

    }
    project (':subproj2'){


        task hello(overwrite: true){
            doLast{
                println "the build Dir: $buildDir"
                println "hello from subproject 2"
            }
        }

    }
//}

Solution

  • Regarding the second point: because your code is run as part of the project configuration, which is always run, whatever the task being executed. If you want code being executed when a task is executed, then it should be inside the doLast closure of a task definition:

    task someTask {
      doLast {
        ...
      }
    }
    

    Regarding the first point: the closure passed to subprojects is executed for every subproject. So, it's called once for the subproject 1, and configures subproject 1 and subproject 2, then it's called again for subproject 2, and reconfigures subproject 1 and subproject 2 again. You shouldn't have subprojects at all.