Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track meaningful changes in a structured way #13

Open
Cirras opened this issue Dec 29, 2023 · 2 comments
Open

Track meaningful changes in a structured way #13

Cirras opened this issue Dec 29, 2023 · 2 comments
Assignees

Comments

@Cirras
Copy link
Owner

Cirras commented Dec 29, 2023

Background

  • An important use-case for the eo-protocol specification is code generation for libraries.
  • eo-protocol still receives changes to fix inaccuracies or inconsistencies.

Problems

  1. How are libraries supposed to conform to semantic versioning while also managing changes to eo-protocol?

    • In practice most libraries could at least handle trivial field renames by deprecating the old accessors and redirecting them to the new field.
    • In many other cases, an eo-protocol spec change may surface as a breaking change for the library's API. In other words, deprecation of the old API is not possible and the library will require a major version bump.
  2. How are libraries supposed to "remember" the eo-protocol changes so that deprecations can be generated?

    • eolib-python does this by hardcoding deprecations into the code generator. (see Cirras/eolib-python@c03eda6)
    • The eolib-python approach is inconsistent and error-prone, with no centralized source of truth.

Solution

Meaningful changes should be tracked in a changes.xml file which libraries can consume and make decisions based on.

Change types

Each change type element should be a direct child of the root <changes> element.

structs packets fields enums enum values miscellaneous
add-struct add-packet add-field add-enum add-enum-value other
remove-struct remove-packet remove-field remove-enum remove-enum-value -
rename-struct - rename-field rename-enum rename-enum-value -
- - retype-field retype-enum - -

Each change type element should have the following attributes:

  • when (date when the change was made, with format YYYY-MM-DD)
  • reason (message describing the reason for the change)

Consuming changes.xml

A changeset-start-date should be specified by each target and not be changed unless the major version is bumped.

A particular target's code generator should...

  • read all changes from changes.xml
  • discard all changes before changeset-start-date
  • collect remaining changes, which we will call the "changeset"
    • The changeset should be persisted through codegen and used to generate deprecatations
    • Example: if we have a rename-field change, then deprecated field accessors should be generated with the old name
  • raise an error if there's a breaking change in the changeset (see below)

Handling breaking changes

What constitutes a breaking change is target-specific and won't be specified by changes.xml.

For example, renaming a type would always be a breaking change in eolib-java.
However, any language with type aliases could simply create a (deprecated) type alias from the old name to the new name.

Therefore, a particular target's code generator should decide whether a change is breaking.

If a change in the selected changeset (from changeset-start-date onward) is considered breaking...

  • The code generator should raise an error.
  • The message should be something like "Breaking change detected in current eo-protocol changeset. Move changeset-start-date to today, and bump the library's major version."

Minimal changes.xml example

<changes>
  <rename-field when="2023-12-29" reason="`Direction` violates the naming convention for fields.">
    <old-name>Direction</old-name>
    <new-name>direction</new-name>
    <type>
       <packet family="Walk" action="Player" kind="client"/>
    </type>
  </rename-field>
</changes>
@Cirras Cirras self-assigned this Dec 29, 2023
@Cirras
Copy link
Owner Author

Cirras commented Jan 5, 2024

Giving some thought to alternative modeling of the xml elements.

<changes>
    <change when="2023-12-29" reason="`Direction` violates the naming convention for fields.">
        <target>
            <packet family="Walk" action="Player" kind="client">
                <field name="Direction">
            </packet>
        </target>
        <operation>
            <change-name new-name="direction"/>
        </operation>
    </change>
</changes>

I like that this doesn't force us to have a bunch of change-type permutations for the different change targets.

Operations

  • add
  • remove
  • move
  • change-name
  • change-type
  • change-value

@Cirras
Copy link
Owner Author

Cirras commented Jan 5, 2024

Unanswered question...
image

@Cirras Cirras closed this as completed Jan 5, 2024
@Cirras Cirras reopened this Jan 5, 2024
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

No branches or pull requests

1 participant