bumpver

2025.1131 · active · verified Wed Apr 15

Bumpver is a Python library and command-line tool designed for automatic versioning of project files. It supports various versioning schemes, including Semantic Versioning (SemVer) and Calendar Versioning (CalVer), and works with plain text files, making it suitable for any project. It integrates optionally with Git or Mercurial to manage version tags and commits. The current version is 2025.1131. The project has an active release cadence, with updates often several times a year, addressing bug fixes and adding new features.

Warnings

Install

Quickstart

The primary way to use `bumpver` is via its Command Line Interface (CLI). This quickstart demonstrates how to initialize `bumpver` configuration in `pyproject.toml` and then update the project's version across specified files using the `bumpver update` command. The `--dry` flag is useful for previewing changes before applying them.

import os
import subprocess

def setup_project():
    # Simulate project structure
    os.makedirs('my_project', exist_ok=True)
    os.chdir('my_project')
    with open('pyproject.toml', 'w') as f:
        f.write("""
[tool.bumpver]
current_version = "2024.1.0"
version_pattern = "YYYY.MINOR.PATCH"

[tool.bumpver.file_patterns]
"src/__init__.py" = [
    '^__version__ = "{version}"$',
]
"README.md" = [
    'Current Version: {version}',
]
"""
        )
    os.makedirs('src', exist_ok=True)
    with open('src/__init__.py', 'w') as f:
        f.write('__version__ = "2024.1.0"\n')
    with open('README.md', 'w') as f:
        f.write('My Project\n\nCurrent Version: 2024.1.0\n')

    # Initialize bumpver config if it doesn't exist (optional, but good practice)
    try:
        subprocess.run(["bumpver", "init"], check=True, capture_output=True)
        print("bumpver init successful.")
    except subprocess.CalledProcessError as e:
        print(f"bumpver init failed: {e.stderr.decode()}")

def run_bumpver_update():
    print("\n--- Running bumpver update --patch --dry ---")
    try:
        result = subprocess.run(["bumpver", "update", "--patch", "--dry"], check=True, capture_output=True)
        print(result.stdout.decode())
    except subprocess.CalledProcessError as e:
        print(f"bumpver update failed: {e.stderr.decode()}")

    print("\n--- Verifying file contents (dry run means no actual changes) ---")
    with open('src/__init__.py', 'r') as f:
        print(f"src/__init__.py: {f.read().strip()}")
    with open('README.md', 'r') as f:
        print(f"README.md: {f.read().strip()}")

    print("\n--- Running actual bumpver update --patch ---")
    try:
        result = subprocess.run(["bumpver", "update", "--patch"], check=True, capture_output=True)
        print(result.stdout.decode())
    except subprocess.CalledProcessError as e:
        print(f"bumpver update failed: {e.stderr.decode()}")

    print("\n--- Verifying actual file contents ---")
    with open('src/__init__.py', 'r') as f:
        print(f"src/__init__.py: {f.read().strip()}")
    with open('README.md', 'r') as f:
        print(f"README.md: {f.read().strip()}")

if __name__ == '__main__':
    original_dir = os.getcwd()
    try:
        setup_project()
        run_bumpver_update()
    finally:
        os.chdir(original_dir)
        # Clean up created directory if necessary (omitted for simplicity in quickstart)

view raw JSON →