ceylon/ceylon.build — pull request #46 by HenningB (2014-07-15 19:51:53+00:00)
Title: Ant wrapper - module ceylon.build.tasks.ant

This pull request contains the new module `ceylon.build.tasks.ant` with test module.

It doesn't touch anything of the existing project, except that it adds the Maven Aether repository.

Compiled with Ceylon 1.1 from 2014-07-10, which doesn't reflect FroMage's latest binary changes to the module descriptor. But this change affects `ceylon.build.runner` and not `ceylon.build.tasks.ant`.

#### From the module documentation:

# Apache Ant wrapper

Enables you to write Apache Ant scripts in Ceylon. [Apache Ant](https://ant.apache.org/) is a build/batch tool widely used by Java programmers, with which XML is commonly used as definition language.

It facilitates the use of Ant-types, Ant-tasks, and Ant-processes, including introspection, being used within Ceylon. It is not intended to imitate Ant's `target` mechanism.

## Usage

Basically it's a mapping from Ant's XML description language to Ceylon. Elements and attributes are `String`s as Ant itself has a dynamic nature.

Also it is important to distinguish between Ant types and Ant tasks. Types are data holders like `` and task are executables like ``.

Consider the following Ant snippet:

```xml

```

The above Ant snippet becomes with the value `buildDirectory` the following Ceylon code:

```ceylon
value buildDirectory = "target/build";
ant("copy", { "todir" -> "``buildDirectory``/sub-directory" }, [
Ant("fileset", { "dir" -> "``buildDirectory``" }, [
Ant("include", { "name" -> "example.txt" } )
] )
] );
```

So types like `` are built using the `Ant` class. For executing a tasks, use the `ant()` functions, which actually builds an `Ant` object and then calls `execute()` on it.

## External modules

Ant allows users to add their own types and tasks by adding them to Java's classpath. As the module system doesn't allow using classes from modules not imported directly, you need to use `AntProject::addModule()` to add a module to the class loader of `ceylon.build.tasks.ant`, so Ant can use the classes. Before actually using these types and tasks you have to initialize Ant with `` or ``.

Example:

```ceylon
AntProject antProject = activeAntProject();
antProject.addModule("org.apache.ant.ant-commons-net", "1.9.4");
ant("taskdef", { "name" -> "ftp", "classname" -> "org.apache.tools.ant.taskdefs.optional.net.FTP" } );
```

## Introspection

Ant introspection works from top down, as the implementing classes of Ant types change depending on their location in the XML hierarchy.

Example:

```ceylon
AntProject antProject = currentAntProject();
AntDefinition? copyAntDefinition = antProject.allTopLevelAntDefinitions().filter { (AntDefinition a) => (a.antName == "copy"); }.first;
assert(exists copyAntDefinition);
AntDefinition? filesetAntDefinition = copyAntDefinition.nestedAntDefinitions().filter { (AntDefinition a) => (a.antName == "fileset"); }.first;
assert(exists filesetAntDefinition);
AntDefinition? includeAntDefinition = includeAntDefinition.nestedAntDefinitions().filter { (AntDefinition a) => (a.antName == "include"); }.first;
assert(exists includeAntDefinition);
```

## Caveats

XML/Ant namespaces are not supported.