Skip to content

Commit 08c9866

Browse files
committed
Release v0.2.0: Finalize version, update changelog, and add detailed release notes.
1 parent 056d8b4 commit 08c9866

9 files changed

Lines changed: 250 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
66

77
---
88

9-
## [0.2.0] - 2026-01-06
9+
## [0.2.0] - 2026-01-07
1010

1111
### Added
1212

RELEASE.md

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
# Aether Datafixers v0.2.0 — Testkit, Extended Rules, Diagnostics, and Performance
2+
3+
Extended rules, testkit module, migration diagnostics, and high-performance APIs.
4+
5+
---
6+
7+
## Highlights in v0.2.0
8+
9+
- **Testkit Module** — New `aether-datafixers-testkit` module with fluent test data builders, custom AssertJ assertions, and test harnesses for DataFix, Schema, and migration testing.
10+
- **Extended Rewrite Rules** — Convenience methods for batch operations, field grouping/flattening, path-based operations, and conditional rules.
11+
- **Migration Diagnostics** — Opt-in diagnostic system for structured reports with timing, snapshots, and warnings.
12+
- **High-Performance APIs** — Batch transformations and single-pass conditionals for optimized migrations.
13+
- **Performance Optimizations** — Internal improvements with memoized path parsing, pre-allocated lists, and reduced allocations.
14+
15+
---
16+
17+
## Installation
18+
19+
> [!TIP]
20+
> All Aether artifacts are available on **Maven Central** — no extra repository required.
21+
22+
### Maven
23+
24+
```xml
25+
<dependency>
26+
<groupId>de.splatgames.aether.datafixers</groupId>
27+
<artifactId>aether-datafixers-core</artifactId>
28+
<version>0.2.0</version>
29+
</dependency>
30+
```
31+
32+
**Using the BOM**
33+
34+
```xml
35+
<dependencyManagement>
36+
<dependencies>
37+
<dependency>
38+
<groupId>de.splatgames.aether.datafixers</groupId>
39+
<artifactId>aether-datafixers-bom</artifactId>
40+
<version>0.2.0</version>
41+
<type>pom</type>
42+
<scope>import</scope>
43+
</dependency>
44+
</dependencies>
45+
</dependencyManagement>
46+
47+
<dependencies>
48+
<!-- No version needed -->
49+
<dependency>
50+
<groupId>de.splatgames.aether.datafixers</groupId>
51+
<artifactId>aether-datafixers-core</artifactId>
52+
</dependency>
53+
</dependencies>
54+
```
55+
56+
### Gradle (Groovy)
57+
58+
```groovy
59+
dependencies {
60+
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core:0.2.0'
61+
// Or with BOM:
62+
implementation platform('de.splatgames.aether.datafixers:aether-datafixers-bom:0.2.0')
63+
implementation 'de.splatgames.aether.datafixers:aether-datafixers-core'
64+
}
65+
```
66+
67+
### Gradle (Kotlin)
68+
69+
```kotlin
70+
dependencies {
71+
implementation("de.splatgames.aether.datafixers:aether-datafixers-core:0.2.0")
72+
// Or with BOM:
73+
implementation(platform("de.splatgames.aether.datafixers:aether-datafixers-bom:0.2.0"))
74+
implementation("de.splatgames.aether.datafixers:aether-datafixers-core")
75+
}
76+
```
77+
78+
---
79+
80+
## What's New
81+
82+
### Testkit Module
83+
84+
New module `aether-datafixers-testkit` for testing migrations:
85+
86+
```xml
87+
<dependency>
88+
<groupId>de.splatgames.aether.datafixers</groupId>
89+
<artifactId>aether-datafixers-testkit</artifactId>
90+
<version>0.2.0</version>
91+
<scope>test</scope>
92+
</dependency>
93+
```
94+
95+
**Features:**
96+
- `TestData` — Fluent test data builders for Gson and Jackson
97+
- `AetherAssertions` — Custom AssertJ assertions for `Dynamic`, `DataResult`, `Typed`
98+
- `DataFixTester` — Test harness for individual DataFix implementations
99+
- `MigrationTester` — Test harness for complete migration chains
100+
- `SchemaTester` — Test harness for Schema validation
101+
- `QuickFix` — Factory methods for common fix patterns
102+
- `MockSchemas` — Factory for mock Schema instances
103+
- `RecordingContext` / `AssertingContext` — Test contexts
104+
105+
**Example:**
106+
```java
107+
// Create test data fluently
108+
Dynamic<JsonElement> input = TestData.gson().object()
109+
.put("name", "Alice")
110+
.put("level", 10)
111+
.build();
112+
113+
// Test a DataFix
114+
DataFixTester.forFix(myFix)
115+
.withInput(input)
116+
.forType("player")
117+
.expectOutput(expected)
118+
.verify();
119+
120+
// Test a full migration chain
121+
MigrationTester.forFixer(myFixer)
122+
.forType(PLAYER)
123+
.withInput(v1Data)
124+
.from(1).to(5)
125+
.expectOutput(v5Data)
126+
.verify();
127+
```
128+
129+
### Extended Rewrite Rules
130+
131+
New convenience methods in `Rules` class:
132+
133+
| Rule | Purpose |
134+
|------|---------|
135+
| `dynamicTransform(name, ops, fn)` | Custom Dynamic transformation |
136+
| `setField(ops, field, value)` | Set field (overwrites existing) |
137+
| `renameFields(ops, map)` | Batch rename multiple fields |
138+
| `removeFields(ops, fields...)` | Batch remove multiple fields |
139+
| `groupFields(ops, target, fields...)` | Group fields into nested object |
140+
| `flattenField(ops, field)` | Flatten nested object to root |
141+
| `moveField(ops, source, target)` | Move field between paths |
142+
| `copyField(ops, source, target)` | Copy field (keeps original) |
143+
| `transformFieldAt(ops, path, fn)` | Transform at nested path |
144+
| `renameFieldAt(ops, path, newName)` | Rename at nested path |
145+
| `removeFieldAt(ops, path)` | Remove at nested path |
146+
| `addFieldAt(ops, path, value)` | Add at nested path |
147+
| `ifFieldExists(ops, field, rule)` | Conditional on existence |
148+
| `ifFieldMissing(ops, field, rule)` | Conditional on absence |
149+
| `ifFieldEquals(ops, field, value, rule)` | Conditional on value |
150+
151+
**Example:**
152+
```java
153+
Rules.seq(
154+
Rules.renameFields(ops, Map.of("playerName", "name", "xp", "experience")),
155+
Rules.groupFields(ops, "position", "x", "y", "z"),
156+
Rules.ifFieldMissing(ops, "version", Rules.setField(ops, "version", d -> d.createInt(1)))
157+
)
158+
```
159+
160+
### Migration Diagnostics
161+
162+
New opt-in diagnostic system for capturing structured reports:
163+
164+
**API:**
165+
- `DiagnosticOptions` — Configuration for diagnostic capture
166+
- `DiagnosticContext` — Context interface for diagnostic migrations
167+
- `MigrationReport` — Immutable report with timing, fixes, rules, warnings, and snapshots
168+
169+
**Features:**
170+
- Zero overhead when diagnostics are not enabled
171+
- Configurable snapshot capture with truncation limits
172+
- Per-fix and per-rule timing measurements
173+
- Warning emission from DataFix implementations
174+
175+
**Presets:**
176+
- `DiagnosticOptions.defaults()` — Full diagnostics with snapshots and rule details
177+
- `DiagnosticOptions.minimal()` — Timing only, minimal overhead
178+
179+
### High-Performance APIs
180+
181+
**BatchTransform:**
182+
```java
183+
Rules.batch(ops, batch -> batch
184+
.rename("oldName", "newName")
185+
.remove("deprecated")
186+
.set("version", d -> d.createInt(2))
187+
.transform("count", d -> d.createInt(d.asInt(0) + 1))
188+
.addIfMissing("created", d -> d.createLong(System.currentTimeMillis()))
189+
)
190+
```
191+
192+
**Single-Pass Conditionals:**
193+
```java
194+
Rules.conditionalTransform(ops,
195+
d -> d.get("type").asString("").equals("legacy"),
196+
d -> d.set("migrated", d.createBoolean(true))
197+
)
198+
```
199+
200+
### Performance Optimizations
201+
202+
Internal optimizations with no API changes:
203+
- Path parsing uses character-based parsing with memoization cache
204+
- `DataFixRegistry.getFixes()` pre-allocates result list
205+
- `DataFixerImpl` moves validation to registration time
206+
- Reduced allocations in hot paths
207+
208+
---
209+
210+
## Changelog
211+
212+
**New in 0.2.0**
213+
214+
- Testkit module with fluent builders, assertions, and test harnesses
215+
- Extended rewrite rules for batch, grouping, path, and conditional operations
216+
- Migration diagnostics system with timing and snapshots
217+
- High-performance batch transformations
218+
- Single-pass conditional APIs
219+
- Performance optimizations (memoization, pre-allocation)
220+
- Comprehensive documentation updates
221+
222+
**Full Changelog:** [v0.1.0...v0.2.0](https://github.com/aether-framework/aether-datafixers/compare/v0.1.0...v0.2.0)
223+
224+
---
225+
226+
## Roadmap (next)
227+
228+
- **0.3.x**
229+
- Additional codec implementations
230+
- Schema validation enhancements
231+
- Migration dry-run mode
232+
233+
- **1.0.x**
234+
- Stable API surface
235+
- Comprehensive documentation
236+
- Production-ready release
237+
238+
---
239+
240+
## License
241+
242+
**MIT** — see `LICENSE`.

aether-datafixers-api/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>de.splatgames.aether.datafixers</groupId>
88
<artifactId>aether-datafixers</artifactId>
9-
<version>0.2.0-SNAPSHOT</version>
9+
<version>0.2.0</version>
1010
</parent>
1111

1212
<artifactId>aether-datafixers-api</artifactId>

aether-datafixers-bom/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>de.splatgames.aether.datafixers</groupId>
88
<artifactId>aether-datafixers</artifactId>
9-
<version>0.2.0-SNAPSHOT</version>
9+
<version>0.2.0</version>
1010
</parent>
1111

1212
<artifactId>aether-datafixers-bom</artifactId>

aether-datafixers-codec/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>de.splatgames.aether.datafixers</groupId>
88
<artifactId>aether-datafixers</artifactId>
9-
<version>0.2.0-SNAPSHOT</version>
9+
<version>0.2.0</version>
1010
</parent>
1111

1212
<artifactId>aether-datafixers-codec</artifactId>

aether-datafixers-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>de.splatgames.aether.datafixers</groupId>
88
<artifactId>aether-datafixers</artifactId>
9-
<version>0.2.0-SNAPSHOT</version>
9+
<version>0.2.0</version>
1010
</parent>
1111

1212
<artifactId>aether-datafixers-core</artifactId>

aether-datafixers-examples/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>de.splatgames.aether.datafixers</groupId>
99
<artifactId>aether-datafixers</artifactId>
10-
<version>0.2.0-SNAPSHOT</version>
10+
<version>0.2.0</version>
1111
</parent>
1212

1313
<artifactId>aether-datafixers-examples</artifactId>

aether-datafixers-testkit/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>de.splatgames.aether.datafixers</groupId>
88
<artifactId>aether-datafixers</artifactId>
9-
<version>0.2.0-SNAPSHOT</version>
9+
<version>0.2.0</version>
1010
</parent>
1111

1212
<artifactId>aether-datafixers-testkit</artifactId>

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>de.splatgames.aether.datafixers</groupId>
88
<artifactId>aether-datafixers</artifactId>
9-
<version>0.2.0-SNAPSHOT</version>
9+
<version>0.2.0</version>
1010
<packaging>pom</packaging>
1111
<modules>
1212
<module>aether-datafixers-api</module>

0 commit comments

Comments
 (0)