この質問を 1 つずつ見ていきましょう。
ステップ #1: タスクを定義する
次の 2 つの方法のいずれかでタスクを定義できます。
- クラスファイルを指定して、そのクラスファイルが名前を定義するタスクを指定できます。
- タスク名を持つ jar 内のリソースファイルと、それらのタスク名が使用するクラスファイルを指すことができます。
JaCoCo の場合は、最初に次のことを行いました。
<taskdef name="jacoco-coverage"
classname="org.jacoco.ant.CoverageTask"/>
<taskdef name="jacoco-report"
classname="org.jacoco.ant.ReportTask"/>
ただし、2 番目の方法でも実行できます。
<taskdef resource="org/jacoco/ant/antlib.xml"/>
jacoco jar ファイルを開いてそのディレクトリをドリルダウンすると、antlib.xml
. そのファイルを見ると、次のように表示されます。
<antlib>
<taskdef name="coverage" classname="org.jacoco.ant.CoverageTask"/>
<taskdef name="agent" classname="org.jacoco.ant.AgentTask"/>
<taskdef name="report" classname="org.jacoco.ant.ReportTask"/>
<taskdef name="merge" classname="org.jacoco.ant.MergeTask"/>
<taskdef name="dump" classname="org.jacoco.ant.DumpTask"/>
</antlib>
そのため、jar にリソース ファイルがある場合は、すべてのタスクを 1 つの .xml で定義できます<taskdef>
。jacoco-coverage
あなたが呼んだものは単にcoverage
ここで呼び出され、あなたjacoco-report
が呼んだものはここで呼び出されることに注意してくださいreport
。
<jacoco-coverage/>
Ant タスクとして使用した場合、私は を使用します<coverage/>
。
ステップ #2: JAR ファイルはどこにありますか?
上記では、タスクを次のように定義しました。
<taskdef resource="org/jacoco/ant/antlib.xml">
Ant はクラスパスのどこかでそのパスを見つけなければなりませんが、どこでしょうか? JaCoCo jar をフォルダーに入れる$ANT_HOME/lib
と、クラスパスに自動的に含まれます。これにより、タスクの定義が非常に簡単になります。残念ながら、他の誰かがあなたの Ant スクリプトを実行したい場合、その JaCoCo jar をダウンロードして自分の$ANT_HOME/lib
フォルダーに入れなければならないことも意味します。あまり携帯できません。
幸いなことに、その JaCoCo jar が配置されている場所を指定できます。通常、プロジェクトはバージョン管理下にあるため、配置するのに最適な場所は、 がある場所のすぐ下にあるプロジェクトのディレクトリbuild.xml
です。誰かがあなたのプロジェクトと をチェックアウトするとbuild.xml
、JaCoCo.jar も取得します。
私の好みは、という名前のディレクトリを作成し、そのディレクトリ内にすべてのタスク セットごとにantlib
サブディレクトリを作成することです。antlib
この場合、 というディレクトリがありantlib/jacoco
ます。
jacoco.jar ファイルが安全に保管されたら。そのディレクトリで、<classpath>
サブエンティティを追加し<taskdef>
て、検索場所を指定できますjacoco.jar
。
クラスパスの前:
<taskdef resource="org/jacoco/ant/antlib.xml"/>
クラスパスの後:
<taskdef resource="org/jacoco/ant/antlib.xml">
<classpath>
<fileset dir="${basedir}/antlib/jacoco"/>
</classpath>
</taskdef>
を使用することに注意してください。JaCoCo jar ファイルが呼び出されているかどうか<fileset/>
は気にしません。jar の正確な名前がわかっている場合は、次のようにすることができます。jacoco.jar
jacoco-2.3.jar
<taskdef resource="org/jacoco/ant/antlib.xml">
<classpath path="${basedir}/antlib/jacoco/jacoco.jar"/>
</taskdef>
そして、数行を保存します。
ステップ #3: XML 名前空間
この時点でjacoco:
、タスク名にプレフィックスを付ける必要はありません。
私は単にこれを行うことができます:
<project name="MyApp" default="package" basedir=".">
<taskdef resource="org/jacoco/ant/antlib.xml">
<classpath path="${basedir}/antlib/jacoco/jacoco.jar"/>
</taskdef>
<target name="run-coco" depends="doOtherStuff">
<coverage>
<!-- ... -->
<coverage>
<report>
<!-- ... -->
<report>
</target>
</project>
そして、あなたはそれをそのままにしておくことができます。まったく問題ありません。シンプルでクリーン。
Foo
しかし、 という名前の Ant タスク セットとという名前の 2 つの異なる Ant タスク セットを使用Bar
していて、両方に<munge/>
タスクが定義されている場合はどうなるでしょうか。
<taskdef resource="org/foo/ant/antlib.xml">
<classpath path="${basedir}/antlib/foo.jar/>
</taskdef>
<taskdef resource="org/bar/ant/antlib.xml">
<classpath path="${basedir}/antlib/bar.jar/>
</taskdef>
<target name="munge-this">
<!-- Is this foo.jar's or bar.jar's munge task? -->
<munge vorbix="fester"/>
</target>
どのmunge
タスクが実行されていますか? にあるものですかfoo.jar
、それともにあるものbar.jar
ですか?
これを回避するために、Ant では一連のタスクごとにXML 名前空間を定義できます。このような名前空間は、最上位の<project>
エンティティ、タスク自体の内部、または名前で定義できます<target>
。99% の場合、それは<project>
エンティティで行われます。
<project name="demo" default="package" basename="."
xmlns:foo="I-will-have-fries-with-that"
xmlns:bar="Never-on-a-first-date">
<taskdef uri="I-will-have-fries-with-that"
resource="org/foo/ant/antlib.xml">
<classpath path="${basedir}/antlib/foo.jar/>
</taskdef>
<taskdef uri="Never-on-a-first-date"
resource="org/bar/ant/antlib.xml">
<classpath path="${basedir}/antlib/bar.jar/>
</taskdef>
<target name="munge-this">
<!-- Look the 'foo:' XMLNS prefix! It's foo.jar's much task! -->
<foo:munge vorbix="fester"/>
</target>
<munge/>
これで、Foo タスク リストのタスクであることがわかりました。
はxmlns
、XML 名前空間を定義します。はタスクのxmlns:foo
Foo セットの名前空間を定義し、xmlns:bar
タスクのバー セットの名前空間を定義します。のタスクを使用するときは、名前空間foo.jar
を前に付けます。foo:
このプレフィックスは の直後にあることに注意してくださいxmlns:
。
はuri
、名前空間文字列に一致する単なる文字列です。文字列I-will-have-fries-with-that
とを使用しNever-on-a-first-date
て、文字列自体は重要ではないことを示しました。重要なのは、この文字列がタスクのuri
パラメーターと一致することです。<taskdef>
このようにして、定義されているタスクは、使用すべき名前空間を認識します。
通常、URI 文字列は URI 定義です。これには 2 つの方法があります。
- ある程度標準化された
antlib:
URI を使用し、名前空間にその逆の名前を使用します: antlib:org.jacoco.ant
。
- プロジェクトを指す URL を使用します:
http://www.eclemma.org/jacoco/
。
ドキュメントを指すので、後者を好みます。ただし、前者の方が人気があるようです。
それでは、Jacoco がどのように機能するかを見てみましょう。
<project name="MyApp" default="package" basedir="."
xmlns:jacoco="antlib:org.jacoco.ant">
<taskdef uri="antlib:org.jacoco.ant"
resource="org/jacoco/ant/antlib.xml">
<classpath path="${basedir}/antlib/jacoco/jacoco.jar"/>
</taskdef>
<target name="run-coco" depends="doOtherStuff">
<jacoco:coverage>
<!-- ... -->
<jacoco:coverage>
<jacoco:report>
<!-- ... -->
<jacoco:report>
</target>
</project>
uri
JaCoCo<taskdef/>
の は文字列と同じであることに注意してくださいxmlns:jacoco
。
タスク定義については以上です。jacoco:
プレフィックスの由来と、そのクラスを含む実際のクラス名、またはタスク名とクラスの両方を指すリソースファイルを指してタスクを定義する方法を説明できれば幸いです。