Skip to content

Support migrating individual alternatives in unions#90

Open
adinapoli wants to merge 2 commits intomasterfrom
adinapoli/alternative-changes
Open

Support migrating individual alternatives in unions#90
adinapoli wants to merge 2 commits intomasterfrom
adinapoli/alternative-changes

Conversation

@adinapoli
Copy link
Contributor

(Full disclaimer: this has been AI-driven and not yet validated by a human).

Summary of Changes

I added the ChChangeUnionAlt change type to enable writing:

changed union Foo
  alternative changed bar :: BarNew migration MigrateBarOldToBarNew

Modified Files:

  1. src/Data/API/Changes/Types.hs:

    • Added ChChangeUnionAlt TypeName FieldName APIType MigrationTag constructor to APIChange
    • Added ppLines case for pretty-printing the new change syntax
  2. src/Data/API/Parse.y:

    • Added UnChChange FieldName APIType MigrationTag variant to UnionChange
    • Added parser rule for alternative changed
    • Added unionChangeToAPIChange conversion case
  3. src/Data/API/Changes.hs:

    • Added applyAPIChangeToAPI case for schema validation
    • Added applyChangeToData case for Aeson JSON value migration
    • Added applyChangeToData' case for the generic Value representation
    • Added changeTags case to include the migration tag in the set of field migrations
    • Added validateAfter case for proper validation behavior
  4. Test suite (tests/Data/API/Test/UnionMigration.hs and UnionMigrationData.hs):

    • Created a standalone test demonstrating the feature
    • The test migrates a TestRecord within a union by adding a name field with value `"id_"

How It Works:

When migrating a union alternative:

  1. The schema is updated to reflect the new type of the alternative
  2. For values matching the specified alternative, the custom migration function is applied to transform the value
  3. Values of other alternatives are passed through unchanged
  4. The migration function uses the same fieldMigration mechanism as record field changes

The migration tag MigrateBarOldToBarNew would be defined in the FieldMigration enumeration type generated by generateMigrationKinds, and the actual migration logic provided via the fieldMigration field of the CustomMigrations record.

@adinapoli adinapoli marked this pull request as ready for review February 5, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant