Search code examples
grailsantcd

Ant build task: how to change the basedir for an ant command (e.g. how to do a "cd") with grails 2.5


The below ant snippet from a target specified in grails "Scripts" dir, creates a single file with the checksums of all classes, so they can be checked on the target servers.

The output of the ant is a file like this:

c9b1c71b31e53e99ff31b4be0a1284558aa019ec target/classes/bo/ApiRequestFilters$_closure1.class
ff936fddc1b99ba323493b131d271ca4feb0f5dd target/classes/bo/ApiRequestFilters.class
df7a12fe1182b5fc10177a2559a3a0cbb0709e29 target/classes/com/xxx/yyy/apiConstants.class

The problem is the word "target" in the file path. When the app is deployed to tomcat under webapp, there is no target.

How can this be avoided? E.g. if the ant.concat function took a basedir:"target", if if you could do ant.cd("target") or similar it would solve the issue, or if you could specify a basedir per target, but this does not seem possible?

Source:

ant.checksum(fileext:".sha1", algorithm: "SHA", forceoverwrite: "yes", pattern: "{0} {3}") {
    fileset(dir: "target/classes") {
        include(name:"**/*.class")
    }
}

ant.concat(destfile:"target/classes.sha1") {
   fileset(dir: "target/classes") {
       include(name:"**/*.sha1")
   }
}

I found one hacky way - to remove the "target/" from the sha1 file after using:

ant.replace(file:"target/classes.sha1", token:" target/", value: " ")

Is there a better way?


Solution

  • For a small optimization improvement, consider removing the replace task by nesting a filterchain under concat.

    In the following example, the replaceregex filter uses a regular expression to match lines starting with hash values followed by the string target/. If the beginning of the line matches, it is replaced with the target/ part deleted:

    ant.concat(destfile:"target/classes.sha1") {
        fileset(dir: "target/classes") {
            include(name:"**/*.sha1")
        }
        filterchain {
            tokenfilter {
                // Using the regex "pattern" to match:
                //
                // "^": from the start of each line...
                // "[0-9a-f]+": ...match as many hexadecimal characters as possible...
                // " ": ...followed by a space character...
                // "target/": ...followed by the string "target/".
                //
                // "([0-9a-f]+ )": captures the matching characters in group 1
                //
                // Then in "replace":
                // "\\1": inserts capture group 1
                //
                replaceregex(pattern: "^([0-9a-f]+ )target/", replace: "\\1")
            }
        }
    }
    

    The above example avoids the I/O penalties of having concat write a file to disk followed by the replace task re-opening the file and re-writing it.