Topics

Marking API (was Re: [jmri-developers] Do we have a decision about skip deprecation for next major version?


Bob Jacobsen
 

I agree with Daniel; I think this is a good step forward.

How were those example tables (in JUnit4) made? Is that a manual step, or was it automated? Automated would be cool; I don’t think we can realistically maintain manual tables, so would prefer to refer people directly to the code in that case.

I think the next step would be to create a documentation page on how to use this (.md fine), specifically providing some consensus language around what an API is and how it connects to semantic versioning. Some cases are pretty clear (jmri.Turnout), but some are not: Should people consider inheriting from jmri.implementation.AbstractNamedBean to be use of an API? It’s certainly a thing in CATS and others.

I might have missed something, but I think the Unit page ties to semantic versioning as:

- (Visible) changes in STABLE requires a new major release
- INTERNAL and EXPERIMENTAL can be changed as part of update, minor or major releases.

But JUnit5 seems more aggressive about minor releases (center number) than I expected. Earlier, we had language that the center number was features that _didn’t_ break user code. (IIRC this came from the semantic version page). But the JUnit5 convention is (in relevant part):

DEPRECATED - might disappear in the next minor release.
MAINTAINED - will not be changed in a backwards- incompatible way for at least the next minor release of the current major version. If scheduled for removal, it will be demoted to DEPRECATED first.

(The ApiGuardian doc isn’t quite so explicit) That seems to imply that there’s no requirement to have a major-release bump to remove deprecated code, and that a MAINTAINED->DEPRECATED->gone sequence can be done in two minor releases.

Is that what we want? It’s better for developers, but library (not application) users don’t get as clear a picture. Whatever we decide, somebody should write it down.

Bob




On Jul 2, 2020, at 3:40 AM, Randall Wood via groups.io <rhwood=mac.com@groups.io> wrote:

I suggest we use the annotations from [API Guardian](https://github.com/apiguardian-team/apiguardian) to indicate what’s usable by design by implementers and scripters and declare everything else to be “implementation details” subject to change at will. By using these annotations we can allow what must be public to compile, but add a declarative layer over that to indicate that some public classes/methods/fields should not be relied upon.

See https://junit.org/junit5/docs/current/user-guide/#api-evolution for an example of tables automatically generated using those annotations. See also the [JUnit 5 Javadocs](https://junit.org/junit5/docs/current/api/) for how the annotations appear in Javadocs.

Bob Jacobsen
@BobJacobsen


Randall Wood <rhwood@...>
 

On 03-Jul-2020, at 12:40, Bob Jacobsen <@BobJacobsen> wrote:

I agree with Daniel; I think this is a good step forward.

How were those example tables (in JUnit4) made? Is that a manual step, or was it automated? Automated would be cool; I don’t think we can realistically maintain manual tables, so would prefer to refer people directly to the code in that case.
They were automatically generated; the tooling JUnit uses for the JUnit 5 documentation is at https://github.com/junit-team/junit5/tree/main/documentation/src/test/java/org/junit/api/tools

I think the next step would be to create a documentation page on how to use this (.md fine), specifically providing some consensus language around what an API is and how it connects to semantic versioning. Some cases are pretty clear (jmri.Turnout), but some are not: Should people consider inheriting from jmri.implementation.AbstractNamedBean to be use of an API? It’s certainly a thing in CATS and others.
The API annotation can be on methods, not just classes, so we could declare that AbstractNamedBean is STABLE as a class, but that all methods in AbstractNamedBean not overriding a STABLE interface are MAINTAINED. (i.e. a developer can expect to use AbstractNamedBean and that certain methods will remain stable, some other methods exposed as implementation details are not).

I might have missed something, but I think the Unit page ties to semantic versioning as:

- (Visible) changes in STABLE requires a new major release
- INTERNAL and EXPERIMENTAL can be changed as part of update, minor or major releases.

But JUnit5 seems more aggressive about minor releases (center number) than I expected. Earlier, we had language that the center number was features that _didn’t_ break user code. (IIRC this came from the semantic version page). But the JUnit5 convention is (in relevant part):

DEPRECATED - might disappear in the next minor release.
MAINTAINED - will not be changed in a backwards- incompatible way for at least the next minor release of the current major version. If scheduled for removal, it will be demoted to DEPRECATED first.

(The ApiGuardian doc isn’t quite so explicit) That seems to imply that there’s no requirement to have a major-release bump to remove deprecated code, and that a MAINTAINED->DEPRECATED->gone sequence can be done in two minor releases.

Is that what we want? It’s better for developers, but library (not application) users don’t get as clear a picture. Whatever we decide, somebody should write it down.
I think it is what we want. I’m certain we need to be explicit about we interpret the API statuses. We also need to decide what an unannotated class is. Should all unannotated classed be considered MAINTAINED or EXPERIMENTAL (I don’t think we want to make them all STABLE)?

Bob




On Jul 2, 2020, at 3:40 AM, Randall Wood via groups.io <rhwood=mac.com@groups.io> wrote:

I suggest we use the annotations from [API Guardian](https://github.com/apiguardian-team/apiguardian) to indicate what’s usable by design by implementers and scripters and declare everything else to be “implementation details” subject to change at will. By using these annotations we can allow what must be public to compile, but add a declarative layer over that to indicate that some public classes/methods/fields should not be relied upon.

See https://junit.org/junit5/docs/current/user-guide/#api-evolution for an example of tables automatically generated using those annotations. See also the [JUnit 5 Javadocs](https://junit.org/junit5/docs/current/api/) for how the annotations appear in Javadocs.

Bob Jacobsen
@BobJacobsen