#!/bin/sh
# script/version: output the version string to bake into the binary.
# Our own extension to scripts-to-rule-them-all, and the single source
# of truth for the version: the Makefile's LDFLAGS call this rather
# than carrying a hardcoded constant, which is what used to make every
# local build claim to be 1.0.0-rc.1 regardless of git state.
#
# The rules, in order:
#
#   HEAD is exactly on an annotated or lightweight tag
#       -> that tag, with a leading "v" stripped
#   anything else
#       -> "dev-<12 chars of HEAD>"
#   not a git checkout at all (release tarball, `go install`)
#       -> "dev"
#
# Either of the first two gains a "-dirty" suffix when tracked files
# have uncommitted changes, because a modified checkout of v1.0.0 is
# not v1.0.0. Untracked files are ignored, matching `git describe
# --dirty`: a stray scratch file does not change what was compiled.
#
# The "v" is stripped so that a `make` build and a goreleaser build of
# the same tagged commit report the *same* string: goreleaser's
# {{ .Version }} is the tag without the prefix, and the release archive
# names are built from it. A tag named `v1.0.0` therefore produces
# `vaultik 1.0.0`, matching `vaultik_1.0.0_linux_amd64.tar.gz`.
#
# Nothing here ever invents a version number. An untagged build says so
# and names the commit it was built from; it does not round up to the
# nearest plausible release.
set -eu

ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"

# Length of the commit prefix in a dev version. Matches
# globals.ShortCommit, so `vaultik version` shows the same 12 chars in
# its version line and its commit line.
SHORT_LEN=12

main() {
    cd "$ROOT"

    if ! git rev-parse --git-dir >/dev/null 2>&1; then
        echo "dev"
        return 0
    fi

    dirty=""
    if [ -n "$(git status --porcelain --untracked-files=no 2>/dev/null)" ]; then
        dirty="-dirty"
    fi

    # --exact-match so a *descendant* of a tag is not reported as that
    # tag. Plain `git describe --tags` would call a commit 40 patches
    # past v1.0.0 "v1.0.0-40-gabc1234", and the leading token of that is
    # a released version the build is not.
    tag="$(git describe --tags --exact-match HEAD 2>/dev/null || true)"
    if [ -n "$tag" ]; then
        echo "${tag#v}${dirty}"
        return 0
    fi

    sha="$(git rev-parse "--short=$SHORT_LEN" HEAD 2>/dev/null || true)"
    if [ -z "$sha" ]; then
        # A repo with no commits at all.
        echo "dev"
        return 0
    fi

    echo "dev-${sha}${dirty}"
}

main "$@"
