semver

package
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 28, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package semver provides semantic version parsing, manipulation, and persistence.

This package implements the Semantic Versioning 2.0.0 specification (https://semver.org/) for parsing and incrementing semantic versions. It includes file-based persistence and git tag integration for automatic version initialization.

Version Format

A semantic version consists of:

  • Major: Incremented for incompatible API changes
  • Minor: Incremented for backwards-compatible functionality additions
  • Patch: Incremented for backwards-compatible bug fixes
  • PreRelease: Optional pre-release label (e.g., "alpha.1", "rc.2")
  • Build: Optional build metadata (e.g., "build.123", "sha.abc123")

Examples of valid version strings:

1.0.0
v1.2.3
1.0.0-alpha
1.0.0-alpha.1
1.0.0+build.123
1.0.0-beta.2+build.456

Basic Usage

Parse a version string:

v, err := semver.ParseVersion("1.2.3-alpha.1")
if err != nil {
    log.Fatal(err)
}
fmt.Println(v.Major, v.Minor, v.Patch) // 1 2 3

Bump a version:

v, _ := semver.ParseVersion("1.2.3")
v2, _ := semver.BumpByLabel(v, "minor")
fmt.Println(v2) // 1.3.0

Read and write version files:

v, err := semver.ReadVersion(".version")
semver.SaveVersion(".version", v)

Thread Safety

The parsing functions (ParseVersion, BumpByLabel, BumpNext, etc.) are safe for concurrent use. File operations should be synchronized by the caller if used concurrently.

Index

Constants

View Source
const VersionFilePerm = core.PermOwnerRW

VersionFilePerm defines secure file permissions for version files (owner read/write only). References core.PermOwnerRW for consistency across the codebase.

Variables

View Source
var (

	// BumpNextFunc is a function variable for performing heuristic-based version bumps.
	// It defaults to BumpNext but can be overridden in tests to simulate errors.
	BumpNextFunc = BumpNext

	// BumpByLabelFunc is a function variable for bumping a version using an explicit label (patch, minor, major).
	// It defaults to BumpByLabel but can be overridden in tests to simulate errors.
	BumpByLabelFunc = BumpByLabel
)

Functions

func IncrementPreRelease

func IncrementPreRelease(current, base string) string

IncrementPreRelease increments the numeric suffix of a pre-release label. Preserves the original separator style: - "rc.1" -> "rc.2" (dot separator) - "rc-1" -> "rc-2" (dash separator) - "rc1" -> "rc2" (no separator) - "rc" -> "rc.1" (no number, defaults to dot) If current doesn't match base, returns base.1.

func InitializeVersionFileWithFeedback

func InitializeVersionFileWithFeedback(path string) (created bool, err error)

InitializeVersionFileWithFeedback initializes the version file and returns whether a new file was created. This function uses the legacy InitializeVersionFileFunc for backward compatibility. For better testability, use VersionManager.InitializeWithFeedback() instead.

func SaveVersion

func SaveVersion(path string, version SemVersion) error

SaveVersion writes a SemVersion to the given file path. This is a convenience function that uses the default VersionManager with context.Background(). For better testability and context control, use VersionManager.Save() instead.

func SetDefaultManager

func SetDefaultManager(m *VersionManager) func()

SetDefaultManager allows tests to inject a custom manager. Returns a function to restore the original manager.

func UpdatePreRelease

func UpdatePreRelease(path string, label string, meta string, preserve bool) error

UpdatePreRelease updates only the pre-release portion of the version. If label is provided, it switches to that label (starting at .1). If label is empty, it increments the existing pre-release number. This is a convenience function that uses the default VersionManager with context.Background(). For better testability and context control, use VersionManager.UpdatePreRelease() instead.

func UpdateVersion

func UpdateVersion(path string, bumpType string, pre string, meta string, preserve bool) error

UpdateVersion updates the semantic version in the given file based on the bump type (patch, minor, major), and optionally sets the pre-release and build metadata strings. If preserve is true and meta is empty, existing build metadata is retained. This is a convenience function that uses the default VersionManager with context.Background(). For better testability and context control, use VersionManager.Update() instead.

Types

type GitTagReader

type GitTagReader interface {
	// DescribeTags returns the most recent tag, or an error if none exists.
	DescribeTags(ctx context.Context) (string, error)
}

GitTagReader abstracts git tag reading for testability.

type MockGitTagReader

type MockGitTagReader struct {
	Tag string
	Err error
}

MockGitTagReader is a test helper for mocking git tag reading.

func (*MockGitTagReader) DescribeTags

func (m *MockGitTagReader) DescribeTags(ctx context.Context) (string, error)

type SemVersion

type SemVersion struct {
	Major      int
	Minor      int
	Patch      int
	PreRelease string
	Build      string
}

SemVersion represents a semantic version (major.minor.patch-preRelease+build).

func BumpByLabel

func BumpByLabel(v SemVersion, label string) (SemVersion, error)

BumpByLabel bumps the version using an explicit label.

Supported labels:

  • "patch": increments patch (1.2.3 -> 1.2.4)
  • "minor": increments minor, resets patch (1.2.3 -> 1.3.0)
  • "major": increments major, resets minor and patch (1.2.3 -> 2.0.0)

Returns an error if label is not one of: patch, minor, major.

func BumpNext

func BumpNext(v SemVersion) (SemVersion, error)

BumpNext applies heuristic-based smart bump logic. - If it's a pre-release (e.g., alpha.1, rc.1), it promotes to final version. - If it's a final release, it bumps patch by default.

func ParseVersion

func ParseVersion(s string) (SemVersion, error)

ParseVersion parses a semantic version string and returns a SemVersion.

Supported formats:

  • "1.2.3" (basic version)
  • "v1.2.3" (with optional v prefix)
  • "1.2.3-alpha.1" (with pre-release identifier)
  • "1.2.3+build.123" (with build metadata)
  • "1.2.3-rc.1+build.456" (with both)

Returns errInvalidVersion (wrapped) when:

  • Input exceeds maxVersionLength (128 characters)
  • Format doesn't match major.minor.patch pattern
  • Major, minor, or patch cannot be parsed as integers

func ReadVersion

func ReadVersion(path string) (SemVersion, error)

ReadVersion reads a version string from the given file and parses it into a SemVersion. This is a convenience function that uses the default VersionManager with context.Background(). For better testability and context control, use VersionManager.Read() instead.

func (SemVersion) Compare added in v0.10.0

func (v SemVersion) Compare(other SemVersion) int

Compare compares two semantic versions. It returns -1 if v < other, 0 if v == other, and +1 if v > other. Pre-release versions have lower precedence than the associated normal version (e.g., 1.0.0-alpha < 1.0.0). Build metadata is ignored for comparison purposes.

func (SemVersion) String

func (v SemVersion) String() string

String returns the string representation of the semantic version.

type VersionManager

type VersionManager struct {
	// contains filtered or unexported fields
}

VersionManager handles version file operations with injected dependencies. This enables proper testing without global state mutation.

func DefaultVersionManager

func DefaultVersionManager() *VersionManager

DefaultVersionManager returns a VersionManager using real OS and git.

func NewVersionManager

func NewVersionManager(fs core.FileSystem, git GitTagReader) *VersionManager

NewVersionManager creates a VersionManager with the given dependencies.

func (*VersionManager) Initialize

func (m *VersionManager) Initialize(ctx context.Context, path string) error

Initialize creates a version file if it doesn't exist. It tries to use the latest git tag, or falls back to 0.1.0.

func (*VersionManager) InitializeWithFeedback

func (m *VersionManager) InitializeWithFeedback(ctx context.Context, path string) (created bool, err error)

InitializeWithFeedback initializes the version file and returns whether it was created.

func (*VersionManager) Read

func (m *VersionManager) Read(ctx context.Context, path string) (SemVersion, error)

Read reads a version from the given path.

Returns an error if:

  • The file cannot be read (not found, permission denied, etc.)
  • The file content is not a valid semantic version

func (*VersionManager) Save

func (m *VersionManager) Save(ctx context.Context, path string, version SemVersion) error

Save writes a version to the given path. Creates parent directories if they don't exist.

Returns an error if:

  • Parent directory cannot be created
  • File cannot be written (permission denied, disk full, etc.)

func (*VersionManager) Update

func (m *VersionManager) Update(ctx context.Context, path string, bumpType string, pre string, meta string, preserve bool) error

Update reads, bumps, and saves the version.

Parameters:

  • bumpType: one of "patch", "minor", "major"
  • pre: pre-release label to set (empty to clear)
  • meta: build metadata to set (empty to clear unless preserve is true)
  • preserve: if true, keeps existing build metadata when meta is empty

Returns an error if:

  • Version file cannot be read or parsed
  • bumpType is not one of: patch, minor, major
  • Version file cannot be saved

func (*VersionManager) UpdatePreRelease

func (m *VersionManager) UpdatePreRelease(ctx context.Context, path string, label string, meta string, preserve bool) error

UpdatePreRelease updates only the pre-release portion of the version.

Behavior:

  • If label is provided, switches to that label (e.g., "alpha" -> "alpha.1")
  • If label is empty, increments the existing pre-release number

Parameters:

  • label: new pre-release label, or empty to increment existing
  • meta: build metadata to set (empty to clear unless preserve is true)
  • preserve: if true, keeps existing build metadata when meta is empty

Returns an error if:

  • Version file cannot be read or parsed
  • label is empty and current version has no pre-release
  • Version file cannot be saved

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL