Operations
The core library provides composable operations for version manipulation and rendering.
Status Checks
import version.*
val v = "1.2.3-alpha.1".toVersionUnsafe
v.stable // true (major > 0 and not snapshot)
v.snapshot // false
v.preRelease.isDefined // true
// Check via PreRelease extensions
v.preRelease.get.isAlpha // true
v.preRelease.get.isSnapshot // false
Core Extraction
Strip pre-release and metadata:
val v = "1.2.3-alpha.1+build.456".toVersionUnsafe
v.core // Version(1, 2, 3)
Bumping
Core Components
Use next[F] for type-safe bumping. Clears pre-release and metadata:
val v = "1.2.3".toVersionUnsafe
v.next[MajorVersion] // 2.0.0 (resets minor and patch)
v.next[MinorVersion] // 1.3.0 (resets patch)
v.next[PatchNumber] // 1.2.4
// Useful in generic code
def bump[F](v: Version)(using Version.Increment[F]): Version = v.next[F]
Pre-release Classifiers
next[C] also supports versioned pre-release classifiers with precedence-aware semantics:
import version.PreReleaseClassifier.*
val release = "1.2.3".toVersionUnsafe
val alpha = "1.2.3-alpha.1".toVersionUnsafe
val beta = "1.2.3-beta.1".toVersionUnsafe
val snap = "1.2.3-SNAPSHOT".toVersionUnsafe
// Final version → start pre-release cycle
release.next[Alpha] // 1.2.3-alpha.1
// Same classifier → increment number
alpha.next[Alpha] // 1.2.3-alpha.2
// Higher-precedence classifier → advance within cycle
alpha.next[Beta] // 1.2.3-beta.1
alpha.next[ReleaseCandidate] // 1.2.3-rc.1
// Lower-precedence classifier → new patch cycle
beta.next[Alpha] // 1.2.4-alpha.1
// Snapshot (highest) → any versioned = new patch cycle
snap.next[Alpha] // 1.2.4-alpha.1
Note: Snapshot has no Increment instance — use as[Snapshot] instead.
Pre-release Operations
Setting Classifier Directly
as[C] sets the pre-release classifier without precedence logic. Clears build metadata.
val v = "1.2.3".toVersionUnsafe
// With default number (1 for versioned classifiers)
v.as[Alpha] // 1.2.3-alpha.1
v.as[ReleaseCandidate] // 1.2.3-rc.1
v.as[Snapshot] // 1.2.3-SNAPSHOT
// With specific number
v.as[Alpha](5)
// Right(1.2.3-alpha.5)
// Error: snapshot cannot have a number
v.as[Snapshot](1)
// Left(ClassifierNotVersioned(Snapshot))
Removing Pre-release
Use core or copy to remove pre-release:
val v = "1.2.3-alpha.1".toVersionUnsafe
v.core // 1.2.3 (also removes metadata)
v.copy(preRelease = None) // 1.2.3 (preserves metadata)
Build Metadata
Use copy for metadata operations:
val v = "1.2.3".toVersionUnsafe
// Setting metadata
v.copy(metadata = Some(Metadata(List("build", "456"))))
// 1.2.3+build.456
// Removing metadata
val vMeta = "1.2.3+build.456".toVersionUnsafe
vMeta.copy(metadata = None) // 1.2.3
Comparison
Versions implement Ordered[Version]:
val a = "1.0.0".toVersionUnsafe
val b = "2.0.0".toVersionUnsafe
a < b // true
a.compare(b) // -1
List(b, a).sorted // List(a, b)
Rendering
The version.Version.Show type class controls how versions are rendered to strings.
Built-in Instances
| Instance | Behaviour | Example Output |
|---|---|---|
Version.Show.Standard |
Core + pre-release, excludes metadata | 1.2.3-SNAPSHOT |
Version.Show.Extended |
Includes metadata, SHA truncated to 7 | 1.2.3-SNAPSHOT+sha1234567 |
Version.Show.Full |
Complete metadata without truncation | 1.2.3-SNAPSHOT+sha1234567890abcdef |
Usage
Contextual Usage
Override the default Show instance in scope:
import version.*
given Version.Show = Version.Show.Extended
val v = "1.2.3-SNAPSHOT+sha1234567890abcdef".toVersionUnsafe
v.show // "1.2.3-SNAPSHOT+sha1234567"
Custom Show Instances
Implement version.Version.Show for full control:
object MinimalShow extends Version.Show:
extension (v: Version)
def show: String =
val core = s"${v.major.value}.${v.minor.value}.${v.patch.value}"
if v.snapshot then s"$core-dev" else core
Output: 1.2.3-dev
In this article