Skip to main content

jiggle_version

Deterministic CLI to discover, check, and bump a project version without importing user code or writing regex. Optional autogit (stage/commit/push). Supports PEP 440 and SemVer. Includes an auto mode that infers bump size from public API changes (__all__).


Why this exists

Version values drift across pyproject.toml, setup.cfg, setup.py, and module files. Many tools import your package or ask you to hand-write regex. This one does neither.


Features

  • Discovery across common sources:

    • pyproject.toml → [project].version (PEP 621) or [tool.setuptools].version
    • setup.cfg → [metadata] version
    • setup.py → static AST of setup(version="...")
    • Python modules → top-level __version__ = "...", plus _version.py, __version__.py, __about__.py, package __init__.py
  • Agreement check (CI-friendly, no writes) with optional git tag validation

  • Bump: major | minor | patch | auto with --scheme pep440|semver

  • Auto mode: diffs the union of __all__ symbols to infer major/minor/patch; persists digest in .jiggle_version.config

  • Autogit: --autogit off|stage|commit|push with templated commit message

  • Git-aware discovery: honors .gitignore, repo excludes, and global gitignore; supports extra ignore paths

  • Zero-import of target project; AST + safe text updates only

  • Deterministic exit codes for automation


Install

pipx install jiggle_version
# or
python -m pip install --user jiggle_version

Python: >=3.8

Runtime deps (runtime or conditional): packaging, tomlkit, pathspec, rich-argparse (help styling), tomli on Python <3.11.


Quick start

# From your project root
jiggle_version check
jiggle_version print
jiggle_version bump --increment patch --scheme pep440 --dry-run
jiggle_version bump --increment auto --autogit commit

Initialize default config:

jiggle_version init

Configuration (pyproject.toml)

[tool.jiggle_version]
scheme = "pep440"            # "pep440" | "semver"
default_increment = "patch"  # "major" | "minor" | "patch" | "auto"
project_root = "."
ignore = ["docs/_build", "dist", ".venv"]  # optional

# Optional autogit defaults
autogit = "off"              # "off" | "stage" | "commit" | "push"
commit_message = "Release: {version}"
allow_dirty = false

Notes:

  • CLI overrides config. Missing CLI args are filled from config.
  • ignore is normalized to a list of relative paths.

Commands

check

Discover versions across sources and verify agreement. No writes.

jiggle_version check [--project-root .] [--ignore path ...] [--git-tag]

--git-tag additionally compares the agreed source version against the most recent git tag reachable from HEAD (via git describe --tags --abbrev=0). A leading v/V is stripped before comparison. Exits 102 on mismatch. Exits 0 (with a note) when no tags exist yet.

print

Print the normalized version if all sources agree.

jiggle_version print

inspect

List all candidate files and run check.

jiggle_version inspect

bump

Compute next version and update all writable sources.

jiggle_version bump \
  [--increment major|minor|patch|auto] \
  [--scheme pep440|semver] \
  [--set X.Y.Z] \
  [--force-write] \
  [--dry-run] \
  [--autogit off|stage|commit|push] \
  [--commit-message "Release: {version}"] \
  [--allow-dirty]

Behavior:

  • If sources disagree, operation fails unless --force-write or --set is provided.
  • --set skips bump logic and writes the explicit version everywhere.

hash-all

Compute and persist API digest used by auto mode.

jiggle_version hash-all
# writes .jiggle_version.config (TOML)

init

Append a default [tool.jiggle_version] section to pyproject.toml.


Auto mode: how it decides

  1. Walk project for __all__ in Python modules (respecting .gitignore + ignore).

  2. Build the set union of exported symbols; compare to last stored set in .jiggle_version.config.

  3. Decide:

    • major if any previously exported symbol was removed
    • minor if new symbols were added (and nothing removed)
    • patch if identical or no __all__ anywhere
  4. After a successful, non–--dry-run bump, the digest is updated.

You can pre-seed the digest with jiggle_version hash-all.


Git behavior

  • No shelling out to git for ignore logic; uses pathspec with:

    • <root>/.gitignore
    • <root>/.git/info/exclude
    • ~/.config/git/ignore or ~/.gitignore
  • check --git-tag calls git describe --tags --abbrev=0 to find the nearest tag and compares it (after stripping a leading v/V) to the agreed source version. Opt-in; existing pipelines are unaffected.

  • Autogit uses subprocess.run(..., check=True):

    • stage → git add <changed files>
    • commit → stage + git commit -m "<message>"
    • push → commit + git push origin <current-branch>
  • Refuses to proceed if repo is dirty and autogit is requested, unless --allow-dirty.


Exit codes (stable for CI)

User / project issues (treated as “expected” for tests):

  • 100 — no version declarations found
  • 102 — discovered versions disagree
  • 103 — git repo dirty and --allow-dirty not set
  • 104 — config not found where required

Tool / unexpected failures:

  • 1 — unexpected error
  • 2 — discovery error (I/O, traversal)
  • 3 — auto-increment analysis error
  • 4 — bump calculation error (invalid version/scheme)
  • 5 — failed to update a file
  • 6 — autogit failed
  • 7 — hash/digest generation failed
  • 8 — argparse error (invalid CLI)

Contract for test runners:

  • Treat >=100 as user error (assertable, not a tool crash).
  • Treat <100 as application failure (potential bug).

Safety model

  • Never imports or executes target project code.
  • Python parsed via ast; setup parsing limited to literal version="...".
  • TOML via tomllib/tomli, INI via configparser, tomlkit used to preserve formatting on write.

Semantics (bumping)

  • PEP 440 (default): increments numeric release segments; drops pre/dev/post markers on standard bump.
  • SemVer: enforces MAJOR.MINOR.PATCH; strips pre-release/build on standard bump. (Flags to preserve/annotate can be added later.)

CLI quality-of-life

  • Typo suggestions for choice arguments (e.g., wrong subcommand/value).
  • Verbose logging: -v → INFO, -vv → DEBUG; or --log-level DEBUG.
  • Rich help text when rich-argparse is available.

CI usage examples (GitHub Actions)

Drift check (no writes):

- run: pipx install jiggle_version
- run: jiggle_version check

Release bump (auto + autogit):

- run: pipx install jiggle_version
- run: jiggle_version hash-all
- run: jiggle_version bump --increment auto --autogit push

Known limitations / non-goals

  • Won’t evaluate dynamic setup.py logic (files, env, computed constants).
  • Only updates known patterns; exotic version locations aren’t modified.
  • Single, project-wide version policy (per-module versioning is out-of-scope for now).

Troubleshooting

  • “No version found”: ensure one of the supported sources exists and is literal.
  • “Versions disagree”: run jiggle_version inspect to see sources; reconcile or use --force-write once.
  • Auto mode always “patch”: ensure you actually export a public API via __all__.
  • Ignored paths not respected: confirm entries in pyproject.toml under [tool.jiggle_version].ignore (list or string), and that .gitignore covers generated trees.

Contributing

  1. Add/adjust unit tests (no tests for logging needed).
  2. Keep exit codes and CLI surfaces stable.
  3. Prefer AST/TOML/INI approaches over regex.
  4. Windows paths: avoid shell=True, prefer Path APIs.

License

MIT. See LICENSE.


Minimal API surface (for importers)

This is a CLI-first tool. Internal modules may change. If you import, prefer:

  • jiggle_version.__about__.__version__
  • Running via python -m jiggle_version

Project Links

Release files for jiggle-version 2.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jiggle-version 2.2.1
File Size Uploaded
jiggle_version-2.2.1.tar.gz 519.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jiggle-version 2.2.1
File Interpreter ABI Platform
jiggle_version-2.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 553.5 kB

Release files / jiggle_version-2.2.1.tar.gz

Download URL jiggle_version-2.2.1.tar.gz
Size 519.2 kB
Tags Source
SHA-256 checksum
How to use checksums
86ed3e74b5d92ebe82eb7b90b52094c4176349b10746724234ad9cc5fbe7fd12
BLAKE2b-256 checksum
How to use checksums
3887ec1e111ad375dd55c4de103686a354b6c63dcb6f61379aa8b57ffe8d206a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 4, 2026.

Transparency log

Release files / jiggle_version-2.2.1-py3-none-any.whl

Download URL jiggle_version-2.2.1-py3-none-any.whl
Size 34.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f6b0df96eb1879b5bc4569a378362f3873fcfe28ac373ddb542fceee37e2bc06
BLAKE2b-256 checksum
How to use checksums
c631543f9d18a07a134046fc9cbffcce26b67bee1b4f91fb08bae3d2d942a9fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.2.1 This release

2 release files

2.2.0

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.77

1 release file

1.0.76

1 release file

1.0.71

1 release file

1.0.70

1 release file

1.0.68

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page