Version Manager¶
The VersionManager class provides utilities for semantic version management and calculations following SemVer 2.0.0 standards.
Overview¶
The Version Manager is a utility class responsible for: - Parsing and validating semantic version strings - Calculating next versions with different bump types - Comparing versions for ordering - Supporting pre-release labels (SNAPSHOT, M, RC)
Class Reference¶
VersionManager¶
A static utility class for semantic versioning operations. All methods are static and don't require instantiation.
Methods¶
parse_bump_type()¶
Parse bump type from string or enum value.
Parameters:
- bump_type (VersionBump | str | None): VersionBump enum or string ("major", "minor", "patch")
Returns:
- Optional[VersionBump]: Parsed VersionBump enum or None if invalid
Example:
from prompt_versioner.core.version_manager import VersionManager
from prompt_versioner.core.enums import VersionBump
# Parse from string
bump = VersionManager.parse_bump_type("patch") # → VersionBump.PATCH
bump = VersionManager.parse_bump_type("MAJOR") # → VersionBump.MAJOR
# Pass through enum
bump = VersionManager.parse_bump_type(VersionBump.MINOR) # → VersionBump.MINOR
parse_pre_label()¶
@staticmethod
def parse_pre_label(pre_label: PreReleaseLabel | str | None) -> Optional[PreReleaseLabel]
Parse pre-release label from string or enum value.
Parameters:
- pre_label (PreReleaseLabel | str | None): PreReleaseLabel enum or string
Returns:
- Optional[PreReleaseLabel]: Parsed PreReleaseLabel enum or None if invalid
Example:
# Parse from string
label = VersionManager.parse_pre_label("snapshot") # → PreReleaseLabel.SNAPSHOT
label = VersionManager.parse_pre_label("RC") # → PreReleaseLabel.RC
label = VersionManager.parse_pre_label("m") # → PreReleaseLabel.MILESTONE
label = VersionManager.parse_pre_label("stable") # → PreReleaseLabel.STABLE
parse_version()¶
Parse a semantic version string into its components.
Parameters:
- version_string (str): Version string (e.g., "1.2.3-RC.1")
Returns:
- Optional[Dict]: Dictionary with parsed components or None if invalid
Components:
- major (int): Major version number
- minor (int): Minor version number
- patch (int): Patch version number
- pre_label (str): Pre-release label (if any)
- pre_number (int): Pre-release number (if any)
Example:
# Parse different version formats
parsed = VersionManager.parse_version("1.2.3")
# → {"major": 1, "minor": 2, "patch": 3, "pre_label": None, "pre_number": None}
parsed = VersionManager.parse_version("2.0.0-RC.1")
# → {"major": 2, "minor": 0, "patch": 0, "pre_label": "RC", "pre_number": 1}
parsed = VersionManager.parse_version("1.5.0-SNAPSHOT")
# → {"major": 1, "minor": 5, "patch": 0, "pre_label": "SNAPSHOT", "pre_number": None}
format_version()¶
@staticmethod
def format_version(
major: int,
minor: int,
patch: int,
pre_label: Optional[PreReleaseLabel] = None,
pre_number: Optional[int] = None,
) -> str
Format version components into a semantic version string.
Parameters:
- major (int): Major version number
- minor (int): Minor version number
- patch (int): Patch version number
- pre_label (Optional[PreReleaseLabel]): Pre-release label
- pre_number (Optional[int]): Pre-release number
Returns:
- str: Formatted version string
Example:
from prompt_versioner.core.enums import PreReleaseLabel
# Basic version
version = VersionManager.format_version(1, 2, 3) # → "1.2.3"
# With pre-release label
version = VersionManager.format_version(1, 0, 0, PreReleaseLabel.RC, 1) # → "1.0.0-RC.1"
# Snapshot version
version = VersionManager.format_version(2, 1, 0, PreReleaseLabel.SNAPSHOT) # → "2.1.0-SNAPSHOT"
calculate_next_version()¶
@staticmethod
def calculate_next_version(
current_version: Optional[str],
bump_type: VersionBump,
pre_label: Optional[PreReleaseLabel] = None,
pre_number: Optional[int] = None,
) -> str
Calculate the next semantic version following SemVer 2.0.0 rules.
Parameters:
- current_version (Optional[str]): Current version string or None for first version
- bump_type (VersionBump): Type of version bump (MAJOR, MINOR, PATCH)
- pre_label (Optional[PreReleaseLabel]): Pre-release label for new version
- pre_number (Optional[int]): Pre-release number
Returns:
- str: Next version string
Example:
from prompt_versioner.core.enums import VersionBump, PreReleaseLabel
# First version
next_ver = VersionManager.calculate_next_version(None, VersionBump.PATCH)
# → "1.0.0"
# Increment patch
next_ver = VersionManager.calculate_next_version("1.0.0", VersionBump.PATCH)
# → "1.0.1"
# Minor with pre-release
next_ver = VersionManager.calculate_next_version(
"1.0.0",
VersionBump.MINOR,
PreReleaseLabel.SNAPSHOT
)
# → "1.1.0-SNAPSHOT"
# Release candidate
next_ver = VersionManager.calculate_next_version(
"1.0.0",
VersionBump.MINOR,
PreReleaseLabel.RC,
1
)
# → "1.1.0-RC.1"
# Promote RC to stable
next_ver = VersionManager.calculate_next_version(
"1.0.0-RC.2",
VersionBump.PATCH,
PreReleaseLabel.STABLE
)
# → "1.0.0"
is_valid_semver()¶
Check if a version string is valid SemVer format.
Parameters:
- version_string (str): Version string to validate
Returns:
- bool: True if valid semantic version
Example:
# Valid versions
VersionManager.is_valid_semver("1.0.0") # → True
VersionManager.is_valid_semver("2.1.3-RC.1") # → True
VersionManager.is_valid_semver("0.0.1-SNAPSHOT") # → True
# Invalid versions
VersionManager.is_valid_semver("1.0") # → False
VersionManager.is_valid_semver("v1.0.0") # → False
VersionManager.is_valid_semver("1.0.0.1") # → False
compare_versions()¶
Compare two semantic versions according to SemVer precedence rules.
Parameters:
- version1 (str): First version to compare
- version2 (str): Second version to compare
Returns:
- int: -1 if version1 < version2, 0 if equal, 1 if version1 > version2
Precedence Rules: 1. Major.minor.patch numbers are compared numerically 2. Stable versions have higher precedence than pre-release 3. Pre-release precedence: SNAPSHOT < M < RC 4. Pre-release numbers are compared numerically
Example:
# Basic comparison
VersionManager.compare_versions("1.0.0", "1.0.1") # → -1
VersionManager.compare_versions("2.0.0", "1.9.9") # → 1
VersionManager.compare_versions("1.0.0", "1.0.0") # → 0
# Pre-release comparison
VersionManager.compare_versions("1.0.0-RC.1", "1.0.0") # → -1 (stable > pre-release)
VersionManager.compare_versions("1.0.0-M.1", "1.0.0-RC.1") # → -1 (M < RC)
VersionManager.compare_versions("1.0.0-RC.1", "1.0.0-RC.2") # → -1 (RC.1 < RC.2)
Version Bump Types¶
The Version Manager works with the VersionBump enum for semantic versioning:
VersionBump Enum¶
from prompt_versioner.core.enums import VersionBump
class VersionBump(Enum):
MAJOR = "major" # Breaking changes (non-backward compatible)
MINOR = "minor" # New features (backward compatible)
PATCH = "patch" # Bug fixes (backward compatible)
Usage Examples¶
# Major version bump - breaking changes
next_version = VersionManager.calculate_next_version("1.5.2", VersionBump.MAJOR)
# → "2.0.0"
# Minor version bump - new features
next_version = VersionManager.calculate_next_version("1.5.2", VersionBump.MINOR)
# → "1.6.0"
# Patch version bump - bug fixes
next_version = VersionManager.calculate_next_version("1.5.2", VersionBump.PATCH)
# → "1.5.3"
Pre-Release Labels¶
The Version Manager supports pre-release versioning with labels:
PreReleaseLabel Enum¶
from prompt_versioner.core.enums import PreReleaseLabel
class PreReleaseLabel(Enum):
SNAPSHOT = "SNAPSHOT" # Development version
MILESTONE = "M" # Milestone version
RC = "RC" # Release Candidate
STABLE = None # Stable release (no label)
Pre-Release Workflows¶
# Development snapshot
dev_version = VersionManager.calculate_next_version(
"1.0.0",
VersionBump.MINOR,
PreReleaseLabel.SNAPSHOT
)
# → "1.1.0-SNAPSHOT"
# Milestone releases
milestone = VersionManager.calculate_next_version(
"1.1.0-SNAPSHOT",
VersionBump.PATCH,
PreReleaseLabel.MILESTONE,
1
)
# → "1.1.0-M.1"
# Release candidate
rc = VersionManager.calculate_next_version(
"1.1.0-M.1",
VersionBump.PATCH,
PreReleaseLabel.RC,
1
)
# → "1.1.0-RC.1"
# Final stable release
stable = VersionManager.calculate_next_version(
"1.1.0-RC.1",
VersionBump.PATCH,
PreReleaseLabel.STABLE
)
# → "1.1.0"
Integration with PromptVersioner¶
The Version Manager is used internally by the main PromptVersioner class:
from prompt_versioner import PromptVersioner, VersionBump
pv = PromptVersioner("my-project")
# When you call save_version, VersionManager calculates the next version
version = pv.save_version(
name="my_prompt",
system_prompt="You are a helpful assistant.",
user_prompt="Help with: {request}",
bump_type=VersionBump.MAJOR # VersionManager calculates "1.0.0"
)
Error Handling¶
The Version Manager handles invalid inputs gracefully:
# Invalid version strings return None
parsed = VersionManager.parse_version("invalid") # → None
# Invalid bump types return None
bump = VersionManager.parse_bump_type("invalid") # → None
# Version comparison falls back to string comparison for invalid versions
result = VersionManager.compare_versions("invalid1", "invalid2") # → string comparison
See Also¶
PromptVersioner- Main versioner class that uses VersionManagerVersionBump- Version increment typesPreReleaseLabel- Pre-release label types