|
1 |
| -# baton |
2 |
| -A Maven plugin that helps generically provide lightweight, convention-driven migration capabilities to make it easier to evolve your projects over time. |
| 1 | +# Baton |
| 2 | +[](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.technologybrewery.baton%22%20AND%20a%3A%22baton%22) |
| 3 | +[](https://opensource.org/licenses/mit) |
| 4 | +[](https://github.com/TechnologyBrewery/baton/actions/workflows/maven.yaml) |
| 5 | + |
| 6 | +Baton pays homage to [Burton Baton](https://dogfishalehouse.com/beers/burton-baton/), a fabulous beer that is a blend of |
| 7 | +a traditional English-style Old Ale and a modern imperial IPA. This "two thread" beer brings both source beers together |
| 8 | +into something arguably better than either beer was individually. Like the beer, this project blends your |
| 9 | +existing codebase with new migrations that helps modernize and keep your old code relevant. The result is |
| 10 | +more substantive and satisfying than either old or new code alone could accomplish. |
| 11 | + |
| 12 | +## Why Do You Need Baton? |
| 13 | +Baton is a Maven plugin that helps generically provide lightweight, convention-driven migration capabilities to make it |
| 14 | +easier to evolve your projects over time. It makes it easy to embed automated migrations into your Maven build. |
| 15 | +Additionally, by using classpath-driven configurations, version upgrades of your migration jars control what gets applied |
| 16 | +when. This makes it easy to release a set of artifacts that correspond to a general release of a framework and get just |
| 17 | +the migration you need at the appropriate time. |
| 18 | + |
| 19 | +## Requirements |
| 20 | + |
| 21 | +In order to use Baton, the following prerequisites must be installed: |
| 22 | + |
| 23 | +* Maven 3.9+ |
| 24 | +* Java 11+ |
| 25 | + |
| 26 | +## Usage |
| 27 | +Creating and applying migrations is easy. Follow these steps and you'll be migrating your code in no time. |
| 28 | + |
| 29 | +### Create migration class |
| 30 | +To start, implement your migration by extending AbstractMigration, adding your specific logic to: |
| 31 | +1. Determine if the migration applies to a given file |
| 32 | +2. If applicable, perform the migration |
| 33 | + |
| 34 | +These steps are outlined below is a simple class that migrates files ending in `.foo` to now end in `.bar`: |
| 35 | +```java |
| 36 | +public class FooToBarMigration extends AbstractMigration { |
| 37 | + |
| 38 | + @Override |
| 39 | + protected boolean shouldExecuteOnFile(File file) { |
| 40 | + return file.getName().contains(".foo"); |
| 41 | + } |
| 42 | + |
| 43 | + @Override |
| 44 | + protected boolean performMigration(File file) { |
| 45 | + FileUtils.moveFile(file, new File(file.getParent(), file.getName().replace(".foo", ".bar"))); |
| 46 | + return true; |
| 47 | + } |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +### Configure Baton to use the migration |
| 52 | +With a migration to apply, we both configure and tailor that use through a simple json file. This file can live anywhere |
| 53 | +in Baton's classpath and is named `migrations.json` by default. |
| 54 | + |
| 55 | +The following example configures the migration to only look in the `./src/main/resources/legacy` folder while leaving |
| 56 | +one file, `original-specification-example.foo` alone. |
| 57 | +```json |
| 58 | +[ |
| 59 | + { |
| 60 | + "name": "upgrade-foo-extension-files-migration", |
| 61 | + "implementation": "org.technologybrewery.baton.example.FooToBarMigration", |
| 62 | + "fileSets": [ |
| 63 | + { |
| 64 | + "includes": ["**/legacy/*.foo"], |
| 65 | + "excludes": ["original-specification-example.foo"] |
| 66 | + } |
| 67 | + ] |
| 68 | + } |
| 69 | +] |
| 70 | +``` |
| 71 | + |
| 72 | +### Add `baton-maven-plugin` to your Maven build |
| 73 | +The last step is to add `baton-maven-plugin` to your Maven build process just like any other plugin. |
| 74 | + |
| 75 | +The following example highlight the default plugin configuration as well as a notional dependency containing both the |
| 76 | +Migration class and configuration json file above. |
| 77 | + |
| 78 | +```xml |
| 79 | + <plugin> |
| 80 | + <groupId>org.technologybrewery.baton</groupId> |
| 81 | + <artifactId>baton-maven-plugin</artifactId> |
| 82 | + <version>0.1.0</version> |
| 83 | + <extensions>true</extensions> |
| 84 | + <executions> |
| 85 | + <execution> |
| 86 | + <id>default</id> |
| 87 | + <goals> |
| 88 | + <goal>baton-migrate</goal> |
| 89 | + </goals> |
| 90 | + </execution> |
| 91 | + </executions> |
| 92 | + <dependencies> |
| 93 | + <dependency> |
| 94 | + <groupId>org.technologybrewery.baton.example</groupId> |
| 95 | + <artifactId>example-migration-configuration</artifactId> |
| 96 | + <version>1.0.0</version> |
| 97 | + </dependency> |
| 98 | + </dependencies> |
| 99 | + </plugin> |
| 100 | +``` |
| 101 | + |
| 102 | +### Example result output |
| 103 | +When executing your next Maven build, Baton will execute as part of the `initialize` build lifecycle and output similar |
| 104 | +to the following will result: |
| 105 | + |
| 106 | +```bash |
| 107 | +[INFO] --- baton:0.1.0:baton-migrate (default) @ toml-file-update --- |
| 108 | +[INFO] Loading migrations from: jar:file:/Users/dfh/.m2/repository/org/technologybrewery/baton/example/example-migration-configuration/1.0.0/example-migration-configuration-1.0.0-SNAPSHOT.jar!/migrations.json |
| 109 | +[INFO] Found 1 migrations |
| 110 | +[INFO] Migrations Processed: 1, Successfully Migrated Files: 1, Unsuccessfully Migrated Files: 0 |
| 111 | +``` |
| 112 | + |
| 113 | +## Plugin Configuration |
| 114 | +All Baton configurations may be set either via the `baton-maven-plugin`'s `<configuration>` definition, Maven POM |
| 115 | +properties, or `-D` on the command line and follow a consistent naming pattern for the different configuration |
| 116 | +approaches. For setting configurations via POM properties or `-D` on the command line, all configuration keys may be |
| 117 | +prepended with `baton.`. For example, `migrationsConfigurationFile` controls the file name that Baton will use to find |
| 118 | +migrations and may be configured using the following approaches: |
| 119 | + |
| 120 | +1. Plugin `<configuration>` |
| 121 | + |
| 122 | +```xml |
| 123 | + <plugin> |
| 124 | + <groupId>org.technologybrewery.baton</groupId> |
| 125 | + <artifactId>baton-maven-plugin</artifactId> |
| 126 | + <extensions>true</extensions> |
| 127 | + <configuration> |
| 128 | + <migrationsConfigurationFile>alternative-migrations.json</migrationsConfigurationFile> |
| 129 | + </configuration> |
| 130 | + </plugin> |
| 131 | +``` |
| 132 | + |
| 133 | +2. `-D` via command line |
| 134 | + |
| 135 | +```shell |
| 136 | +mvn clean install -DmigrationsConfigurationFile=alternative-migrations.json |
| 137 | +``` |
| 138 | + |
| 139 | +3. POM properties |
| 140 | + |
| 141 | +```xml |
| 142 | + <properties> |
| 143 | + <migrationsConfigurationFile>alternative-migrations.json</migrationsConfigurationFile> |
| 144 | + </properties> |
| 145 | +``` |
| 146 | + |
| 147 | +**NOTE:** The above list's order reflects the precedence in which configurations will be applied. For example, |
| 148 | +configuration values that are specified in the plugin's `<configuration>` definition will always take precedence, while |
| 149 | +system properties via the command line (`-D`) will take precedence over `<properties>` definitions. |
| 150 | + |
| 151 | +### baseDirectory |
| 152 | +The desired base directory to use when Baton looks for files on which to perform migrations. By default, only `pom.xml` |
| 153 | +and `*.toml` from the base directory will be included. |
| 154 | + |
| 155 | +Default: `${project.basedir}` |
| 156 | + |
| 157 | +### sourceDirectory |
| 158 | +The desired source directory to include when Baton looks for files on which to perform migrations. |
| 159 | + |
| 160 | +Default: `${project.basedir}/src` |
| 161 | + |
| 162 | +### testDirectory |
| 163 | +The desired test directory to include, if desired, when Baton looks for files on which to perform migrations. |
| 164 | + |
| 165 | +Default: None |
| 166 | + |
| 167 | +### fileSets |
| 168 | +A [standard Maven fileSets block](https://maven.apache.org/shared/file-management/examples/mojo.html) that can be used |
| 169 | +to include any sets of file you desire. If used, no additional defaulting of fileSet values will be performed by Baton |
| 170 | +and *only* these filesets will be used for the plugin's execution. |
| 171 | + |
| 172 | +**NOTE:** File set configurations specified in your `migrations.json` will override those specified to your plugin at |
| 173 | +large. |
| 174 | + |
| 175 | +Default: None |
| 176 | + |
| 177 | +### migrationsConfigurationFile |
| 178 | +The configurations file name to look for in the classpath (all matches will be used). |
| 179 | + |
| 180 | +Default: `migrations.json` |
| 181 | + |
| 182 | +## Migrations JSON File Configuration |
| 183 | +When specifying your configurations in `migrations.json` or your custom `migrationsConfigurationFile` file name, the |
| 184 | +following options are available. |
| 185 | + |
| 186 | +### name |
| 187 | +The name of the migration to perform. As of 0.1.0, `name` is not particularly impactful. However, in subsequent |
| 188 | +releases it will gain importance as a means to order migration execution (convention-driven in the style of Flyway) as |
| 189 | +well as inactivate specific migrations. |
| 190 | + |
| 191 | +Required? `true` |
| 192 | + |
| 193 | +Default: None |
| 194 | + |
| 195 | +### description |
| 196 | +The description of the migration. This is intended to provide context on why the migration is needed. |
| 197 | + |
| 198 | +Required? `false` |
| 199 | + |
| 200 | +Default: None |
| 201 | + |
| 202 | +### implementation |
| 203 | +The fully qualified Java class name that will perform the migration. This **MUST** implement the |
| 204 | +`org.technologybrewery.baton.Migration` interface, however it is recommended that it extend |
| 205 | +`org.technologybrewery.baton.AbstractMigration` to allow implementations to be more consistent and focus on migration |
| 206 | +logic rather than Baton plumbing. The implementation **MUST** have a default constructor. |
| 207 | + |
| 208 | +Required? `true` |
| 209 | + |
| 210 | +Default: None |
| 211 | + |
| 212 | +### fileSet |
| 213 | +A Maven-inspired object that allows specification of common file sets. **MUST** be added as a list item. |
| 214 | + |
| 215 | +Required? `false` |
| 216 | + |
| 217 | +Default: None |
| 218 | + |
| 219 | +#### fileSet/directory |
| 220 | +The directory on which this file set should operate. |
| 221 | + |
| 222 | +Required? `false` |
| 223 | + |
| 224 | +Default: `./` (project base directory) |
| 225 | + |
| 226 | +#### fileSet/includes |
| 227 | +A list of specific inclusions following [standard Maven conventions](https://maven.apache.org/shared/file-management/examples/mojo.html). |
| 228 | + |
| 229 | +Required? `false` |
| 230 | + |
| 231 | +Default: None |
| 232 | + |
| 233 | +#### fileSet/excludes |
| 234 | +A list of specific exclusions following [standard Maven conventions](https://maven.apache.org/shared/file-management/examples/mojo.html). |
| 235 | + |
| 236 | +Required? `false` |
| 237 | + |
| 238 | +Default: None |
| 239 | + |
| 240 | +#### fileSet/followSymlinks |
| 241 | +Whether to follow symlinks following [standard Maven conventions](https://maven.apache.org/shared/file-management/examples/mojo.html). |
| 242 | + |
| 243 | +Required? `false` |
| 244 | + |
| 245 | +Default: None |
| 246 | + |
| 247 | +## Building Baton |
| 248 | +If you are working on Baton, please be aware of some nuances in working with a plugin that defines a custom Maven build |
| 249 | +lifecycle and packaging. `examples` are utilized to immediately test the `baton-maven-plugin`. If `baton-maven-plugin` |
| 250 | +has not been previously built, developers must manually build the `baton-maven-plugin` and then execute another, separate |
| 251 | +build of `examples` (and any other baton module) to use the updated `baton-maven-plugin`. That said, once an initial |
| 252 | +build has been completed, a single build may be used to build `baton-maven-plugin` and apply the updates to `examples`. |
| 253 | +To assist, there are two profiles available in the build: |
| 254 | + |
| 255 | +- `mvn clean install -Pbootstrap`: Builds the baton-maven-plugin such that it may be utilized within subsequent builds. |
| 256 | +- `mvn clean install -Pdefault`: (ACTIVE BY DEFAULT - `-Pdefault` does not need to be specified) builds all modules. Developers may use this profile to build and apply changes to existing `baton-maven-plugin` Mojo classes. |
0 commit comments