diff options
| author | user <user@clank> | 2026-08-27 01:22:34 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-27 01:22:34 +0200 |
| commit | 276ea2610c783bd61789691b910b4be4dbeae890 (patch) | |
| tree | c88be298d15b4c8bd493229620f1c4ef27fe23dd | |
| parent | macos-remote-build: stop rsyncing 850M of caches to the builder (diff) | |
| download | slosh-276ea2610c783bd61789691b910b4be4dbeae890.tar.gz slosh-276ea2610c783bd61789691b910b4be4dbeae890.tar.xz slosh-276ea2610c783bd61789691b910b4be4dbeae890.zip | |
version: derive from git tags instead of a hand-bumped constant
VERSION was a constant in the Makefile that had to be bumped by hand and
could silently disagree with the git tag a release was cut from. Derive it
instead, with a committed ./VERSION as the floor and no-git fallback:
on a tag v0.2.0 -> 0.2.0
past a tag v0.2.0-5-gabc123 -> 0.2.0-5-gabc123 (sorts after 0.2.0)
before any tag 0.1.0-197-g2d1815 -> ./VERSION + commit count + short id
no .git at all 0.1.0 -> ./VERSION verbatim (cgit snapshot ->
Homebrew source build)
A dirty tree appends -dirty. The commit count keeps 'brew upgrade' ordering
monotonic before the first tag exists.
version.h now bakes just VERSION (dropping the redundant +GITDESC, which the
derived string already carries). contrib/brew-release reads the base from
./VERSION rather than grepping the Makefile's VERSION line, which is now a
$(shell ...) expression it could not parse.
| -rw-r--r-- | Makefile | 29 | ||||
| -rw-r--r-- | VERSION | 1 | ||||
| -rwxr-xr-x | contrib/brew-release | 9 |
3 files changed, 33 insertions, 6 deletions
@@ -14,11 +14,32 @@ VT_INC := $(VT_OUT)/include # header rebuilds what actually uses it. Without this a header edit rebuilt # nothing and the only safe move was `make clean`, which is how a 0.1s build # turns into a habit of throwing the whole thing away. +# # The version is baked in, because the first question when a session is # behaving oddly is "which build is this?" -- and a session keeps the binary it # started with, so the answer is not "whatever is in build/ now". -VERSION := 0.1.0 -GITDESC := $(shell git describe --always --dirty 2>/dev/null || echo unknown) +# +# It is derived from git tags (vX.Y.Z), so a tag is the single source of truth +# and nothing here is bumped by hand: +# on a tag v0.2.0 -> 0.2.0 +# past a tag v0.2.0-5-gabc123 -> 0.2.0-5-gabc123 (sorts after 0.2.0) +# before any tag 0.1.0-197-g2d1815 -> ./VERSION + commit count + short id +# no .git at all 0.1.0 -> ./VERSION verbatim (a cgit snapshot +# tarball, which is how Homebrew builds) +# A dirty tree appends -dirty. ./VERSION is the committed floor and the only +# value a source tarball without git can show; contrib/brew-release reads it too. +# The commit count is in there so `brew upgrade` sees a later build as later: +# without it 0.1.0-gabc123 vs 0.1.0-gdef456 would sort alphabetically, which +# has nothing to do with which came first. +VERSION := $(shell \ + if git rev-parse --git-dir >/dev/null 2>&1; then \ + d=$$(git describe --tags --match 'v[0-9]*' --dirty 2>/dev/null); \ + if [ -n "$$d" ]; then printf '%s\n' "$${d#v}"; \ + else printf '%s-%s-g%s%s\n' "$$(cat VERSION 2>/dev/null || echo 0.0.0)" \ + "$$(git rev-list --count HEAD 2>/dev/null || echo 0)" \ + "$$(git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)" \ + "$$(git diff --quiet 2>/dev/null || echo -dirty)"; fi; \ + else cat VERSION 2>/dev/null || echo 0.0.0; fi) CFLAGS := -std=c23 -O1 -g -Wall -Wextra -Wno-unused-parameter -MMD -MP \ -I$(VT_INC) -Iinclude -Ibuild @@ -90,8 +111,8 @@ build/logo.h: logo.txt | build printf '};\n'; } > $@ build/version.h: FORCE | build - @printf '/* generated by the Makefile */\n#define SLOSH_VERSION "%s+%s"\n' \ - '$(VERSION)' '$(GITDESC)' > $@.tmp + @printf '/* generated by the Makefile */\n#define SLOSH_VERSION "%s"\n' \ + '$(VERSION)' > $@.tmp @cmp -s $@.tmp $@ || mv $@.tmp $@ @rm -f $@.tmp @@ -0,0 +1 @@ +0.1.0 diff --git a/contrib/brew-release b/contrib/brew-release index d3eadda..dbaf526 100755 --- a/contrib/brew-release +++ b/contrib/brew-release @@ -84,8 +84,13 @@ esac # A tag must look like a version (digits with a dot); "1368b7f" starts with a # digit but is a commit, and calling it version 1368b7f would be a lie brew # could never climb down from. -mkver="$(sed -n 's/^VERSION *:*= *//p' "$root/Makefile" | head -1)" -[ -n "$mkver" ] || fail "no VERSION in $root/Makefile" +# The base/floor version. It lives in ./VERSION (one line, e.g. 0.1.0), which +# is also what the Makefile bakes into a source build that has no git and the +# floor it builds tag-less versions on top of. It used to be grepped out of the +# Makefile's `VERSION :=` line; that line is now a $(shell ...) derivation, so +# read the file both of them trust instead. +mkver="$(sed -n '1s/[[:space:]]*$//p' "$root/VERSION" 2>/dev/null | head -1)" +[ -n "$mkver" ] || fail "no base version in $root/VERSION" short="$(printf '%s' "$full" | cut -c1-7)" # The count must be a real count. Falling back to 0 when the commit is not in # this clone would mint "0.1.0-0-<short>", which brew reads as older than every |
