"distZip" is executed before "clean" or "build"


(Alex Sko) #1

I have a multi-module project:

common/build.gradle
launcher/build.gradle
productmodel/build.gradle
build.gradle
settings.gradle

here’s my settings.gradle file:

include "common", "launcher", "productmodel"

root-level build.gradle file:

subprojects {
      apply plugin: 'java'
      sourceCompatibility = 1.7
      repositories {
        maven {
            url "http://nexus:8081/nexus/content/groups/public"
        }
    }
      dependencies {
        testCompile 'junit:junit:4.11'
    }
}

launcher’s purpose is to pack the application into a runnable distributive with a WAR file produced by “productmodel” module and some other files.

I added “distZip” definition to launcher/build.gradle to download some Docs (zip), create a new WAR File basing on the original one with the docs included:

apply plugin:'application'
...
    dependencies {
    def jetty_version = "8.1.4.v20120524"
      compile
(
        ["org.eclipse.jetty:jetty-server:$jetty_version"],
        ["org.eclipse.jetty:jetty-webapp:$jetty_version"]
    )
}
  startScripts {
  // solution from http://forums.gradle.org/gradle/topics/specifying_memory_settings_in_application_plugin_start_scripts
  ext.jvmOpts = "-Xmx512m"
  inputs.property("jvmOpts", { ext.jvmOpts }) // for incremental build to work properly
    doLast {
    def optsEnvVar = "DEFAULT_JVM_OPTS"
    unixScript.text = unixScript.text.replace("$optsEnvVar=${'""'}", "$optsEnvVar=${'"'}$ext.jvmOpts${'"'}")
    windowsScript.text = windowsScript.text.replace("set $optsEnvVar=", "set $optsEnvVar=$ext.jvmOpts")
  }
}
  distZip {
      downloadDocZip()
    unpackDocZip()
    includeDocFilesIntoWARFile()
      distZip.baseName = PD_NAME
      def nowCal = Calendar.instance
    def y = nowCal.get(Calendar.YEAR)
    Date nowDate = nowCal.time
    def m = nowDate[Calendar.MONTH] + 1
    def d = nowDate[Calendar.DATE]
    def timeStamp = "$y-$m-$d"
    distZip.classifier = timeStamp
      def name_plus_classifier = "$PD_NAME-$timeStamp"
      into("$name_plus_classifier/war") {
        from '.'
        include MODIFIED_WAR_FILE
    }
      // copy README.txt to the root of the ZIP folder
    into("$name_plus_classifier") {
        from '.'
        include 'README.txt'
    }
}
  def downloadDocZip() {
    ant.get(src:DOC_ZIP_URL, dest: DOC_ZIP_DOWNLOAD_LOCATION, verbose:true, usetimestamp:true)
}
  def unpackDocZip() {
    ant.unzip(src: DOC_ZIP_DOWNLOAD_LOCATION, dest: DOC_TMP_FOLDER)
  }
  def includeDocFilesIntoWARFile() {
    ant.zip(update: 'true',
            destfile: MODIFIED_WAR_FILE) {
        fileset(dir: DOC_TMP_FOLDER)
        zipfileset(src: "../productmodel/build/libs/$WAR_FILE_NAME")
    }
}

I try running “gradle clean build distZip” in the project root folder. I tried Gradle 1.5 and 1.6 on Windows 64bit, JDK 7 u21.

the problem is that the code in “distZip” is executed before anything else, so that there’s no WAR file yet, no “build” folder, etc, etc. even if I just run “gradle clean” in the root folder, it still runs the code in “distZip”. I’m guessing this is because the code in my “distZip” section means it’s some configuration stuff, which is evaluated on Gradle project open.

so then how do I change the code to only execute certain operations during the dstributive building - download the doc.zip, unpack it, include the contents into the WAR file produced by “producemodel” module and then pack all that into the final ZIP file?


(Peter Niederwieser) #2

It’s a problem with your task declaration. All code that implements the task’s behavior (rather than configuring the task) needs to go into ‘doFirst { … }’ or ‘doLast { … }’. These methods add a task action to the task’s list of actions (at the front and end, respectively). In your case you probably want ‘doFirst’, since you want the code to run (just) before the main action of the ‘distZip’ task.

You can read more about these concepts in the Gradle User Guide.


(Alex Sko) #3

awesome. thank you! moving the distZip code into doFirst {…} helped:

distZip {
      doFirst {
      downloadDocZip()
      unpackDocZip()
      includeDocFilesIntoWARFile()
          distZip.baseName = PD_NAME
        def nowCal = Calendar.instance
      def y = nowCal.get(Calendar.YEAR)
      Date nowDate = nowCal.time
      def m = nowDate[Calendar.MONTH] + 1
      def d = nowDate[Calendar.DATE]
      def timeStamp = "$y-$m-$d"
      distZip.classifier = timeStamp
        def name_plus_classifier = "$PD_NAME-$timeStamp"
        into("$name_plus_classifier/war") {
        from 'build'
        include WAR_FILE_NAME
      }
        // copy README.txt to the root of the ZIP folder
      into("$name_plus_classifier") {
        from '.'
        include 'README.txt'
      }
    }
}

(Peter Niederwieser) #4

You should only move the first three lines into ‘doFirst’. Everything else is configuration. (This distinction is very important for understanding Gradle.)


(Alex Sko) #5

thank you! you know what’s great about Gradle? that I was able to convert our Maven build to Gradle without even knowing these details :slight_smile: