123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- #!/bin/bash
- # MKit - simple install helper
- # See LICENSE file for copyright and license details.
-
- mkit_import ini
-
- git_bool() {
- #
- # Get git bool (ie. exit status counts) $1
- #
- local bool_name=$1 # name of boolean to get
- git_present || warn "can't give bool outside git repo: $bool_name"
- case "$bool_name" in
- dirty_files)
- git diff-files | grep -qm 1 .
- ;;
- dirty_index)
- git diff-index HEAD | grep -qm 1 .
- ;;
- dirty)
- git_bool dirty_files || git_bool dirty_index
- ;;
- *)
- warn "unknown git bool asked: $bool_name"
- return 2
- ;;
- esac
- }
-
- git_fact() {
- #
- # Get git fact $1
- #
- local fact_name=$1 # name of fact to get
- git_present || warn "can't give fact outside git repo: $fact_name"
- case "$fact_name" in
- latest_tag)
- git log --format="%d" \
- | sed 's/,/\n/g' \
- | sed 's/^[[:blank:]]*//' \
- | grep -E '^\(?tag' \
- | tr -cd '[[:digit:]].v\n' \
- | grep . -m 1
- ;;
- latest_version)
- git_fact latest_tag | git_tag2ver
- ;;
- current_branch)
- git rev-parse --abbrev-ref HEAD
- ;;
- reldiff)
- git log --oneline "$(git_fact latest_tag)..HEAD" --name-only
- ;;
- latest_sha)
- git log -1 --pretty=format:%h HEAD
- ;;
- *)
- warn "unknown git fact asked: $fact_name"
- ;;
- esac
- }
-
- git_present() {
- #
- # True if we're in a git repo
- #
- git rev-parse HEAD >&/dev/null
- }
-
- git_tag2ver() {
- #
- # Convert tag to version
- #
- sed s/^v//
- }
-
- git_ver2tag() {
- #
- # Convert version to tag
- #
- sed s/^/v/
- }
-
- git_lasthash() {
- #
- # Show last commit hash (with .dirty suffix if needed)
- #
- # We can't do it outside git repo (or without git) but we should
- # not be asked to; targets that don't require git should make use
- # of cache built by dist target.
- #
- local last_hash # last commit hash
- git_present || {
- echo UNKNOWN_HASH
- warn "no git present; could not determine last hash"
- return 3
- }
- last_hash=$(git rev-parse HEAD)
- echo -n "$last_hash"
- git_bool dirty && echo -n ".dirty"
- }
-
- semver() {
- #
- # Build proper SemVer version string
- #
- # Build version string from available info using following
- # logic:
- #
- # 1. Use version from last git tag (or mkit.ini if there is no
- # tag, which is possible on new project)
- # 2. if set, add project:prerl (from mkit.ini) as pre-release ID
- # (afer dash)
- # 3. if we are at a later commit than the last tag, add branch
- # name and commit sha1 to build metadata (after plus sign)
- # 4. if the tree is "dirty", i.e. has uncommited changes,
- # add "dirty" to build metadata
- #
- # The version is compatible with SemVer 2.0.0.
- #
- # Examples:
- #
- # foo v1.0.7 # all clear; proper release
- # foo v1.0.7-beta # mkit.ini: project:prerl="beta"
- # foo v1.0.7-beta+g1aef811.master # ^^ + some commits after
- # foo v1.0.7-beta+gf14fc4f.api2 # ^^ + on a feature branch
- # foo v1.0.7-beta+gf14fc4f.api2.dirty # ^^ + tree edited
- # foo v1.0.7-beta+dirty # tag OK but tree edited
- # foo v1.0.7+dirty # ^^ but no pre-release id
- #
- # Note that versions with "dirty" should be perceived as kind of
- # dangerous outside developer's own machine. Versions with sha1 are
- # safer but must not be released.
- #
- # FIXME: Using project:prerl for release IDs may not be compatible with
- # release strategy implemented in release.sh
- #
- local xyz # base version string
- local prerl # pre-release keyword (from mkit.ini, eg. 'beta')
- local latest_tag # latest git tag
- local commit # commit indicator (CURRENT_BRANCH.gHASH)
- local dirty=F # F if dirty, T if clean
- local btime # hex timestamp or nothing (see $MKIT_TTAG)
- local suffix # version suffix
- prerl=$(ini 1value project:prerl)
- case $MKIT_TTAG in
- none) btime= ;;
- btime) btime=$(printf '%08x' "$(date +%s)") ;;
- esac
- grep ":" <<<"$prerl" \
- && warn "colon in project:prerl may corrupt version data: $prerl"
- git_present || {
- echo UNKNOWN_VERSION
- warn "no git present; could not determine SemVer"
- return 3
- }
- latest_tag=$(git_fact latest_tag)
- case $latest_tag in
- v*) xyz=${latest_tag:1} ;;
- "") warn "no tags, using base version from mkit.ini (ok for new project)"
- xyz=$(ini 1value project:version) ;;
- *) warn "bad form of last tag, using base version from mkit.ini: tag is '$latest_tag'"
- xyz=$(ini 1value project:version) ;;
- esac
- if ! git describe --tags --exact-match HEAD >&/dev/null;
- then # we are at a later commit than the last tag
- commit="$(git_fact current_branch).g$(git_fact latest_sha)"
- fi
- git_bool dirty && dirty=T
- case "$dirty:$btime:$commit" in
- F:*:) suffix="" ;;
- T::) suffix="+dirty" ;;
- T:*:) suffix="+t$btime.dirty" ;;
- F::*) suffix="+$commit" ;;
- F:*:*) suffix="+t$btime.$commit" ;;
- T::*) suffix="+$commit.dirty" ;;
- T:*:*) suffix="+t$btime.$commit.dirty" ;;
- *) suffix=MKIT_BUG
- warn "MKIT_BUG: bad dirt/commit detection" ;;
- esac
- test -n "$prerl" && suffix="-$prerl$suffix"
- echo "$xyz$suffix"
- }
|