feat(version): append +dev suffix for non-release builds#99
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces dynamic versioning for source checkouts by appending PEP 440 local-version suffixes derived from git metadata. It also modifies the version parsing logic in the doctor module to correctly handle these suffixes during version comparisons and adds a comprehensive test suite. Feedback suggests enhancing the tag detection logic to support both 'v'-prefixed and non-prefixed git tags.
| tag_prefix = f"v{base}" | ||
| # Exactly on the release tag with a clean tree -- no suffix needed. | ||
| if desc == tag_prefix: | ||
| return "" | ||
| # On the release tag with uncommitted changes. | ||
| if desc == f"{tag_prefix}.dirty": | ||
| return "+dirty" | ||
| # Past the release tag: "v0.6.3-2-gabc1234[.dirty]" -> "+dev.2.gabc1234[.dirty]" | ||
| if desc.startswith(f"{tag_prefix}-"): | ||
| rest = desc[len(tag_prefix) + 1 :] | ||
| return f"+dev.{rest.replace('-', '.')}" | ||
| # No reachable matching tag (shallow clone, different tag, etc.) -- | ||
| # fall back to whatever git describe returned, normalized for PEP 440. | ||
| return f"+dev.{desc.replace('-', '.')}" |
There was a problem hiding this comment.
The current implementation assumes that git tags always have a v prefix (e.g., v0.6.3). While common, some repositories use tags without the prefix (e.g., 0.6.3). Making this check more robust by supporting both formats ensures the version string remains clean even if the tagging convention changes or differs from the assumption.
| tag_prefix = f"v{base}" | |
| # Exactly on the release tag with a clean tree -- no suffix needed. | |
| if desc == tag_prefix: | |
| return "" | |
| # On the release tag with uncommitted changes. | |
| if desc == f"{tag_prefix}.dirty": | |
| return "+dirty" | |
| # Past the release tag: "v0.6.3-2-gabc1234[.dirty]" -> "+dev.2.gabc1234[.dirty]" | |
| if desc.startswith(f"{tag_prefix}-"): | |
| rest = desc[len(tag_prefix) + 1 :] | |
| return f"+dev.{rest.replace('-', '.')}" | |
| # No reachable matching tag (shallow clone, different tag, etc.) -- | |
| # fall back to whatever git describe returned, normalized for PEP 440. | |
| return f"+dev.{desc.replace('-', '.')}" | |
| # Handle both 'v1.2.3' and '1.2.3' tag formats | |
| for prefix in (f"v{base}", base): | |
| if desc == prefix: | |
| return "" | |
| if desc == f"{prefix}.dirty": | |
| return "+dirty" | |
| if desc.startswith(f"{prefix}-"): | |
| rest = desc[len(prefix) + 1 :] | |
| return f"+dev.{rest.replace('-', '.')}" | |
| # No reachable matching tag (shallow clone, different tag, etc.) -- | |
| # fall back to whatever git describe returned, normalized for PEP 440. | |
| return f"+dev.{desc.replace('-', '.')}" |
A wheel install from PyPI ships only the static version recorded in pyproject.toml, so ``stonks --version`` from a release looks like ``0.6.3``. Source checkouts (``pip install -e .`` against a git working tree, or ``uv sync`` in a clone) have no such cue, and users running an in-progress build look identical to release users when filing bug reports. Detect source checkouts by looking for a ``.git`` directory next to the ``src/`` tree and, when present, append a PEP 440 local-version suffix derived from ``git describe --tags --always --dirty=.dirty``: * exact tag, clean tree -> ``0.6.3`` * exact tag, dirty tree -> ``0.6.3+dirty`` * past tag, clean tree -> ``0.6.3+dev.<N>.g<sha>`` * past tag, dirty tree -> ``0.6.3+dev.<N>.g<sha>.dirty`` * no reachable tag -> ``0.6.3+dev.<sha>[.dirty]`` Failures (missing git, timeout, repo not present) silently drop back to the bare version so PyPI / wheel installs never pay for the probe and never carry the suffix. ``doctor._version_tuple`` is updated to strip the local-version segment before parsing so a dev build of 0.6.3 still compares equal to PyPI's 0.6.3, instead of collapsing to ``(0, 6)`` and triggering a spurious "out of date" warning. Signed-off-by: Igor Opaniuk <igor.opaniuk@gmail.com>
a215a52 to
d3b642c
Compare
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
A wheel install from PyPI ships only the static version recorded in pyproject.toml, so
stonks --versionfrom a release looks like0.6.3. Source checkouts (pip install -e .against a git working tree, oruv syncin a clone) have no such cue, and users running an in-progress build look identical to release users when filing bug reports.Detect source checkouts by looking for a
.gitdirectory next to thesrc/tree and, when present, append a PEP 440 local-version suffix derived fromgit describe --tags --always --dirty=.dirty:0.6.30.6.3+dirty0.6.3+dev.<N>.g<sha>0.6.3+dev.<N>.g<sha>.dirty0.6.3+dev.<sha>[.dirty]Failures (missing git, timeout, repo not present) silently drop back to the bare version so PyPI / wheel installs never pay for the probe and never carry the suffix.
doctor._version_tupleis updated to strip the local-version segment before parsing so a dev build of 0.6.3 still compares equal to PyPI's 0.6.3, instead of collapsing to(0, 6)and triggering a spurious "out of date" warning.