![CI status](https://secure.travis-ci.org/jeluard/semantic-versioning.png)
Version number changes implications are not always clearly identified. Can I be sure this new minor version didn't break the public API?
As a library writer, how to continuously validate I don't break binary compatibility?
`semantic-versioning` is a Java library allowing to validate (using bytecode inspection) if library version numbers follows Semantic Versioning principles as defined by [Semantic Versioning](http://semver.org).
It can check JAR files or classes to identify changes between versions and validate if the new version number is correct according to semver.
`semantic-versioning` is available as an [API](#api), a [command line tool](#cli) and a [maven enforcer](http://maven.apache.org/enforcer/maven-enforcer-plugin/) [rule](#rule).
## API overview
Semantic Versioning also provides an API for programmatically validating your project's version number.
```java
final File previousJar = ...;
final File currentJar = ...;
final Comparer comparer = new Comparer(previousJar, currentJar, ..., ...);
final Delta delta = comparer.diff();
final String compatibilityType = ...;
//Validates that computed and provided compatibility type are compatible.
final Delta.CompatibilityType expectedCompatibilityType = Delta.CompatibilityType.valueOf(compatibilityType);
final Delta.CompatibilityType detectedCompatibilityType = delta.computeCompatibilityType();
if (detectedCompatibilityType.compareTo(expectedCompatibilityType) > 0) {
//Not compatible.
}
//Provide version number for previous and current Jar files.
final Version previous = Version.parse(...);
final Version current = Version.parse(...);
//Validates that current version number is valid based on semantic versioning principles.
final boolean compatible = delta.validate(previous, current);
```
## CLI
This simple command line tool looks at Java JAR files and determine API changes.
### Built-in help
```
% java -jar semver.jar --help
Semantic Version validator.
Usage: semver [options]
Options:
--base-jar JAR The base jar.
--base-version VERSION Version of the base jar (given with --base-jar).
--check,-c Check the compatibility of two jars.
--diff,-d Show the differences between two jars.
--excludes EXCLUDE;... Semicolon separated list of full qualified class names
or partly qualified class names with wild cards
to be excluded.
--help,-h Show this help and exit.
--includes INCLUDE;... Semicolon separated list of full qualified class names
or partly qualified class names with wild cards
to be included.
--infer,-i Infer the version of the new jar based on the previous
jar.
--new-jar JAR The new jar.
--new-version VERSION Version of the new jar (given with --new-jar).
--validate,-v Validate that the versions of two jars fulfil the
semver specification.
```
### Diff
Dump all changes between two JARs on standard output.
```
% java -jar semver.jar --diff --base-jar previousJar --new-jar current.jar
Class org.project.MyClass
Added Class
Class org.project.MyClass2
Added Method method1
Removed Field field1
Changed Field field2 removed: final
```
### Excludes / Includes
In- or exclude classes for the validation by specifying a fully qualified
class name or using wild cards. There are two wild cards: `*` and `**`.
`*` is a wild card for an arbitrary number of characters but at most one
folder hierarchy.
`**` is a wild card for an arbitrary number of characters and an arbitrary
number of folder hierarchies.
```
% java -jar semver.jar --excludes **/MyClass; org/**/MyClass; org/**/*Class;
```
### Check
Check compatibility type between two JARs.
```
% java -jar semver.jar --check --base-jar previousJar --new-jar current.jar
BACKWARD_COMPATIBLE_IMPLEMENTER
```
### Infer
Infer JAR version based on a previously versioned JAR.
```
% java -jar semver.jar --infer --base-version 1.0.0 --base-jar previous.jar --new-jar current.jar
1.0.1
```
### Validate
Validate JAR version based on a previously versioned JAR.
```
% java -jar semver.jar --validate --base-version 1.0.0 --base-jar previous.jar --new-version 1.0.1 --new-jar current.jar
true
```
## Maven Enforcer Rule
The enforcer rule offers a rule for checking project's version against a previously released artifact.
### Checking a project's compatibility
In order to check your project's compatibility, you must add the enforcer rule as a dependency to
the maven-enforcer-plugin and then configure the maven-enforcer-plugin to run the rule:
```xml
...
...
...
maven-enforcer-plugin
1.0.1
...
...
org.semver
enforcer-rule
0.9.18
...
...
....
check
verify
enforce
BACKWARD_COMPATIBLE_IMPLEMENTER
...
...
...
...
...
```
Once you have configured your project, maven-enforcer will be able to throw a build error if current version is not backward compatible with last released one.
You can force strict checking (i.e. compatibility type must exactly match specified one):
```xml
...
true
...
```
### Checking a project's version
In order to check your project's version, you must add the enforcer rule as a dependency to
the maven-enforcer-plugin and then configure the maven-enforcer-plugin to run the rule:
```xml
...
...
...
maven-enforcer-plugin
1.0.1
...
...
org.semver
enforcer-rule
0.9.12
...
...
....
check
verify
enforce
...
...
...
...
...
```
Once you have configured your project, maven-enforcer will be able to throw a build error if current version follows semantic versioning principles.
## Dumping details
Dump details of detected changes:
```xml
...
true
...
```
### Checking against a well known version
You can force check with a well known version:
```xml
...
1.0.0
...
```
### Filtering
Both rules allow to filter classes/packages:
```xml
...
org.project.MyClass
org.project.internal
org.project.MyClass
org.project.internal
...
```
## Maven dependency
```xml
org.semver
enforcer-rule
0.9.18
```
## License
Released under [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0.html).