Migrations
Use pistonconfig-migrations when a release changes config paths, defaults, or schema expectations.
Add the Module
dependencies {
implementation(platform("net.pistonmaster:pistonconfig-bom:0.1.0-SNAPSHOT"))
implementation("net.pistonmaster:pistonconfig-core")
implementation("net.pistonmaster:pistonconfig-migrations")
}
Create a Registry
var registry = MigrationRegistry.builder()
.versionPath(ConfigPath.parse("config.version"))
.addMigration(ConfigMigration.builder()
.version(1)
.action(config -> {
Migrations.rename(config, "server.bind", "server.host");
Migrations.setIfMissing(config, "server.port", 25565);
})
.build())
.addMigration(ConfigMigration.builder()
.version(2)
.action(config -> {
Migrations.copy(config, "server.host", "network.host");
Migrations.remove(config, "legacy");
})
.build())
.build();
Migrations run in ascending version order. The registry stores the latest applied version in the configured version path.
Apply Migrations
registry.migrate(document);
Run migrations after loading a file and before reading application values. Migrations mutate the document in place.
Built-In Operations
| Helper | Purpose |
|---|---|
Migrations.rename(document, from, to) |
Move a node to a new path. |
Migrations.copy(document, from, to) |
Copy a node while leaving the source in place. |
Migrations.remove(document, path) |
Delete a node. |
Migrations.setIfMissing(document, path, value) |
Add a scalar default only when no value exists. |
Versioning Rules
- Use monotonically increasing integer versions.
- Keep migrations deterministic and idempotent.
- Avoid reading runtime environment state inside migrations.
- Keep migrations focused on document shape, not application startup side effects.
Full Startup Order
- Load the user’s file.
- Run migrations.
- Merge current defaults.
- Apply environment and system property overrides.
- Save the migrated document.
This order keeps older files readable while preserving user edits.