1#!/bin/sh 2# In a git/autoconf/automake-enabled project with a NEWS file and a version- 3# controlled .prev-version file, automate the procedure by which we record 4# the date, release-type and version string in the NEWS file. That commit 5# will serve to identify the release, so apply a signed tag to it as well. 6VERSION=2012-08-01.09 # UTC 7 8# Note: this is a bash script (could be zsh or dash) 9 10# Copyright (C) 2009-2012 Free Software Foundation, Inc. 11 12# This program is free software: you can redistribute it and/or modify 13# it under the terms of the GNU General Public License as published by 14# the Free Software Foundation, either version 3 of the License, or 15# (at your option) any later version. 16 17# This program is distributed in the hope that it will be useful, 18# but WITHOUT ANY WARRANTY; without even the implied warranty of 19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20# GNU General Public License for more details. 21 22# You should have received a copy of the GNU General Public License 23# along with this program. If not, see <http://www.gnu.org/licenses/>. 24 25# Written by Jim Meyering 26 27ME=$(basename "$0") 28warn() { printf '%s: %s\n' "$ME" "$*" >&2; } 29die() { warn "$*"; exit 1; } 30 31help() 32{ 33 cat <<EOF 34Usage: $ME [OPTION...] VERSION RELEASE_TYPE 35 36Run this script from top_srcdir to perform the final pre-release NEWS 37update in which the date, release-type and version string are 38recorded. Commit that result with a log entry marking the release, 39and apply a signed tag. Run it from your project's top-level 40directory. 41 42Requirements: 43- you use git for version-control 44- a version-controlled .prev-version file 45- a NEWS file, with line 3 identical to this: 46$noteworthy_stub 47 48Options: 49 --branch=BRANCH set release branch (default: $branch) 50 -C, --builddir=DIR location of (configured) Makefile (default: $builddir) 51 --help print this help, then exit 52 --version print version number, then exit 53 54EXAMPLE: 55To update NEWS and tag the beta 8.1 release of coreutils, I would run this: 56 57 $ME 8.1 beta 58 59Report bugs and patches to <bug-gnulib@gnu.org>. 60EOF 61 exit 62} 63 64version() 65{ 66 year=$(echo "$VERSION" | sed 's/[^0-9].*//') 67 cat <<EOF 68$ME $VERSION 69Copyright (C) $year Free Software Foundation, Inc, 70License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 71This is free software: you are free to change and redistribute it. 72There is NO WARRANTY, to the extent permitted by law. 73EOF 74 exit 75} 76 77## ------ ## 78## Main. ## 79## ------ ## 80 81# Constants. 82noteworthy='* Noteworthy changes in release' 83noteworthy_stub="$noteworthy ?.? (????-??-??) [?]" 84 85# Variables. 86branch=$(git branch | sed -ne '/^\* /{s///;p;q;}') 87builddir=. 88 89while test $# != 0 90do 91 # Handle --option=value by splitting apart and putting back on argv. 92 case $1 in 93 --*=*) 94 opt=$(echo "$1" | sed -e 's/=.*//') 95 val=$(echo "$1" | sed -e 's/[^=]*=//') 96 shift 97 set dummy "$opt" "$val" ${1+"$@"}; shift 98 ;; 99 esac 100 101 case $1 in 102 --help|--version) ${1#--};; 103 --branch) shift; branch=$1; shift ;; 104 -C|--builddir) shift; builddir=$1; shift ;; 105 --*) die "unrecognized option: $1";; 106 *) break;; 107 esac 108done 109 110test $# = 2 \ 111 || die "Usage: $ME [OPTION...] VERSION TYPE" 112 113ver=$1 114type=$2 115 116 117## ---------------------- ## 118## First, sanity checks. ## 119## ---------------------- ## 120 121# Verify that $ver looks like a version number, and... 122echo "$ver"|grep -E '^[0-9][0-9.]*[0-9]$' > /dev/null \ 123 || die "invalid version: $ver" 124prev_ver=$(cat .prev-version) \ 125 || die 'failed to determine previous version number from .prev-version' 126 127# Verify that $ver is sensible (> .prev-version). 128case $(printf "$prev_ver\n$ver\n"|sort -V -u|tr '\n' ':') in 129 "$prev_ver:$ver:") ;; 130 *) die "invalid version: $ver (<= $prev_ver)";; 131esac 132 133case $type in 134 alpha|beta|stable) ;; 135 *) die "invalid release type: $type";; 136esac 137 138# No local modifications allowed. 139case $(git diff-index --name-only HEAD) in 140 '') ;; 141 *) die 'this tree is dirty; commit your changes first';; 142esac 143 144# Ensure the current branch name is correct: 145curr_br=$(git rev-parse --symbolic-full-name HEAD) 146test "$curr_br" = refs/heads/$branch || die not on branch $branch 147 148# Extract package name from Makefile. 149Makefile=$builddir/Makefile 150pkg=$(sed -n 's/^PACKAGE = \(.*\)/\1/p' "$Makefile") \ 151 || die "failed to determine package name from $Makefile" 152 153# Check that line 3 of NEWS is the stub line about to be replaced. 154test "$(sed -n 3p NEWS)" = "$noteworthy_stub" \ 155 || die "line 3 of NEWS must be exactly '$noteworthy_stub'" 156 157## --------------- ## 158## Then, changes. ## 159## --------------- ## 160 161# Update NEWS to have today's date, plus desired version number and $type. 162perl -MPOSIX -ni -e 'my $today = strftime "%F", localtime time;' \ 163 -e 'my ($type, $ver) = qw('"$type $ver"');' \ 164 -e 'my $pfx = "'"$noteworthy"'";' \ 165 -e 'print $.==3 ? "$pfx $ver ($today) [$type]\n" : $_' \ 166 NEWS || die 'failed to update NEWS' 167 168printf "version $ver\n\n* NEWS: Record release date.\n" \ 169 | git commit -F - -a || die 'git commit failed' 170git tag -s -m "$pkg $ver" v$ver HEAD || die 'git tag failed' 171 172# Local variables: 173# indent-tabs-mode: nil 174# eval: (add-hook 'write-file-hooks 'time-stamp) 175# time-stamp-start: "VERSION=" 176# time-stamp-format: "%:y-%02m-%02d.%02H" 177# time-stamp-time-zone: "UTC" 178# time-stamp-end: " # UTC" 179# End: 180