~kp/git-release

2ff496d4086546150ef6fc969fd3571375b11991 — Konstantinos Pachnis 9 years ago 1.0.0
Initial import
5 files changed, 352 insertions(+), 0 deletions(-)

A LICENSE
A Makefile
A README.md
A rn
A rn.1
A  => LICENSE +27 -0
@@ 1,27 @@
Copyright (c) 2015, Konstantinos Pachnis
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
   may be used to endorse or promote products derived from this software without
   specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

A  => Makefile +15 -0
@@ 1,15 @@
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man

install:
	@printf "Installing executable file to ${DESTDIR}${PREFIX}/bin\n"
	@install -m 0755 rn ${DESTDIR}${PREFIX}/bin/rn
	@printf "Installing manual page to ${DESTDIR}${MANPREFIX}/man1\n"
	@mkdir -p ${DESTDIR}${MANPREFIX}/man1
	@install -m 0644 rn.1 ${DESTDIR}${MANPREFIX}/man1/rn.1

uninstall:
	@printf "Removing executables from ${DESTDIR}${PREFIX}/bin\n"
	@rm -f ${DESTDIR}${PREFIX}/bin/rn
	@printf "Removing manual page from ${DESTDIR}${MANPREFIX}/man1\n"
	@rm -f ${DESTDIR}${MANPREFIX}/man1/rn.1

A  => README.md +11 -0
@@ 1,11 @@
**rn** is a shell script, which automates the creation of software release numbers 
in the form of **MAJOR**.**MINOR**.**PATCH** using git signed tags.

For more information read the online documentation `rn(8)`.

Install with
    
```sh
$ make install
```


A  => rn +231 -0
@@ 1,231 @@
#!/bin/sh

if [ "$RN_DEBUG" ]; then
  set -e
  set -x
fi

PATH="$(getconf PATH)"

readonly EPERM=1
readonly ENOENT=2

checks() {
  if [ ! -x "$(command -v git)" ]; then
    printf "ERROR: git not found"
    exit $ENOENT
  fi

  if [ ! -d "$PWD/.git" ]; then
    printf "ERROR: Not a git repository\n"
    exit $EPERM
  fi

  return 0
}

version() {
  local version='1.0.0'

  printf "rn $version, (C) 2015 Konstantinos Pachnis, see LICENSE for details\n"

  exit 0
}

usage() {
  printf "Usage: rn [-s] [-l] [-n version] [-M] [-m] [-p] [-D] [-d version] [-v]\n"

  exit 0
}

create_release_number() {
  checks

  if echo "$version_no" | grep [0-9].[0-9].[0-9] >/dev/null; then
    remotes="$(git remote)"

    git tag -s "$version_no" -m "Create version $version_no"

    if [ $? -eq 0 ]; then
      for r in $remotes; do
        git push "$r" "$version_no"
      done
    else
      exit $?
    fi
  else
    usage
  fi

  exit 0
}

current_release_number() {
  checks

  local version="$(git tag -l | sort -n -r -t. -k1,1 -k2,2 -k3,3 | head -n 1)"

  if [ "$version" ]; then
    printf "$version\n"
  else
    printf "No versions found\n"
    exit $EPERM
  fi

  exit 0
}

list_release_numbers() {
  checks

  local versions="$(git tag -l | sort -n -t. -k1,1 -k2,2 -k3,3)"

  if [ "$versions" ]; then
    for v in $versions; do
      printf "$v\n"
    done
  else
    printf "No versions found\n"
    exit $EPERM
  fi

  exit 0
}

auto_release_number() {
  checks

  version="$(git tag -l | sort -n -r -t. -k1,1 -k2,2 -k3,3 | head -n 1)"

  if echo "$version" | grep [0-9].[0-9].[0-9] >/dev/null; then
    case $version_type in
      'major')
        version_no="$(echo $version | awk -F . '{ print $1+1 "." 0 "." 0 }')"
        ;;
      'minor')
        version_no="$(echo $version | awk -F . '{ print $1 "." $2+1 "." 0 }')"
        ;;
      'patch')
        version_no="$(echo $version | awk -F . '{ print $1 "." $2 "." $3+1 }')"
        ;;
      *)
        ;;
    esac
    create_release_number
  else
    printf "No versions found\n"
    exit $EPERM
  fi

  exit 0
}

delete_all_release_numbers() {
  local confirm_delete='N'

  checks

  versions="$(git tag -l | sort -n -t. -k1,1 -k2,2 -k3,3)"

  if [ ! "$versions" ]; then
    printf "No versions found\n"
    exit $EPERM
  fi

  printf "WARNING: All versions will be deleted permanently.\n"
  printf "Do you want to continue [N/y]? "

  read confirm_delete

  if [ "$confirm_delete" ] && [ "$confirm_delete" = 'Y' -o "$confirm_delete" = 'y' ]; then
    remotes="$(git remote)"

    for v in $versions; do
      git tag -d "$v"

      for r in $remotes; do
        git push "$r" ":refs/tags/$v"
      done
    done
  fi

  exit 0
}

delete_release_number() {
  local confirm_delete='N'

  checks

  if ! echo "$version_no" | grep [0-9].[0-9].[0-9] >/dev/null; then
    printf "Release $version_no not found\n"
    exit $EPERM
  fi

  printf "WARNING: Release $version_no will be deleted permanently.\n"
  printf "Do you want to continue [N/y]? "

  read confirm_delete

  if [ "$confirm_delete" ] && [ "$confirm_delete" = 'Y' -o "$confirm_delete" = 'y' ]; then
    remotes="$(git remote)"

    git tag -d "$version_no"

    if [ $? -eq 0 ]; then
      for r in $remotes; do
        git push "$r" ":refs/tags/$version_no"
      done
    fi
  fi

  exit 0
}

main() {
  while getopts d:n:DMhlmpsv opt; do
    case $opt in
      M)
        version_type='major'
        auto_release_number
        ;;
      m)
        version_type='minor'
        auto_release_number
        ;;
      p)
        version_type='patch'
        auto_release_number
        ;;
      s)
        current_release_number
        ;;
      l)
        list_release_numbers
        ;;
      n)
        version_no="$OPTARG"
        create_release_number
        ;;
      D)
        delete_all_release_numbers
        ;;
      d)
        version_no="$OPTARG"
        delete_release_number
        ;;
      v)
        version
        ;;
      h)
        usage
        ;;
    esac
  done

  shift $(( OPTIND - 1 ))

  [ $# = 0 ] && usage
}

main "$@"

A  => rn.1 +68 -0
@@ 1,68 @@
.TH RN 1 "May 11, 2015" "1.0.0"
.SH NAME
rn \- manage software release numbers
.SH SYNOPSIS
.B rn
.RB [ \-s ]
.RB [ \-l ]
.RB [ \-n
.IR <relno> ]
.RB [ \-M ]
.RB [ \-m ]
.BR [ \-p ]
.RB [ \-d
.IR <relno> ]
.RB [ \-D ]
.RB [ \-h ]
.RB [ \-v ]
.SH DESCRIPTION
.B rn
is a shell script, which automates the creation of software relese numbers in the
form of \fBMAJOR\fP.\fBMINOR\fP.\fBPATCH\fP using signed git tags.
.sp
Git operations performed by \fBrn\fP, will be pushed to all tracked
repositories.
.SH OPTIONS
.TP
.B \-s
Show current release number.
.TP
.B \-l
List all release numbers.
.TP
.BI \-n\  <relno>
Create a new custom release number.
.TP
.B \-M
Create a new major release number.
.TP
.B \-m
Create a new minor release number.
.TP
.B \-p
Create a new patch release number.
.TP
.B \-D
Delete all release numbers.
.TP
.BI \-d\  <relno>
Delete a release number.
.TP
.B \-h
Print a help message and exit.
.TP
.B \-v
Display
.B rn
version information.
.SH ENVIRONMENT
.TP
.B RN_DEBUG
If
.RB $ RN_DEBUG
is set, the shell \fBerrexit\fP, \fBnounset\fP and \fBxtrace\fP options will
be set.
.SH SEE ALSO
.BR git-tag (1),
.BR gpg2 (1),