| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 | #!/bin/bash
. "$MKIT_DIR/include/ini.sh"   || die "cannot import ini.sh"
. "$MKIT_DIR/include/facts.sh" || die "cannot import facts.sh"
_bump_version() {
    #
    # Bump version on stdin by level $1 (x, y or z)
    #
    local rlevel=$1
    local old
    read -r old
    local oldx=${old%.*.*}
    local oldz=${old#*.*.}
    local tmpy=${old%.*}
    local oldy=${tmpy#*.}
    local new=""
    case $rlevel in
        x) new="$((oldx+MKIT_BUMPSIZE)).0.0"            ;;
        y) new="$oldx.$((oldy+MKIT_BUMPSIZE)).0"        ;;
        z) new="$oldx.$oldy.$((oldz+MKIT_BUMPSIZE))"    ;;
        *) die "invalid release level: $1"  ;;
    esac
    echo "$new"
}
_relck() {
    #
    # Die if blocking condition $1 is detected
    #
    local condition="$1"
    local x
    case "$condition" in
        git_present)
            git rev-parse HEAD >&/dev/null\
             || die "cannot do this outside git repo"
            ;;
        at_relsrc)
            local relsrc=$(ini 1value project:relsrc)
            git_fact current_branch \
              | grep -qFx "$relsrc" \
             || die "you are not on release source branch: $relsrc"
            ;;
        not_dirty)
            git diff --shortstat 2>/dev/null \
              | grep -q . \
             && die "tree is dirty: $dirt"
            ;;
        tags_ok)
            git_fact latest_tag \
              | grep -q . \
             || die "cannot find latest tag"
            ;;
        vbump_hot)
            git diff-tree --no-commit-id --name-only -r HEAD \
              | grep -qFx mkit.ini \
             || die "last change must be version bump in mkit.ini"
            ;;
        no_wip)
            git_fact reldiff \
              | grep '^....... WIP ' \
             && die "WIP commit since $(git_fact latest_tag)"
            ;;
        ini_version)
            local oracle=$(git_fact latest_version | _bump_version "$rlevel")
            ini 1value project:version  \
              | grep -qFx "$oracle" \
             || die "new version not in mkit.ini: $oracle"
            ;;
        *)
            die "unknown release check: $condition"
            ;;
    esac
}
_release() {
    #
    # Prepare release
    #
    # Span release routines: make a signed tag, check branch
    # and update release branch
    #
    # FIXME: Using project:prerl as build.sh:semver() does may not be
    #        compatible with this release strategy
    #
    local rlevel=$1
    local newtag
    local reldst
    _relck git_present
    _relck at_relsrc
    _relck not_dirty
    _relck tags_ok
    _relck vbump_hot
    _relck no_wip
    _relck ini_version
    newtag=$(git_fact latest_version | _bump_version "$rlevel" | git_ver2tag )
    set -e
    debug_var newtag
    $MKIT_DRY && return
    git tag -m "$(_release_msg)" "$newtag"
    reldst=$(ini 1value project:reldst)
    debug_var reldst
    if test -n "$reldst";
    then
        git branch -f "$reldst" "$newtag"
    fi
}
_release_msg() {
    #
    # Generate message for annotated tag
    #
    # The last commit before issuing a release must be "Bump version" commit
    # suggested by _vbump_gitmsg() and  manually edited by user.  Since the
    # commit contains changelog, this function just uses the message body.
    #
    # The sort message (first line) is replaced with a nicer one (with project
    # name, codename and version).
    #
    echo "$(ini 1value project:name) $newtag - $(ini 1value project:codename)"
    echo
    git show -s --format=%B \
      | tail -n +3
}
_vbump() {
    local rlevel="$1"
    local nextver   # after the bump
    _relck git_present
    _relck at_relsrc
    _relck not_dirty
    nextver=$(ini 1value project:version | _bump_version "$rlevel")
    debug_var nextver
    $MKIT_DRY && return
    update_version "$nextver" mkit.ini \
      || die "failed to update version in mkit.ini"
    git add mkit.ini \
      || die "failed to add mkit.ini to the index"
    git commit -e -m "$(_vbump_gitmsg)"
}
_vbump_gitmsg() {
    echo "Bump version"
    echo ""
    echo "Overview of changes:"
    echo ""
    git_fact reldiff \
      | sed '
            s/^[a-f0-9]\{7\} / *  &/; t PATHS
            s/^/        /
            :PATHS
        '
}
release_x() {
    _release x
}
release_y() {
    _release y
}
release_z() {
    _release z
}
vbump_x() {
    _vbump x
}
vbump_y() {
    _vbump y
}
vbump_z() {
    _vbump z
}
 |