Skip to main content

Language-agnostic version management across project files

Project description

vrzn

Author: Scott Arne Johnson (scott.arne.johnson@gmail.com)

Language-agnostic version management across project files.

Overview

Projects often store version numbers in multiple files: pyproject.toml, __init__.py, CMakeLists.txt, package.json, and others. When these fall out of sync, builds break and releases ship incorrect metadata.

vrzn solves this by letting you declare every file that contains a version number in a single configuration file. It can then read, set, and bump versions across all of them at once, with full PEP 440 support.

Installation

Requires Python 3.10 or later.

pip install vrzn

For YAML config file support:

pip install 'vrzn[yaml]'

Quick Start

Create a vrzn.toml in your project root:

[[locations]]
file = "pyproject.toml"
type = "pyproject-version"

[[locations]]
file = "src/mypackage/__init__.py"
type = "python-dunder"

Check that all version locations are in sync:

$ vrzn get

                       vrzn — version report
╭───────────────────────────┬───────────────────┬─────────┬────────╮
│ File                      │ Location          │ Version │ Status │
├───────────────────────────┼───────────────────┼─────────┼────────┤
│ pyproject.toml            │ pyproject-version │  1.0.0  │   ok   │
├───────────────────────────┼───────────────────┼─────────┼────────┤
│ src/mypackage/__init__.py │ python-dunder     │  1.0.0  │   ok   │
╰───────────────────────────┴───────────────────┴─────────┴────────╯

  Consensus version: 1.0.0
  All version numbers are consistent.

Set a specific version everywhere:

$ vrzn -y set 1.2.0

  Setting version to 1.2.0

                                updated files
╭───────────────────────────┬───────────────────┬─────────┬───────┬─────────╮
│ File                      │ Location          │ Current │  New  │ Result  │
├───────────────────────────┼───────────────────┼─────────┼───────┼─────────┤
│ pyproject.toml            │ pyproject-version │  1.0.0  │ 1.2.0 │ updated │
│ src/mypackage/__init__.py │ python-dunder     │  1.0.0  │ 1.2.0 │ updated │
╰───────────────────────────┴───────────────────┴─────────┴───────┴─────────╯

  All versions set to 1.2.0.

Bump the version:

$ vrzn -y bump patch

  Version bump: 1.2.0 → 1.2.1

                                updated files
╭───────────────────────────┬───────────────────┬─────────┬───────┬─────────╮
│ File                      │ Location          │ Current │  New  │ Result  │
├───────────────────────────┼───────────────────┼─────────┼───────┼─────────┤
│ pyproject.toml            │ pyproject-version │  1.2.0  │ 1.2.1 │ updated │
│ src/mypackage/__init__.py │ python-dunder     │  1.2.0  │ 1.2.1 │ updated │
╰───────────────────────────┴───────────────────┴─────────┴───────┴─────────╯

  Version bumped to 1.2.1.

Preview changes without writing files:

$ vrzn --dry-run bump minor

  Version bump: 1.2.1 → 1.3.0

                                    dry run
╭───────────────────────────┬───────────────────┬─────────┬───────┬──────────────╮
│ File                      │ Location          │ Current │  New  │    Result     │
├───────────────────────────┼───────────────────┼─────────┼───────┼──────────────┤
│ pyproject.toml            │ pyproject-version │  1.2.1  │ 1.3.0 │ would update │
│ src/mypackage/__init__.py │ python-dunder     │  1.2.1  │ 1.3.0 │ would update │
╰───────────────────────────┴───────────────────┴─────────┴───────┴──────────────╯

  Dry run — no files were modified.

Pre-release workflows:

vrzn -y bump patch --pre rc  # 1.0.0 -> 1.0.1rc1
vrzn -y bump pre             # 1.0.1rc1 -> 1.0.1rc2
vrzn -y bump release         # 1.0.1rc2 -> 1.0.1

CLI Reference

Global Options

Global options must be placed before the subcommand (e.g., vrzn --dry-run bump patch).

Option Description
--dry-run Show what would change without writing files.
--yes, -y Skip confirmation prompts.
--quiet, -q Machine-readable output, no tables.
--config, -c PATH Path to config file (overrides discovery).

Commands

vrzn get

Display the current version in all configured files. Prints a table showing each location, its version, and whether it matches the consensus.

With --quiet, prints only the consensus version string.

Exit codes: 0 if all versions agree, 1 if mismatches exist, 2 if no config found.

vrzn set VERSION

Set all version numbers to VERSION. Accepts any PEP 440 version string (e.g., 1.0.0, 1.0.0rc1, 1.0.0.post1). Non-normalized forms are accepted and automatically normalized.

Prompts for confirmation unless --yes or --dry-run is set.

Exit codes: 1 for invalid version format, 2 if no config found.

vrzn bump PART [--pre LABEL]

Bump the version number. PART must be one of: major, minor, patch, pre, release.

Use --pre with a label (alpha, a, beta, b, rc) to enter a pre-release state. Use bump pre to increment an existing pre-release. Use bump release to finalize a pre-release to its stable version.

If versions are out of sync, vrzn warns and uses a consensus version (most common across locations). Prompts for confirmation unless --yes or --dry-run is set.

Exit codes: 1 for errors (no readable version, invalid bump operation), 2 if no config found.

Configuration

vrzn searches up the directory tree for config in this order:

  1. vrzn.toml
  2. vrzn.yaml
  3. vrzn.json
  4. pyproject.toml (under [tool.vrzn])

Built-in Presets

Preset Matches base_only
pyproject-version version = "X.Y.Z" in TOML no
python-dunder __version__ = "X.Y.Z" no
python-version-info __version_info__ = (X, Y, Z) yes
cmake-project project(NAME VERSION X.Y.Z) yes
c-define #define PREFIX_VERSION_MAJOR N yes
cargo-toml version = "X.Y.Z" in Cargo.toml no
package-json "version": "X.Y.Z" in JSON no
maven-pom <version>X.Y.Z</version> no
gradle-version version = 'X.Y.Z' in Gradle no

Presets marked base_only write only the MAJOR.MINOR.PATCH portion, ignoring pre-release or post-release suffixes.

The c-define preset requires a prefix parameter:

[[locations]]
file = "include/mylib.h"
type = "c-define"
prefix = "MYLIB"

Custom Locations

For files that don't match a built-in preset, use custom with explicit regex patterns:

[[locations]]
file = "docs/conf.py"
type = "custom"
label = "Sphinx config"
pattern = '(release\s*=\s*")[^"]+"'
replacement = '\g<1>{version}"'
extract = 'release\s*=\s*"([^"]+)"'

Replacement format variables: {version}, {major}, {minor}, {patch}, {info_tuple}.

Development

pip install --config-settings editable_mode=compat -e ".[dev,yaml]"
pytest

License

MIT License. Copyright (c) 2026 Scott Arne Johnson. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vrzn-0.1.0.tar.gz (23.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vrzn-0.1.0-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

Details for the file vrzn-0.1.0.tar.gz.

File metadata

  • Download URL: vrzn-0.1.0.tar.gz
  • Upload date:
  • Size: 23.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vrzn-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3883a86a542ea251969fc0c20761ed755ececcb5f4c0a839770911725e0b4a64
MD5 3ac508d2d22902d3889cc8d3f926d894
BLAKE2b-256 888bbf5688141050e4672dfa0fd2cba97411001c4b7d1e43859dd711b8119fa8

See more details on using hashes here.

Provenance

The following attestation bundles were made for vrzn-0.1.0.tar.gz:

Publisher: build-wheels.yml on scott-arne/vrzn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vrzn-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vrzn-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vrzn-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3329125650badfa87e93647642122233463f71c4596942aa7db927fc9963fcb0
MD5 6d3b8f82632291b45efad9253fcbc00b
BLAKE2b-256 3bb8e8a5f75f0df600a1628c6a037e7a0b8e35b31ad2c1d92d2ec5a44d80f0b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for vrzn-0.1.0-py3-none-any.whl:

Publisher: build-wheels.yml on scott-arne/vrzn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page