Skip to content

Commit 555858d

Browse files
Merge pull request #2 from TechnologyBrewery/1-initial-cut
#1 🎉 initial cut of rough migration functionality
2 parents 5520190 + 44b40f2 commit 555858d

File tree

33 files changed

+1901
-2
lines changed

33 files changed

+1901
-2
lines changed

.github/workflows/maven.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
3+
4+
# This workflow uses actions that are not certified by GitHub.
5+
# They are provided by a third-party and are governed by
6+
# separate terms of service, privacy policy, and support
7+
# documentation.
8+
9+
name: Build Baton
10+
11+
on:
12+
push:
13+
branches: [ "dev" ]
14+
pull_request:
15+
branches: [ "dev" ]
16+
17+
jobs:
18+
build:
19+
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- uses: actions/checkout@v3
24+
- name: Setup Pyenv
25+
uses: gabrielfalcao/pyenv-action@v16
26+
- name: Install Poetry
27+
uses: snok/install-poetry@v1
28+
- name: Set up JDK 11
29+
uses: actions/setup-java@v3
30+
with:
31+
java-version: '11'
32+
distribution: 'temurin'
33+
cache: maven
34+
- name: Build baton-maven-plugin
35+
run: mvn -B install -Pbootstrap --file pom.xml
36+
37+
# Work around habushu challenge in test step by just running initialize
38+
- name: Build migrations for testing
39+
run: mvn -B install -pl :example-migration-configuration --file pom.xml
40+
41+
# Work around habushu challenge in test step by just running initialize
42+
- name: Test baton-maven-plugin
43+
run: mvn -B initialize --file pom.xml
44+
45+
# Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
46+
- name: Update dependency graph
47+
uses: advanced-security/maven-dependency-submission-action@v3

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Log files
2+
*.log
3+
4+
# Maven
5+
target/
6+
dist/
7+
8+
# poetry examples
9+
poetry.lock
10+
.python-version
11+
12+
# JetBrains IDE
13+
.idea/
14+
*.iml
15+
16+
# Generated by MacOS
17+
.DS_Store
18+
19+
# Generated by Windows
20+
Thumbs.db

README.md

Lines changed: 256 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,256 @@
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+
[![Maven Central](https://img.shields.io/maven-central/v/org.technologybrewery.baton/baton.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.technologybrewery.baton%22%20AND%20a%3A%22baton%22)
3+
[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://opensource.org/licenses/mit)
4+
[![Build (github)](https://github.com/TechnologyBrewery/baton/actions/workflows/maven.yaml/badge.svg)](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

Comments
 (0)