Appendix A
Potential Traps

A.1 Groovy Script Variables

For Gradle users it is important to understand how Groovy deals with script variables. Groovy has to type of script variables. One with a local scope and one with a script wide scope.

  String localScope1 = 'localScope1'
  def localScope2 = 'localScope2'
  scriptScope = 'scriptScope'
  
  println localScope1
  println localScope2
  println scriptScope
  
  closure = {
      println localScope1
      println localScope2
      println scriptScope
  }
  
  def method() {
      try {localScope1} catch(MissingPropertyException e) {println 'localScope1NotAvailable' }
      try {localScope2} catch(MissingPropertyException e) {println 'localScope2NotAvailable' }
      println scriptScope
  }
  
  closure.call()
  method()

  >groovy scope.groovy
  localScope1
  localScope2
  scriptScope
  localScope1
  localScope2
  scriptScope
  localScope1NotAvailable
  localScope2NotAvailable
  scriptScope

Variables which are declared with a type modifier are visible within closures but not visible within methods. This is a heavily discussed behavior in the Groovy community.1

A.2 Configuration and Execution Phase

It is important to keep in mind that Gradle has a distinct configuration and execution phase (see chapter 13).

  classesDir = new File('build/classes')
  classesDir.mkdirs()
  createTask('clean') {
      ant.delete(dir: 'build')
  }
  createTask('compile', dependsOn: 'clean') {
      if (!classesDir.isDirectory()) {
          println 'The class directory does not exists. I can not operate'
          // do something
      }
      // do something
  }

  >gradle -q -bmkdirTrap.gradle compile
  The class directory does not exists. I can not operate

As the creation of the directory happens during the configuration phase, the clean task removes the directory during the execution phase.