liquibase/liquibase — pull request #275 by mattbertolini (2014-05-29 01:58:58+00:00)
Title: Ant Tasks Refactoring

I've spent the past few weeks refactoring the Liquibase Ant tasks to make them much more "Ant-like". This pull request represents the summation of that work. Please let me know if you have any questions or would like any changes made. Also, if you feel that this is not needed, no worries. It was still a fun project and I enjoyed working on it. :)

## Changes

### Dependency Upgrades

The existing Ant tasks depend on Ant version 1.6.5 (circa 2005). I have done a modest bump to version 1.7.1 (circa 2008). Ant 1.7 introduced many new features like the resource objects and antlib/namespace support which I make extensive use of in these updates.

### Antlib Definition

I have updated the way you load the ant tasks using the antlib feature inside of Ant 1.7+. Instead of a properties file, you will now load an `antlib.xml` file which will load all of the task and datatypes. This also allows you to namespace the tasks to avoid naming conflicts.

```xml

```

### General Cleanup

I examined all of the attributes in each task and determined which were common to all tasks and which were for only certain tasks. I removed any attribute from the base class that was not required for all tasks and created a small hierarchy for the different types of tasks. The class hierarchy now looks like this:

```
BaseLiquibaseTask
|- TagDatabaseTask
|- DropAllTask
|- DBDocTask
|- GenerateChangeLogTask
|- AbstractChangeLogBasedTask
| |- DatabaseUpdateTask
| |- MarkNextChangeSetRanTask
| |- DatabaseRollbackFutureTask
| |- ChangeLogSyncTask
| |- DatabaseRollbackTask
| |- DatabaseUpdateTestingRollbackTask
|- AbstractDatabaseDiffTask
| |- DiffDatabaseTask
| |- DiffDatabaseToChangeLogTask
```

I have also made the `` element and `classpathref` attribute optional as it should not be required if users have chosen to directly include their libraries on Ant's classpath.

### Data Types

The first thing I noticed when examining the tasks was that every task needed to define the database settings. This resulted in a lot of repetition if you used more than one task for the same database.

To resolve this I created two custom Ant data types: `` and ``. These types can be defined outside of tasks and referenced many times. They can also be nested inside the tasks if you want to keep everything in one place.

```xml

```

Here is an example of the `` type:

```xml

```

Usage of the new data types is by the two new "ref" attributes on the tasks:

```xml

```

The `` type is also used in the diff database tasks. Instead of providing two sets of attributes (for main and reference database) now you provide a `` element or `referenceDatabaseRef` attribute.

```xml

```

#### JDBC Connection Properties

The `` type also adds a new nested element `` that allows users the ability to pass in custom JDBC connection properties to the Liquibase database connection.

```xml

```

### Output Changelogs to Different Formats

The `GenerateChangeLogTask` and `DiffDatabaseToChangeLogTask` output a change log file. In the old tasks, the only output format that could be made was a XML change log. I have added the ability to output XML, JSON, YAML, and plain text. You can also output multiple formats in one task:

```xml

```

### Logging

I've replaced the `LogRedirector` class with a new `AntTaskLogger` which interacts with the Liquibase logging system directly rather than redirecting through `java.util.logging`. This routes log messages through Ant so custom Ant output loggers can capture the output.

### Testing

I've added a lot of unit/integration tests to make sure the ant task functionality remains correct to reduce the chance of a regression in the future. To facilitate this I added a small testing harness with some custom Ant conditions to test the presence of database tables and columns.

The tests use the [AntUnit] (http://ant.apache.org/antlibs/antunit/) library for creating unit/integration tests for the tasks using Ant itself. You can view the AntUnit tests in the `src/main/resources/liquibase/integration/ant` folder. The integration tests are also a good source of examples for how the new tasks work inside a build file.

## Backward Compatibility

I did my best to make sure the tasks were completely backward compatible to the end-user. Users using the legacy versions of the tasks will start to see warning log messages telling them their current usage of the task is deprecated and to update their build files.

Here is a typical update task definition in the legacy style:

```xml

```

This is what the same task looks like migrated to the new style:

```xml

```

### Potential Breaking Changes

* As mentioned earlier, the tasks now require Ant 1.7.1 or higher. While the attributes and elements remain backward compatible, the Java code behind them now uses classes specific to the newer version of Ant. Most users of the task should notice no difference.
* Setting a log level from the ant task will no longer work. It is advised that users use the built in Ant logging flags `-debug`, `-verbose`, or `-quiet`.
* Anyone with thrid-party tasks that extend from `BaseLiquibaseTask` might have issues with their implementation. It is advised that users examine the deprecations in the Javadoc and make the appropriate changes.

Please let me know if you see any area where I may have broken backward compatibility and I will do my best to fix it.

### Deprecation Policy

I'm not sure what your deprecation policy is but I would recommend keeping the deprecated attributes around for a few versions so people have a chance to migrate their tasks over to the new format. Liquibase 3.5 would seem like a good time to remove them.

## TODOs

There are a few things that are not in this pull request that I would still like to accomplish:

* Output to formatted SQL. For some reason the `FormattedSqlChangeLogSerializer` requires a change log file when the other serializers do not. For that reason I had to remove it as an output format.
* Shorten the names of the ant tasks. `` could really be shortened to ``. This can be done while preserving backward compatibility but I felt it was out of scope for this patch.
* More unit tests. While there are over 70 tests currently, I have not finished covering all of the tasks.
* Because I have added integration tests to the ant tasks, it might be prudent to split them out into their own module. (e.g. liquibase-ant)

## Resolved Issues

With this pull request, I consider the following issues to be resolved:

* [CORE-597 - dbDoc does not appear to be working in 2.0.rc1] (http://liquibase.jira.com/browse/CORE-597)
* [CORE-776 - Using ant tasks when called from another ant] (http://liquibase.jira.com/browse/CORE-776)
* [CORE-1894 - [ant] NPE when classpathref not given] (http://liquibase.jira.com/browse/CORE-1894)
* [CORE-1895 - [ant] NPE when changeLogFile not given in markNextChangeSetRan] (http://liquibase.jira.com/browse/CORE-1895)

## Documentation

I will be submitting a pull request with documentation updates to the [liquibase.github.com] (https://github.com/liquibase/liquibase.github.com) repository shortly.