feat(cli): report build provenance in --version - #95
Merged
Merged
Conversation
`desk --version` reported `0.3.0` across changes that altered what commands do — #88 added -c/--calendar to the write commands, #89 changed the wall-clock time a naive --start resolves to — so the same string named a build where `cal create --start 2026-11-11T17:30:00` produces 4:30pm and one where it produces 5:30pm. Bumping the version per release helps but does not close this: desk is commonly installed with `uv tool install git+https://...`, which tracks a branch rather than a release, so between tags no version string can distinguish two builds. $ desk --version desk, version 0.3.0 (a837d65, 2026-09-03) A hatchling build hook resolves the commit at build time and injects desk/_build_info.py into the wheel and sdist via force_include — never into the source tree, which would either dirty the working copy on every local build or, if gitignored, risk hatchling's VCS-aware file selection dropping it from the sdist. When git is absent but a generated _build_info.py already exists (the sdist -> wheel path), its values carry through instead of being overwritten with unknowns. Runtime resolution is: baked-in build info, else a git read of the package's own directory, else nothing. The git step exists only for editable installs, where there was no build to bake anything in; it is wrapped so no git failure can break --version, and `source` in the JSON marks which path was taken so a caller knows how much to trust `commit`. --version --json returns the fields separately, for an operator recording what a deployment runs. This replaces click.version_option, which cannot vary its output by another flag. --capabilities gains the commit too, since an agent checking whether a fix is present reads that rather than --version. The version number keeps its scheme and its source in pyproject.toml, so ADR-011's SemVer decision is untouched. Fixes #93 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
robpc
force-pushed
the
feat/version-build-info
branch
from
September 4, 2026 03:23
a539594 to
d2c1689
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #93.
desk --versionreported0.3.0across changes that altered what commands do — #88 added-c/--calendarto the write commands, #89 changed the wall-clock time a naive--startresolves to. The same string named a build wherecal create --start 2026-11-11T17:30:00produces 4:30pm and one where it produces 5:30pm.How the commit gets there
A hatchling build hook resolves it at build time and injects
desk/_build_info.pyinto the wheel and sdist viaforce_include— deliberately not by writing intosrc/. Writing there would dirty the working copy on every local build, and gitignoring it would risk hatchling's VCS-aware file selection dropping it from the sdist.force_includesidesteps both.When git is absent but a generated
_build_info.pyalready exists — the sdist → wheel path — its values carry through rather than being overwritten with unknowns.Runtime resolution is: baked-in build info → a git read of the package's own directory → nothing. The git step exists only for editable installs, where there was no build to bake anything into. The issue asked for build-time capture "rather than shelling out to git at runtime," which is about not depending on git in an installed wheel; step 1 satisfies that, and step 2 fires only where step 1 structurally cannot. Every git call is wrapped so no failure can break
--version, andsourcein the JSON marks which path was taken so a caller knows how much to trustcommit.Also
--capabilitiesreports the commit too — an agent checking whether a fix is present reads that, not--version.click.version_option, which cannot vary its output by another flag.pyproject.toml, so ADR-011's SemVer decision is untouched.hatch-vcswas considered and rejected for exactly that reason — it solves provenance by changing something ADR-011 settled for unrelated reasons.Verification
893 tests pass (14 new), ruff clean. The whole build chain was exercised end to end:
/tmpsource: "build"source: "git"Tests cover the git-failure paths too (missing binary, timeout,
OSError), since a broken git must never take--versiondown.Reasoning in ADR-036.
🤖 Generated with Claude Code