This is a collection of tips & tricks to help you get started with Revapi and to take full advantage of its many configuration options.
In situations where you want to require that certain version changes are made to have a passing build you can use
the semver ignore extension. Additionally, if you are wanting to not ignore specific codes, for an example in Java,
adding a method to an interface (
java.method.addedToInterface), you can also use reclassify extension to turn
BREAKING changes into
EQUIVALENT changes. The configuration for these might work independently, but there really is
not a guarantee of order that the extensions can be run, meaning that
semver.ignore can be ran before the
extension, causing the build to fail anyway. To get around this, a transform block can be used instead.
The configuration of the extensions are still specified in the
analysisConfiguration, but the
must also be specified to ensure that these extensions are run together and in a specific order.
<plugin> <groupId>org.revapi</groupId> <artifactId>revapi-maven-plugin</artifactId> <version>0.14.3</version> <dependencies> <dependency> <groupId>org.revapi</groupId> <artifactId>revapi-java</artifactId> <version>0.24.4</version> </dependency> </dependencies> <configuration> <analysisConfiguration> <revapi.reclassify> <item> <code>java.method.addedToInterface</code> <classify> <BINARY>EQUIVALENT</BINARY> <SOURCE>EQUIVALENT</SOURCE> <SEMANTIC>EQUIVALENT</SEMANTIC> </classify> </item> </revapi.reclassify> <revapi.semver.ignore> <enabled>true</enabled> <versionIncreaseAllows> <major>breaking</major> <minor>nonBreaking</minor> <patch>equivalent</patch> </versionIncreaseAllows> </revapi.semver.ignore> </analysisConfiguration> <pipelineConfiguration> <transformBlocks> <block> <item>revapi.reclassify</item> <item>revapi.semver.ignore</item> </block> </transformBlocks> </pipelineConfiguration> </configuration> </plugin>
This is mainly a warning to ensure that you are exposing class from external dependency on purpose. Generally, exposing a class from an external dependency could be considered a bad design because this could make it harder to upgrade to a more recent version of the dependency. One reason amongst others which makes encapsulation a good practice.
But there are use cases where this totally makes sense. The most common one is probably when you have a multi-module Maven project. In this case it is usual to have some modules exposing classes from another "core" or "api" module.
myproject-impl exposes classes from
An easy way to deal with this is to configure revapi like this :
<plugin> <groupId>org.revapi</groupId> <artifactId>revapi-maven-plugin</artifactId> <configuration> <analysisConfiguration> <revapi.ignore> <item> <regex>true</regex> <code>java.class.externalClassExposedInAPI</code> <newArchive>org\.my\.project:myproject.*:.*</newArchive> <justification> MyProject sub-modules implement MyProject API which makes them expose MyProject specific classes usually. </justification> </item> </revapi.ignore> </plugin>