Scriptdef 可用于使用脚本语言定义 Apache Ant 任务。由 Apache BSF 或 JSR 223 支持的 Ant 脚本语言可用于定义脚本。Scriptdef 提供了一种机制,可以将构建中的控制逻辑封装在 Ant 任务中,从而最大限度地减少在 Ant 本身中提供控制样式任务的需要。可以提供复杂的逻辑,同时保留 Ant 构建文件的简单结构。Scriptdef 也适用于为新的自定义任务创建原型。当然,随着脚本复杂度的增加,最好将任务定义迁移到基于 Java 的自定义任务中。
注意:此任务依赖于 Ant 发行版中未包含的外部库。有关更多信息,请参阅 库依赖项。
可以使用 <attribute> 和 <element> 嵌套元素定义任务支持的属性和嵌套元素。这些元素可用于实现任务的脚本,作为两个集合样式脚本变量 和 attributes。elements 集合中的元素可以通过属性名称访问。attributes 集合可以通过嵌套元素名称访问。这将返回嵌套元素的所有实例的列表。此列表中的实例可以通过整数索引访问。elements
注意:Ant 将所有属性和元素名称转换为小写名称,因此即使您使用 name=SomeAttribute
,您也必须使用 someattribute
从 集合中检索属性的值。attributes
名称 (自 Ant 1.6.3 起)是 selfscriptdef 任务实例的预定义引用。它可用于记录或与 Ant 的其余部分集成。 属性包含传递给脚本的任何嵌套文本self.text
如果未传入属性或元素,则 或 attributes.get() 将返回 null。由脚本执行任何检查和验证。elements.get() 可用于引发 self.fail(String message)BuildException。
名称 是 Ant 项目的预定义引用。有关编写脚本的更多信息,请参阅 project<script> 任务。
| 属性 | 描述 | 必需 |
|---|---|---|
| name | 使用脚本创建的任务的名称 | 是 |
| language | 脚本编写的编程语言。必须是受支持的 Apache BSF 或 JSR 223 语言 | 是 |
| manager | 要使用的脚本引擎管理器。有关使用此属性的信息,请参阅 script 任务。 | 否;默认值为 auto |
| src | 脚本作为文件的位置(如果不在内联中) | 否 |
| encoding | 脚本作为文件的编码。自 Ant 1.10.2 起。 | 否;默认为默认 JVM 字符编码 |
| compiled | 如果为 true,则在第一次评估之前编译脚本,以便更快地执行多次,前提是 manager 为 javax且目标引擎实现了 javax.script.Compilable。请注意,bsf管理器可能会自动编译脚本。自 Ant 1.10.2 起。 |
否;默认为 false |
| uri | 此定义应驻留的 XML 命名空间 URI。 | 否 |
| classpath | 传递到脚本的类路径。 | 否 |
| classpathref | 要使用的类路径,作为对在其他地方定义的路径的 引用 给出。 | 否 |
| loaderRef | 用于加载脚本的加载器的名称,由指定的类路径构建。这允许多个脚本定义重用相同的类加载器。 | 否 |
| setbeans | 此属性控制是否为运行脚本中的所有属性、引用和目标设置变量。如果此属性为 false,则仅设置 project 和 self 变量。如果此属性为 true,则设置所有变量。自 Ant 1.10.13 起 |
否;默认值为 false,以保持向后兼容性 |
| 属性 | 描述 | 必需 |
|---|---|---|
| name | 属性的名称 | 是 |
| default | 属性的默认值 自 Ant 1.10.13 起 | 否 |
| 属性 | 描述 | 必需 |
|---|---|---|
| name | 由脚本定义的任务支持的嵌套元素的名称 | 是 |
| classname | 要用于嵌套元素的类的类名。这直接指定类,是指定 Ant 类型名称的替代方法。 | 否 |
| type | 这是创建此元素时要使用的 Ant 任务或类型的名称。这是直接指定类名的替代方法。如果类型位于命名空间中,则 URI 和 :必须作为前缀添加到类型。例如 type= antlib:example.org:newtype |
否 |
有关使用此嵌套元素的信息,请参阅 script 任务。
自 Ant 1.7.1 起
此任务可以从作为嵌套元素提供的任何资源加载脚本。
以下定义创建了一个任务,该任务支持名为 attr 的属性和两个嵌套元素,一个是 fileset,另一个是 path。执行时,生成的 task 将记录属性的值和第一个 fileset 的 basedir。
<scriptdef name="scripttest" language="javascript">
<attribute name="attr1"/>
<element name="fileset" type="fileset"/>
<element name="path" type="path"/>
<![CDATA[
self.log("Hello from script");
self.log("Attribute attr1 = " + attributes.get("attr1"));
self.log("First fileset basedir = "
+ elements.get("fileset").get(0).getDir(project));
]]>
</scriptdef>
<scripttest attr1="test">
<path>
<pathelement location="src"/>
</path>
<fileset dir="src"/>
<fileset dir="main"/>
</scripttest>
以下对上述脚本的变体列出了 fileset 元素的数量并遍历它们
<scriptdef name="scripttest2" language="javascript">
<element name="fileset" type="fileset"/>
<![CDATA[
filesets = elements.get("fileset");
self.log("Number of filesets = " + filesets.size());
for (i = 0; i < filesets.size(); ++i) {
self.log("fileset " + i + " basedir = "
+ filesets.get(i).getDir(project));
}
]]>
</scriptdef>
<scripttest2>
<fileset dir="src"/>
<fileset dir="main"/>
</scripttest2>
当脚本存在语法错误时,scriptdef 名称将列在错误中。例如,在上面的脚本中,删除右大括号会导致以下错误
build.xml:15: SyntaxError: missing } in compound statement (scriptdef <scripttest2>; line 10)
脚本错误仅在实际执行 script 任务时才会检测到。
下一个示例在 Jython 中使用嵌套文本。它还在新的 xml 命名空间中声明脚本,必须使用该命名空间来引用任务。在新的命名空间中声明脚本可确保 Ant 不会创建具有相同(命名空间、本地名称)名称对的任务。
<target name="echo-task-jython">
<scriptdef language="jython"
name="echo"
uri="https://example.org/script">
<![CDATA[
self.log("text: " +self.text)
]]>
</scriptdef>
</target>
<target name="testEcho" depends="echo-task-jython"
xmlns:s="https://example.org/script">
<s:echo>nested text</s:echo>
</target>
下一个示例展示了 <classpath> 和 loaderref 的使用,以访问 beanshell jar。
<scriptdef name="b1" language="beanshell"
loaderref="beanshell-ref">
<attribute name="a"/>
<classpath path="${user.home}/scripting/beanshell/bsh-1.3b1.jar"/>
self.log("attribute a is " + attributes.get("a"));
</scriptdef>
<scriptdef name="b2" language="beanshell"
loaderref="beanshell-ref">
<attribute name="a2"/>
self.log("attribute a2 is " + attributes.get("a2"));
</scriptdef>
<b1 a="this is an 'a'"/>
<b2 a2="this is an 'a2' for b2"/>
测试脚本最简单的方法是使用 AntUnit Ant 库。这将运行脚本中以 test
开头的所有目标(及其依赖项)。