AntelopeTasksを使ってAntでtry-catchする

Antでビルドを走らせる際に,そのタスクの実装にもよるが,タスクでエラーが発生した場合そのまま処理が止まってしまうことがある.
例えば,正常時は Target1→Target2→Target3 と走らせていくが,もしTarget1でエラーが発生した場合は,Target2だけは必ず走らせて,そこで止まって欲しいような場合もあると思う.そこでAntelopeTasksを使ったAnt拡張でうまくいきそうだったので,試してみた.

普通に書くとこうなる

ここではエラーを発生させるタスクの例としてJavaScriptの静的解析を行うJSHintを使っているが,流れとしては JSHint→target2→target3 と走らせるが,JSHintでエラーが発生した場合は,target2だけはどうしても走らせて終わりたい.

<?xml version="1.0" encoding="UTF-8"?>
<project name="sample" default="target3" basedir=".">

	<taskdef name="jshint" classname="com.philmander.jshint.JsHintAntTask" classpath="${basedir}/lib/ant-jshint-0.3.4-deps.jar" />

	<target name="jshint">
		<echo>Target:jshint</echo>
		<jshint dir="${basedir}/src/js" fail="true">
			<include name="**/*.js"/>
			<report type="xml" destFile="${basedir}/result/jshint_results.xml" />
		</jshint>
	</target>
	
	<target name="target2" depends="jshint">
		<echo>Target:target2</echo>
	</target>
	
	<target name="target3" depends="target2">
		<echo>Target:target3</echo>
	</target>

</project>

実際には,JSHintでエラーが発生した場合,次のターゲットには進まず,そのままビルドが失敗してしまう.

C:\buildroot>ant
Buildfile: C:\buildroot\build.xml

jshint:
[echo] Target:jshint
[jshint] Validating files in C:\buildroot\src\js
[jshint] Could not find properties file at C:\buildroot\.jshintrc
[jshint] Using custom options:
[jshint] Using custom options:
[jshint] JSHint validation failed for C:\buildroot\src\js\sample.js
[jshint] Missing "use strict" statement. (line: 2, character: 5)
[jshint] > alert("hoge");
[jshint] 'alert' is not defined. (line: 2, character: 5)
[jshint] > alert("hoge");
[jshint] Writing report to C:\buildroot\result\jshint_results.xml

BUILD FAILED
C:\buildroot\build.xml:8: JSHint found 2 errors.

Total time: 0 seconds

AntelopeTasksを使って書くとこうなる

AntelopeTasksを使うと,Antでtryタスクとcatchタスクを使えるようになるので,JSHintタスクをtryタスクにネストさせて,さらにcatchタスクもネストさせてプロパティを設定する.こうすることでビルドは継続するので,target2を走らせて,そこでfailさせることができる.ちなみにその後続のtarget3でunlessを書いているが,正確にはこれはなくても問題なく,単なる明示の意味である.AntelopeTasksはここから Antelope 3.5.1 Tasks をダウンロードした.

<?xml version="1.0" encoding="UTF-8"?>
<project name="sample" default="target3" basedir=".">

	<taskdef name="jshint" classname="com.philmander.jshint.JsHintAntTask" classpath="${basedir}/lib/ant-jshint-0.3.4-deps.jar" />
	<taskdef name="try" classname="ise.antelope.tasks.TryTask" classpath="${basedir}/lib/AntelopeTasks_3.5.1.jar" />

	<target name="jshint">
		<echo>Target:jshint</echo>
		<try>
			<jshint dir="${basedir}/src/js" fail="true">
				<include name="**/*.js"/>
				<report type="xml" destFile="${basedir}/result/jshint_results.xml" />
			</jshint>
			<catch>
				<echo>Set property.</echo>
				<property name="continue.error" value="true" />
			</catch>
		</try>
	</target>
	
	<target name="target2" depends="jshint">
		<echo>Target:target2</echo>
		<fail message="Error detected." if="continue.error" />
	</target>
	
	<target name="target3" depends="target2" unless="continue.error">
		<echo>Target:target3</echo>
	</target>

</project>

C:\buildroot>ant
Buildfile: C:\buildroot\build.xml

jshint:
[echo] Target:jshint
[jshint] Validating files in C:\buildroot\src\js
[jshint] Could not find properties file at C:\buildroot\.jshintrc
[jshint] Using custom options:
[jshint] Using custom options:
[jshint] JSHint validation failed for C:\buildroot\src\js\sample.js
[jshint] Missing "use strict" statement. (line: 2, character: 5)
[jshint] > alert("hoge");
[jshint] 'alert' is not defined. (line: 2, character: 5)
[jshint] > alert("hoge");
[jshint] Writing report to C:\buildroot\result\jshint_results.xml
[try] Task 'jshint' in target 'jshint' failed, error message is: JSHint found 2 errors.
[echo] Set property.

target2:
[echo] Target:target2

BUILD FAILED
C:\buildroot\build.xml:23: Error detected.

Total time: 1 second