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. 6 VERSION=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 27 ME=$(basename "$0") 28 warn() { printf '%s: %s\n' "$ME" "$*" >&2; } 29 die() { warn "$*"; exit 1; } 30 31 help() 32 { 33 cat <<EOF 34 Usage: $ME [OPTION...] VERSION RELEASE_TYPE 35 36 Run this script from top_srcdir to perform the final pre-release NEWS 37 update in which the date, release-type and version string are 38 recorded. Commit that result with a log entry marking the release, 39 and apply a signed tag. Run it from your project's top-level 40 directory. 41 42 Requirements: 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 48 Options: 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 54 EXAMPLE: 55 To update NEWS and tag the beta 8.1 release of coreutils, I would run this: 56 57 $ME 8.1 beta 58 59 Report bugs and patches to <bug-gnulib (at] gnu.org>. 60 EOF 61 exit 62 } 63 64 version() 65 { 66 year=$(echo "$VERSION" | sed 's/[^0-9].*//') 67 cat <<EOF 68 $ME $VERSION 69 Copyright (C) $year Free Software Foundation, Inc, 70 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 71 This is free software: you are free to change and redistribute it. 72 There is NO WARRANTY, to the extent permitted by law. 73 EOF 74 exit 75 } 76 77 ## ------ ## 78 ## Main. ## 79 ## ------ ## 80 81 # Constants. 82 noteworthy='* Noteworthy changes in release' 83 noteworthy_stub="$noteworthy ?.? (????-??-??) [?]" 84 85 # Variables. 86 branch=$(git branch | sed -ne '/^\* /{s///;p;q;}') 87 builddir=. 88 89 while test $# != 0 90 do 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 108 done 109 110 test $# = 2 \ 111 || die "Usage: $ME [OPTION...] VERSION TYPE" 112 113 ver=$1 114 type=$2 115 116 117 ## ---------------------- ## 118 ## First, sanity checks. ## 119 ## ---------------------- ## 120 121 # Verify that $ver looks like a version number, and... 122 echo "$ver"|grep -E '^[0-9][0-9.]*[0-9]$' > /dev/null \ 123 || die "invalid version: $ver" 124 prev_ver=$(cat .prev-version) \ 125 || die 'failed to determine previous version number from .prev-version' 126 127 # Verify that $ver is sensible (> .prev-version). 128 case $(printf "$prev_ver\n$ver\n"|sort -V -u|tr '\n' ':') in 129 "$prev_ver:$ver:") ;; 130 *) die "invalid version: $ver (<= $prev_ver)";; 131 esac 132 133 case $type in 134 alpha|beta|stable) ;; 135 *) die "invalid release type: $type";; 136 esac 137 138 # No local modifications allowed. 139 case $(git diff-index --name-only HEAD) in 140 '') ;; 141 *) die 'this tree is dirty; commit your changes first';; 142 esac 143 144 # Ensure the current branch name is correct: 145 curr_br=$(git rev-parse --symbolic-full-name HEAD) 146 test "$curr_br" = refs/heads/$branch || die not on branch $branch 147 148 # Extract package name from Makefile. 149 Makefile=$builddir/Makefile 150 pkg=$(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. 154 test "$(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. 162 perl -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 168 printf "version $ver\n\n* NEWS: Record release date.\n" \ 169 | git commit -F - -a || die 'git commit failed' 170 git 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