⬆️ Bump2version
bump2versionis a multi-language version bumper written entirely in 100% safe Rust, withno_stdsupport and native Python and Node.js bindings 🗿.
| 🦀 Rust | 🐍 Python | 🟩 Node.js |
|---|---|---|
cargo add bump2version |
pip install bump-rs |
npm install bump2version |
| Documentation | Read PYTHON.md | Read NODE.md |
🤔 What does this crate provide?
bump2version automates semantic version management for any project regardless of language. It:
- Parses version strings using a fully configurable regex (default: semver
major.minor.patch). - Bumps any named component (
major,minor,patch, or custom cyclic stages). - Rewrites version occurrences across multiple files, including multiline CHANGELOG patterns, using
(?ms)DOTALL + MULTILINE semantics identical to Python'sre.MULTILINE | re.DOTALL. - Commits and tags via 100% pure
gix(gitoxide); zero subprocess calls, zeroweb-flowghost-author bugs. - Reads author identity from the local git config.
🦀 Rust
The Rust crate is available on crates.io. For a complete API reference, installation guide, and worked examples, visit the Rust Usage Guide.
The crate ships the following Cargo features:
| Feature | Default | Description |
|---|---|---|
std |
✅ | File I/O, git integration, regex stdlib cache |
cli |
❌ | Standalone bump2version binary via clap |
python |
❌ | Python extension module via PyO3/maturin |
node |
❌ | Node.js native add-on via napi-rs |
Quick Start
[dependencies]
bump2version = "0.2.0"
use bump2version::{config::BumpConfig, version::{parse_version, bump_version, serialize_version}};
fn main() {
let cfg = BumpConfig::default();
let v = parse_version("1.2.3", &cfg).unwrap();
let v2 = bump_version(&v, "patch", &cfg).unwrap();
println!("{}", serialize_version(&v2, &cfg)); // 1.2.4
}
no_std Support
Core modules (config, version, files, error) compile in no_std + alloc:
# no_std (alloc required by the target):
bump2version = { version = "0.2.0", default-features = false }
| Module | no_std+alloc |
std |
|---|---|---|
config |
✅ | ✅ |
version |
✅ | ✅ |
files |
✅ | ✅ |
error |
✅ | ✅ |
git |
❌ | ✅ |
| CLI | ❌ | ✅ |
| Python / Node.js | ❌ | ✅ |
🐍 Python
The Python bindings are published to PyPI as bump-rs and can be installed with pip install bump-rs.
Built with maturin, pre-compiled wheels for CPython 3.12+.
For installation instructions, full method signatures, and examples, read the Python Usage Guide.
pip install bump-rs
from bump_rs import bump_version, apply_file_change, BumpConfig
print(bump_version("1.2.3", "patch")) # "1.2.4"
print(bump_version("1.2.3", "minor")) # "1.3.0"
print(bump_version("1.2.3", "major")) # "2.0.0"
content = 'version = "1.0.0"\n'
print(apply_file_change(content, "1.0.0", "1.0.1"))
# 'version = "1.0.1"\n'
# Multiline CHANGELOG pattern
content = "## 1.0.0\nRelease notes\n\n## 0.9.0\nOld notes\n"
updated = apply_file_change(
content,
current_version="1.0.0",
new_version="1.0.1",
search="## {current_version}\nRelease notes",
replace="## {new_version}\nRelease notes",
)
print(updated) # "## 1.0.1\nRelease notes\n\n## 0.9.0\nOld notes\n"
# Custom parse/serialize config
cfg = BumpConfig(parse=r"(?P<major>\d+)\.(?P<minor>\d+)", serialize="{major}.{minor}")
print(bump_version("2.0", "minor", config=cfg)) # "2.1"
🟩 Node.js
The Node.js bindings are published to npm as bump2version and can be installed with npm install bump2version.
Built with napi-rs, pre-compiled .node add-on.
For installation instructions, TypeScript type definitions, and examples, read the Node.js Usage Guide.
npm install bump2version
const { bumpVersion, applyFileChange } = require("bump2version");
console.log(bumpVersion("1.2.3", "patch")); // '1.2.4'
console.log(bumpVersion("1.2.3", "minor")); // '1.3.0'
💻 Command-line interface
cargo install bump2version --features rust-binary
bump2version --bump patch # 1.0.0 → 1.0.1
bump2version --bump minor # 1.0.0 → 1.1.0
bump2version --bump major # 1.0.0 → 2.0.0
| Option | Description |
|---|---|
--config-file |
Config file path (default: .bumpversion.toml) |
--current-version |
Override current version |
--bump |
Component: major, minor, patch |
--parse |
Parse regex override |
--serialize |
Serialize format override |
--dry-run / -n |
Simulate without writing files |
--new-version |
Explicit new version |
--commit / --tag |
Git commit + tag |
⚙️ Configuration File (.bumpversion.toml)
[bumpversion]
current_version = "1.0.0"
commit = true
tag = true
[bumpversion:file:Cargo.toml]
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'
[bumpversion:file:CHANGELOG.md]
search = """
## {current_version}
Release notes line 1
Release notes line 2"""
replace = """
## {new_version}
Release notes line 1
Release notes line 2"""
🔒 Safety
This crate enforces a zero-unsafe policy via #![forbid(unsafe_code)] at the crate root (except the Node.js FFI layer which requires unsafe for napi-rs interop). Every byte of the implementation, config parsing, regex matching, version bumping, git object creation, is written in safe Rust. The compiler will reject any future unsafe block introduced into the safe portions.
📊 Benchmarks
Rust (cargo bench)
Run with cargo bench. Results on x86-64 Linux (rustc stable):
cargo bench output
| Benchmark | Time |
|---|---|
config_parse/minimal |
~12 µs |
config_parse/full_with_parts |
~18 µs |
version_parse/1.0.0 |
~439 µs |
version_bump/patch |
~13.5 µs |
version_bump/minor |
~14.1 µs |
version_bump/major |
~6.0 µs |
file_replace/100 lines |
~247 µs |
file_replace/1 000 lines |
~1.35 ms |
file_replace/10 000 lines |
~14.4 ms |
multiline_replace (CHANGELOG) |
~87 µs |
Python Nano-Benchmarks (benchmarks/benchmark.py)
Times measured via 3-sigma filtered timeit (CPython 3.12, x86-64 Linux). Run with:
pip install bump-rs bumpversion
python benchmarks/benchmark.py
Version Bumping: full round-trip (parse + bump + serialize)
| Library | patch | minor | major |
|---|---|---|---|
bump-rs (Rust, Arc<Regex> cache) |
~57 µs | ~54 µs | ~53 µs |
bump-my-version (Python library) |
~79 µs | ~95 µs | ~72 µs |
Pure Python (re.compile + int()) |
~3.6 µs | ~2.2 µs | ~2.2 µs |
bump-my-version CLI (subprocess) |
~585 ms | ~585 ms | ~585 ms |
bump-rs is 1.4-1.8× faster than bump-my-version's Python library and ~10 000× faster than the CLI.
File Search/Replace
| Library | Single-line | Multiline CHANGELOG |
|---|---|---|
| bump-rs (Rust, cached) | ~65 µs | ~104 µs |
Pure Python re.sub |
~1.7 µs | ~1.3 µs |
When bump-rs wins:
- vs bump-my-version library: 1.4-1.8× faster version bumping, correct multiline pattern semantics.
- vs bump-my-version CLI: ~10 000× faster, no subprocess startup.
- Thread safety:
#![forbid(unsafe_code)]+ no GIL constraint → scales across threads. - Full pipeline: config + bump + git commit entirely in safe Rust.
When pure Python wins:
- Single in-memory arithmetic on a tiny string where ~50 µs PyO3 FFI overhead dominates: use
bump_rsin batch or for full-pipeline work.
📚 Further Reading
- Semantic Versioning 2.0.0: the canonical version scheme.
- bump-my-version: the Python tool this crate is feature-parity with.
- gitoxide (gix): the pure-Rust git implementation powering our git integration.
- PyO3: Rust ↔ Python FFI framework.
- napi-rs: Rust ↔ Node.js FFI framework.
📄 License
Licensed under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bump_rs-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: bump_rs-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 515.2 kB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3c7f45a8059edfbb28569180860ceceab624d84fd3faf7c40a1431923063efc
|
|
| MD5 |
2a73d6ba176e6fb399efd169dcf155c6
|
|
| BLAKE2b-256 |
85018ed25d8852241457bd7dec29dc0cf3f2ae20bb8f47b97de7f9c78c05fab9
|