The Ant Hook scripts using Groovy implementation is extended with the ability to also skip target execution. Thus, an “around” advice AOP like or filter.
In the last post, Ant Hooks using Groovy Script via Scriptdef, we used the Ant BuildListener interface to add a hooks feature that invokes a Groovy script mapped to build events. Now we implement a true “around advice”. Admittingly kludgy, but ….
Approach
Since the hook script has the Ant Event object, we have access to the Target object currently about to be executed. Target has a convenient method to allow target skip:
public void setUnless(java.lang.String property): Sets the "unless" condition to test on execution. if the property is set, the task will not execute.
Demo
The demo Ant build script is modified with two new targets, ‘deploy’ and ‘build’. Also, the default target is changed to ‘build’.
<project name="demo1" default="build" basedir="."> ............ see original code ..... <target name="compile"> <echo>Hello compile world!</echo> </target> <target name="deploy"> <echo>Deploying ... ${skipSet}</echo> </target> <target name="build" depends="compile,deploy"> <echo>Building ... </echo> </target> </project>
A new hook script to filter the ‘deploy’ target and skip it is added.
demo1/deploy_targetStarted.groovy
println " hook: {project=${event.project.name},target=${event.target.name},when=pre,event=$event}" hook.skipTarget(event)
Listener implementation
The actual listener is slightly modified to test for the skip property. If found the ‘unLess’ method is used on the target and the target is skipped.
/** * Ant build listener that invokes groovy hook scripts. * * @author josef betancourt * */ class HookListener implements SubBuildListener { ...... see prior post ...... /** Invoke the 'started' or 'finished' root or target hook script */ def evokeTargetHook(BuildEvent event, When when){ def b = new Binding() b.event=event b.hook=this def shell = new GroovyShell(b) def hookName = "${event.target.name}_${TARGETHOOK}${when.name}" def hooked = false def stored = projectHooks[hookName] if(stored){ hooked = true shell.evaluate(stored) }else{ def hook = rootHooks[hookName] if(hook){ hooked = true shell.evaluate(hook) } } if( hooked && (when == When.STARTED) ){ def skipSet = event.project.getProperty( "${event.target.name}_skipTarget") if(skipSet){ event.project.setProperty(skipSet, "true") event.target.setUnless(skipSet) } } } /** invoked from a hook script */ static void skipTarget(BuildEvent event) { def name = event.target.name def project = event.project project.setProperty(name + "_skipTarget", 'set') } ...... see prior post ...... } ...... see prior post ......
Output
Buildfile: C:\Users\jbetancourt\workspace-4.3\AntAroundAdvice\build.xml compile: hook: {project=demo1,target=compile,when=pre,event=org.apache.tools.ant.BuildEvent} [echo] Hello compile world! hook: root,{target=compile,when=post,event=org.apache.tools.ant.BuildEvent} deploy: hook: {project=demo1,target=deploy,when=pre,event=org.apache.tools.ant.BuildEvent} build: [echo] Building ... BUILD SUCCESSFUL
Further reading
- ABuilds use of Ant hooks So far, the only Ant hook mention I’ve located
- Groovy Goodness: Using Groovy for Git Hooks
2 thoughts on “Ant hooks using Groovy, continued”