Semver4j is a lightweight Java library that helps you to handle versions. It follows the rules of the semantic versioning specification.
It also provides support for several range checking: node-semver, CocoaPods and Ivy.
Add the dependency to your project:
<dependency>
<groupId>org.semver4j</groupId>
<artifactId>semver4j</artifactId>
<version>5.4.1</version>
</dependency>
Groovy
implementation 'org.semver4j:semver4j:5.4.1'
Kotlin
implementation("org.semver4j:semver4j:5.4.1")
Version v1.0.x
references to original library version v3.1.0
in source repository.
In Semver4j, a version looks like: 1.2.3-beta.4+sha899d8g79f87
.
1
is the major part (required)2
is the minor part (required)3
is the patch part (required)beta
and4
are the pre-release version (optional)sha899d8g79f87
is the build metadata (optional)
You can create Semver
object in number of ways.
Semver version = new Semver("1.2.3-beta.4+sha899d8g79f87");
Semver version = Semver.parse("1.2.3-beta.4+sha899d8g79f87"); // returns correct Semver object
Semver version = Semver.parse("invalid"); // returns null, cannot parse this version
Library can help you to create valid Semver
object when the version is not valid. This aims to provide forgiving
translation from not-semver into semver.
Semver version = Semver.coerce("..1"); // it produces the same result as new Semver("1.0.0")
Semver version = Semver.coerce("invalid"); // returns null, cannot coerce this version
You can check if you're working with a stable version by using isStable()
.
A version is stable if its major number is strictly positive, and it has no pre-release version.
Examples:
// true
new Semver("1.2.3").isStable(); // major is > 0 and has no pre-release version
new Semver("1.2.3+sHa.0nSFGKjkjsdf").isStable(); // major is > 0 and has only build metadata without pre-release version
// false
new Semver("0.1.2").isStable()); // major is < 1
new Semver("0.1.2+sHa.0nSFGKjkjsdf").isStable(); // major is < 1
new Semver("1.2.3-BETA.11+sHa.0nSFGKjkjsdf").isStable(); // major is > 0 but has pre-release version BETA.11
isGreaterThan()
returns true if the version is strictly greater than the other one.
Semver version = new Semver("1.2.3");
version.isGreaterThan("1.2.2"); // true
version.isGreaterThan("1.2.4"); // false
version.isGreaterThan("1.2.3"); // false
isLowerThan()
returns true if the version is strictly lower than the other one.
Semver version = new versionver("1.2.3");
version.isLowerThan("1.2.2"); // false
version.isLowerThan("1.2.4"); // true
version.isLowerThan("1.2.3"); // false
isEqualTo()
returns true if the versions are exactly the same.
Semver version = new Semver("1.2.3+sha123456789");
version.isEqualTo("1.2.3+sha123456789"); // true
version.isEqualTo("1.2.3+shaABCDEFGHI"); // false
isEquivalentTo()
returns true if the versions are the same (does not take the build metadata into account).
Semver version = new Semver("1.2.3+sha123456789");
version.isEquivalentTo("1.2.3+sha123456789"); // true
version.isEquivalentTo("1.2.3+shaABCDEFGHI"); // true
If you want to know what is the main difference between 2 versions, use the diff()
method.
It will return a VersionDiff
enum value among: NONE
, MAJOR
, MINOR
, PATCH
, PRE_RELEASE
, BUILD
.
It will always return the biggest difference.
Semver version = new Semver("1.2.3-beta.4+sha899d8g79f87");
version.diff("1.2.3-beta.4+sha899d8g79f87"); // NONE
version.diff("2.3.4-alpha.5+sha32iddfu987"); // MAJOR
version.diff("1.3.4-alpha.5+sha32iddfu987"); // MINOR
version.diff("1.2.4-alpha.5+sha32iddfu987"); // PATCH
version.diff("1.2.3-alpha.5+sha32iddfu987"); // PRE_RELEASE
version.diff("1.2.3-beta.4+sha32iddfu987"); // BUILD
If you want to check if a version satisfies a range, use the satisfies()
method.
Semver4j
can interpret the following range implementations:
- NPM
- Primitive ranges
<
,<=
,>
,>=
and=
- Hyphen ranges
X.Y.Z - A.B.C
- X-Ranges
1.2.x
,1.X
,1.2.*
and*
- Tilde ranges
~1.2.3
,~1.2
and~1
- Caret ranges
^1.2.3
,^0.2.5
and^0.0.4
- Primitive ranges
- CocaPods
- Optimistic operator
~> 1.0
- Optimistic operator
- Ivy
- Version Range Matcher
[1.0,2.0]
,[1.0,2.0[
,]1.0,2.0]
,]1.0,2.0[
,[1.0,)
,]1.0,)
,(,2.0]
and(,2.0[
- Version Range Matcher
The internal ranges builds ranges using fluent interface.
RangesExpression rangesExpression = equal("1.0.0")
.and(less("2.0.0"))
.or(greaterOrEqual("3.0.0")); // (=1.0.0 and <2.0.0) or >=3.0.0
The Semver
object is immutable. However, it provides a set of methods that will help you create new versions:
withIncMajor()
andwithIncMajor(int increment)
returns aSemver
object with the major part incrementedwithIncMinor()
andwithIncMinor(int increment)
returns aSemver
object with the minor part incrementedwithIncPatch()
andwithIncPatch(int increment)
returns aSemver
object with the patch part incrementedwithClearedPreRelease()
returns aSemver
object with no pre-release versionwithClearedBuild()
returns aSemver
object with no build metadata
You can also use built-in versioning methods such as:
nextMajor()
:1.2.3-beta.4+sha32iddfu987 => 2.0.0
nextMinor()
:1.2.3-beta.4+sha32iddfu987 => 1.3.0
nextPatch()
:1.2.3-beta.4+sha32iddfu987 => 1.2.4
Semver4j
provides an API for programmatically creating Semver
object.
The newly introduced API looks like:
Semver semver = Semver.of()
.withMajor(1)
.withMinor(2)
.withBuild("5bb76cdb")
.toSemver();
And is an equivalent of:
Semver semver = new Semver("1.2.0+5bb76cdb");
Sometimes you want to format Semver
using custom formatters. You can do this using
a format(Function<Semver, String> formatter)
method from the Semver
class:
Semver semver = new Semver("1.2.3-alpha.1+sha.1234");
String customVersion = semver.format(sem -> format("%d:%d:%d", sem.getMajor(), sem.getMinor(), sem.getPatch())); // 1:2:2
There is also a method in the SemverBuilder
called toVersion(Function<Semver, String> formatter)
which behaves
exactly the same.
Any pull request or bug report are welcome! If you have any suggestion about new features, you can open an issue.
Logo created by Tomek Babik @tomekbbk.