Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Seamlessly integrate Aether Datafixers into Spring Boot applications:
### Support

- [Troubleshooting](troubleshooting/index.md)
- [Migration Guide](migration/index.md)
- [Common Errors](troubleshooting/common-errors.md)
- [FAQ](troubleshooting/faq.md)
- [Glossary](appendix/glossary.md)
Expand Down
25 changes: 25 additions & 0 deletions docs/migration/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Migration Guides

This section contains guides for upgrading between major versions of Aether Datafixers.

## Available Guides

| From | To | Guide |
|--------|--------|------------------------------------|
| v0.5.x | v1.0.0 | [Migration Guide](v0.5-to-v1.0.md) |

## Before You Migrate

1. **Back up your project** — Create a commit or backup before starting
2. **Read the full guide** — Understand all changes before making modifications
3. **Update dependencies first** — Ensure your build file references the new version
4. **Run tests after** — Verify your migrations still work correctly

## General Migration Strategy

1. Update the version in your build file (`pom.xml` or `build.gradle`)
2. Attempt to compile — note all compilation errors
3. Apply automated migration patterns from the guide
4. Fix any remaining issues manually
5. Run your test suite
6. Enable deprecation warnings to catch deprecated API usage
348 changes: 348 additions & 0 deletions docs/migration/v0.5-to-v1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
# Migration Guide: v0.5.x to v1.0.0

This guide helps you migrate your project from Aether Datafixers v0.5.x to v1.0.0. It covers breaking changes, step-by-step migration instructions, and automated migration patterns.

## Overview

Version 1.0.0 introduces breaking changes to improve the codec package organization and API clarity. This guide will help you update your codebase with minimal effort.

| Change Type | Component | Impact |
|-----------------|-------------------------|---------------------------------------------------|
| **Breaking** | Codec package structure | Import statements must be updated |
| **Breaking** | `JacksonOps` rename | Class renamed to `JacksonJsonOps` |
| **Breaking** | `TestData.jackson()` | Method renamed to `TestData.jacksonJson()` |
| **Deprecation** | Rules traversal methods | Single-argument overloads deprecated (still work) |

---

## Breaking Changes

### 1. Codec Package Restructuring

The codec module has been reorganized to better reflect the supported formats (JSON, YAML, TOML, XML).

**Before (v0.5.x):**
```java
import de.splatgames.aether.datafixers.codec.gson.GsonOps;
import de.splatgames.aether.datafixers.codec.jackson.JacksonOps;
```

**After (v1.0.0):**
```java
import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;
import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;
```

**Rationale:** The new package structure groups implementations by format type (`json`, `yaml`, `toml`, `xml`) rather than by library. This makes it easier to discover all available JSON implementations and aligns with the YAML/TOML/XML naming conventions.

**Complete Package Mapping:**

| Old Package (v0.5.x) | New Package (v1.0.0) |
|----------------------------|-------------------------------------|
| `codec.gson.GsonOps` | `codec.json.gson.GsonOps` |
| `codec.jackson.JacksonOps` | `codec.json.jackson.JacksonJsonOps` |

### 2. JacksonOps Class Rename

The `JacksonOps` class has been renamed to `JacksonJsonOps` to distinguish it from other Jackson-based implementations.

**Before (v0.5.x):**
```java
Dynamic<JsonNode> dynamic = new Dynamic<>(JacksonOps.INSTANCE, jsonNode);
```

**After (v1.0.0):**
```java
Dynamic<JsonNode> dynamic = new Dynamic<>(JacksonJsonOps.INSTANCE, jsonNode);
```

**Rationale:** With the introduction of `JacksonYamlOps`, `JacksonTomlOps`, and `JacksonXmlOps`, the generic name `JacksonOps` was ambiguous. The suffix `JsonOps` makes it clear which format is being used.

### 3. TestData Method Rename

The `TestData.jackson()` method has been renamed to `TestData.jacksonJson()`.

**Before (v0.5.x):**
```java
Dynamic<JsonNode> testData = TestData.jackson()
.put("name", "Alice")
.put("level", 42)
.build();
```

**After (v1.0.0):**
```java
Dynamic<JsonNode> testData = TestData.jacksonJson()
.put("name", "Alice")
.put("level", 42)
.build();
```

**Rationale:** Consistency with `jacksonYaml()`, `jacksonToml()`, and `jacksonXml()` methods.

---

## Deprecations (Non-Breaking)

### Rules Traversal Methods

The single-argument overloads of traversal methods are deprecated but **not removed**. Your code will still compile and run, but you'll see deprecation warnings.

**Deprecated Methods:**
- `Rules.all(rule)` — use `Rules.all(ops, rule)`
- `Rules.one(rule)` — use `Rules.one(ops, rule)`
- `Rules.everywhere(rule)` — use `Rules.everywhere(ops, rule)`
- `Rules.bottomUp(rule)` — use `Rules.bottomUp(ops, rule)`
- `Rules.topDown(rule)` — use `Rules.topDown(ops, rule)`

**Why migrate?** The deprecated methods are **no-ops** that don't actually traverse children. They exist only for API compatibility. To get proper child traversal behavior, you must provide a `DynamicOps` instance.

**Before (deprecated):**
```java
TypeRewriteRule rule = Rules.everywhere(
Rules.renameField("player", "name", "username")
);
```

**After (recommended):**
```java
TypeRewriteRule rule = Rules.everywhere(GsonOps.INSTANCE,
Rules.renameField("player", "name", "username")
);
```

---

## Automated Migration

### IntelliJ IDEA (Regex Search & Replace)

Use **Edit → Find → Replace in Files** (Ctrl+Shift+R / Cmd+Shift+R) with **Regex** enabled.

#### GsonOps Import
- **Find:** `import de\.splatgames\.aether\.datafixers\.codec\.gson\.GsonOps;`
- **Replace:** `import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;`

#### JacksonOps Import and Class Name
- **Find:** `import de\.splatgames\.aether\.datafixers\.codec\.jackson\.JacksonOps;`
- **Replace:** `import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;`

Then replace all usages:
- **Find:** `JacksonOps\.INSTANCE`
- **Replace:** `JacksonJsonOps.INSTANCE`

And the type reference:
- **Find:** `JacksonOps(?!Json)`
- **Replace:** `JacksonJsonOps`

#### TestData.jackson()
- **Find:** `TestData\.jackson\(\)`
- **Replace:** `TestData.jacksonJson()`

#### Rules Methods (Optional - for deprecation cleanup)
- **Find:** `Rules\.(all|one|everywhere|bottomUp|topDown)\((?!.*DynamicOps)(\w+)\)`
- **Replace:** `Rules.$1(GsonOps.INSTANCE, $2)`

**Note:** The Rules regex assumes you want to use `GsonOps.INSTANCE`. Adjust the replacement if you use a different `DynamicOps` implementation.

---

### VS Code (Regex Search & Replace)

Use **Edit → Replace in Files** (Ctrl+Shift+H / Cmd+Shift+H) with **Regex** enabled (Alt+R).

The same patterns work in VS Code:

| Find | Replace |
|--------------------------------------------------------------------------|-----------------------------------------------------------------------------|
| `import de\.splatgames\.aether\.datafixers\.codec\.gson\.GsonOps;` | `import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;` |
| `import de\.splatgames\.aether\.datafixers\.codec\.jackson\.JacksonOps;` | `import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;` |
| `JacksonOps\.INSTANCE` | `JacksonJsonOps.INSTANCE` |
| `TestData\.jackson\(\)` | `TestData.jacksonJson()` |

---

### Command Line (sed)

For batch migration across multiple files:

```bash
# GsonOps import
find . -name "*.java" -exec sed -i 's/import de\.splatgames\.aether\.datafixers\.codec\.gson\.GsonOps;/import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;/g' {} +

# JacksonOps import
find . -name "*.java" -exec sed -i 's/import de\.splatgames\.aether\.datafixers\.codec\.jackson\.JacksonOps;/import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;/g' {} +

# JacksonOps class name
find . -name "*.java" -exec sed -i 's/JacksonOps\.INSTANCE/JacksonJsonOps.INSTANCE/g' {} +
find . -name "*.java" -exec sed -i 's/JacksonOps\([^J]\)/JacksonJsonOps\1/g' {} +

# TestData.jackson()
find . -name "*.java" -exec sed -i 's/TestData\.jackson()/TestData.jacksonJson()/g' {} +
```

**macOS Note:** Use `sed -i ''` instead of `sed -i` on macOS.

---

### PowerShell (Windows)

```powershell
# GsonOps import
Get-ChildItem -Recurse -Filter *.java | ForEach-Object {
(Get-Content $_.FullName) -replace 'import de\.splatgames\.aether\.datafixers\.codec\.gson\.GsonOps;', 'import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;' | Set-Content $_.FullName
}

# JacksonOps import
Get-ChildItem -Recurse -Filter *.java | ForEach-Object {
(Get-Content $_.FullName) -replace 'import de\.splatgames\.aether\.datafixers\.codec\.jackson\.JacksonOps;', 'import de.splatgames.aether.datafixers.codec.json.jackson.JacksonJsonOps;' | Set-Content $_.FullName
}

# JacksonOps class name
Get-ChildItem -Recurse -Filter *.java | ForEach-Object {
(Get-Content $_.FullName) -replace 'JacksonOps\.INSTANCE', 'JacksonJsonOps.INSTANCE' | Set-Content $_.FullName
}

# TestData.jackson()
Get-ChildItem -Recurse -Filter *.java | ForEach-Object {
(Get-Content $_.FullName) -replace 'TestData\.jackson\(\)', 'TestData.jacksonJson()' | Set-Content $_.FullName
}
```

---

## Verification

### Step 1: Compile-Time Verification

After applying the migrations, rebuild your project:

```bash
mvn clean compile
```

or

```bash
./gradlew clean compileJava
```

**Expected:** No compilation errors. If you see import errors, you may have missed some files.

### Step 2: Check for Deprecation Warnings

Enable deprecation warnings to identify remaining deprecated API usage:

**Maven:**
```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-Xlint:deprecation</arg>
</compilerArgs>
</configuration>
</plugin>
```

**Gradle:**
```groovy
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation"
}
```

Look for warnings like:
```
warning: [deprecation] all(TypeRewriteRule) in Rules has been deprecated
```

These indicate deprecated `Rules` methods that should be updated to include `DynamicOps`.

### Step 3: Run Tests

Execute your test suite to verify runtime behavior:

```bash
mvn test
```

or

```bash
./gradlew test
```

### Step 4: Manual Spot Check

Verify critical migration paths in your application:

1. Load sample data from v0.5.x
2. Run migrations through your `DataFixer`
3. Verify output matches expected format
4. Check logs for any unexpected warnings

---

## Troubleshooting

### "Cannot resolve symbol 'JacksonOps'"

You updated the import but not all usages of the class name.

**Solution:** Replace `JacksonOps` with `JacksonJsonOps` throughout your code.

### "Cannot resolve symbol 'GsonOps'" after migration

Verify your import statement is:
```java
import de.splatgames.aether.datafixers.codec.json.gson.GsonOps;
```

Not the old path:
```java
import de.splatgames.aether.datafixers.codec.gson.GsonOps;
```

### Rules not traversing children

If your `Rules.everywhere()`, `Rules.topDown()`, or similar methods seem to not transform nested data, you're likely using the deprecated single-argument overload.

**Solution:** Add a `DynamicOps` parameter:
```java
// Before (deprecated, doesn't traverse children)
Rules.everywhere(myRule)

// After (correct behavior)
Rules.everywhere(GsonOps.INSTANCE, myRule)
```

### "TestData.jackson() not found"

The method was renamed.

**Solution:** Replace `TestData.jackson()` with `TestData.jacksonJson()`.

---

## Summary Checklist

- [ ] Update `codec.gson.GsonOps` imports to `codec.json.gson.GsonOps`
- [ ] Update `codec.jackson.JacksonOps` imports to `codec.json.jackson.JacksonJsonOps`
- [ ] Replace `JacksonOps` class references with `JacksonJsonOps`
- [ ] Replace `TestData.jackson()` with `TestData.jacksonJson()`
- [ ] (Optional) Update deprecated `Rules` methods to include `DynamicOps`
- [ ] Rebuild and verify no compilation errors
- [ ] Run test suite
- [ ] Enable deprecation warnings and address remaining issues

---

## Need Help?

If you encounter issues during migration:

- Check the [FAQ](../troubleshooting/faq.md) for common questions
- Review [Common Errors](../troubleshooting/common-errors.md) for error messages
- File an issue at [GitHub Issues](https://github.com/aether-framework/aether-datafixers/issues)
Loading