1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/scripts/mk-release.sh Sun Mar 07 13:17:27 2010 +0100
1.3 @@ -0,0 +1,308 @@
1.4 +#!/bin/bash
1.5 +#set -x
1.6 +
1.7 +my_name="$( basename "${0}" )"
1.8 +
1.9 +usage() {
1.10 + cat <<-_EOF_
1.11 + Usage:
1.12 + ${my_name} <repos_dir> <M.m.p>
1.13 + _EOF_
1.14 +}
1.15 +
1.16 +repos="${1}"
1.17 +version="${2}"
1.18 +
1.19 +[ -n "${repos}" ] || { usage; exit 1; }
1.20 +[ -d "${repos}" ] || { printf "${my_name}: ${repos}: no such file or directory\n"; exit 1; }
1.21 +[ -n "${version}" ] || { usage; exit 1; }
1.22 +
1.23 +gen_bound_revs() {
1.24 + r1=$( hg log \
1.25 + |awk 'BEGIN {
1.26 + found=0;
1.27 + }
1.28 + $1=="'"${label}"':" {
1.29 + split($2,a,":"); rev=a[1];
1.30 + }
1.31 + $0~/^summary:[[:space:]]*[[:digit:]]+\.[[:digit:]]+: '"${msg}"'/ \
1.32 + && found==0 {
1.33 + printf( "%d\n", rev ); found=1;
1.34 + }'
1.35 + )
1.36 +
1.37 + r2=$( hg log -b "${branch}" \
1.38 + |awk '$1=="changeset:" {
1.39 + split($2,a,":");
1.40 + printf( "%d\n", a[1] );
1.41 + nextfile;
1.42 + }'
1.43 + )
1.44 +
1.45 + r1_log=$((r1+log_offset))
1.46 + if [ ${#r1_log} -gt ${#r2} ]; then
1.47 + rev_w=${#r1_log}
1.48 + else
1.49 + rev_w=${#r2}
1.50 + fi
1.51 +}
1.52 +
1.53 +print_intro_mail() {
1.54 + cat <<-_EOF_
1.55 + Hello all!
1.56 +
1.57 + I'm pleased to announce the release of crosstool-NG ${version}!
1.58 +
1.59 + As usual, there has been quite a number of improvements, new features,
1.60 + and bug fixes all around. The most notable changes are listed below:
1.61 +
1.62 + YEM:
1.63 + YEM: PUT YOUR MESSAGE HERE
1.64 + YEM:
1.65 +
1.66 + This marks the beginning of the ${ver_M}.${ver_m} maintenance branch, and the end of
1.67 + the previous maintenance branch. As always, comments and suggestions
1.68 + are most welcome!
1.69 +
1.70 + The release can be found at the following URLs:
1.71 + Changelog: http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.changelog
1.72 + Tarball: http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.tar.bz2
1.73 + Patches: http://ymorin.is-a-geek.org/download/crosstool-ng/01-fixes/${version}
1.74 +
1.75 + As a reminder, the home for crosstool-NG is:
1.76 + http://ymorin.is-a-geek.org/projects/crosstool
1.77 +
1.78 + Crosstool-NG also has a Freshmeat page:
1.79 + http://freshmeat.net/projects/crosstool-ng/
1.80 + _EOF_
1.81 +}
1.82 +
1.83 +print_intro_changelog_full_release() {
1.84 + cat <<-_EOF_
1.85 + crosstool-NG ${version} -- ${date}
1.86 +
1.87 + This is a feature-release. Significant changes are:
1.88 +
1.89 + YEM:
1.90 + YEM: PUT YOUR MESSAGE HERE
1.91 + YEM:
1.92 + _EOF_
1.93 +}
1.94 +
1.95 +print_intro_changelog_bug_fix() {
1.96 + cat <<-_EOF_
1.97 + crosstool-NG ${version} -- ${date}
1.98 +
1.99 + This is a bug-fix-only release.
1.100 + _EOF_
1.101 +}
1.102 +
1.103 +print_author_stats() {
1.104 + printf "\nMany thanks to the people who contributed to this release:\n\n"
1.105 + prev_author=""
1.106 + template='{author|person}\n'
1.107 + hg log -b "${branch}" -r "${r1_log}:${r2}" \
1.108 + --template "${template}" \
1.109 + |sed -r -e 's/"//g;' \
1.110 + |awk -F '' '{
1.111 + nb[$0]++;
1.112 + }
1.113 + END {
1.114 + for( author in nb ) {
1.115 + printf( " %4d %s\n", nb[author], author );
1.116 + }
1.117 + }' \
1.118 + |sort -rn
1.119 +}
1.120 +
1.121 +print_author_shortlog() {
1.122 + printf "\nHere is the per-author shortlog:\n"
1.123 + prev_author=""
1.124 + template='{author|person}|{rev}|{branches}|{desc|firstline}\n'
1.125 + hg log -b "${branch}" -r "${r1_log}:${r2}" \
1.126 + --template "${template}" \
1.127 + |awk -F '' '{
1.128 + n=split( $0,a,"|" );
1.129 + printf( "%s", gensub("\"","","g",a[1]) );
1.130 + printf( "|%0*d", '${rev_w}', a[2] );
1.131 + for(i=3;i<=n;i++) {
1.132 + printf( "|%s", a[i] );
1.133 + }
1.134 + printf( "\n" );
1.135 + }' \
1.136 + |sort \
1.137 + |while read line; do
1.138 + author="$( echo "${line}" |cut -d \| -f 1 )"
1.139 + rev="$( echo "${line}" |cut -d \| -f 2 )"
1.140 + br="$( echo "${line}" |cut -d \| -f 3 )"
1.141 + desc="$( echo "${line}" |cut -d \| -f 4- )"
1.142 +
1.143 + case "${br}" in
1.144 + ${branch}) ;;
1.145 + [0-9]*.*) continue;;
1.146 + *) ;;
1.147 + esac
1.148 +
1.149 + case "${desc}" in
1.150 + Merge.) continue;;
1.151 + *": close "*" branch"*) continue;;
1.152 +# *\(merged\)) continue;;
1.153 + esac
1.154 +
1.155 + author="$( echo "${author}" |sed -r -e 's/"//g;' )"
1.156 +
1.157 + if [ ! "${prev_author}" = "${author}" ]; then
1.158 + printf "\n"
1.159 + printf " ${author}:\n"
1.160 + prev_author="${author}"
1.161 + fi
1.162 + rev="$( echo "${rev}" |sed -r -e 's/^0*//;' )"
1.163 +
1.164 + printf "%s\n" "${desc}" \
1.165 + |fmt -w 65 \
1.166 + |(first=1; while read l; do
1.167 + if [ -n "${first}" ]; then
1.168 + printf " [%*d] %s\n" ${rev_w} ${rev} "${l}"
1.169 + first=
1.170 + else
1.171 + printf " %*.*s %s\n" ${rev_w} ${rev_w} '' "${l}"
1.172 + fi
1.173 + done)
1.174 + done
1.175 +}
1.176 +
1.177 +print_diffstat() {
1.178 + printf "\nThe diffstat follows:\n\n"
1.179 + hg diff -r "${r1}:${r2}" --color=never \
1.180 + |diffstat -r 2 -p 1 -w 10 \
1.181 + |tail -n 1 \
1.182 + |sed -r -e 's/^ */ /;'
1.183 +
1.184 + hg diff -r "${r1}:${r2}" --color=never \
1.185 + |diffstat -f 1 -r 2 -p 1 -w 10 \
1.186 + |head -n -1 \
1.187 + |while read file line; do
1.188 + if [ ${#file} -gt 57 ]; then
1.189 + file="...$( echo "${file}" |sed -r -e 's/^.*(.{54})$/\1/;' )"
1.190 + fi
1.191 + printf " %-57s %s\n" "${file}" "${line}"
1.192 + done
1.193 +}
1.194 +
1.195 +ver_M="$( printf "${version}" |cut -d . -f 1 )"
1.196 +ver_m="$( printf "${version}" |cut -d . -f 2 )"
1.197 +ver_p="$( printf "${version}" |cut -d . -f 3 )"
1.198 +
1.199 +prefix="$(pwd)/crosstool-ng-${version}"
1.200 +pushd "${repos}" >/dev/null 2>&1
1.201 +
1.202 +printf "Checking for existing tag: "
1.203 +if hg tags |grep -E '^'"crosstool-ng-${version}"'\>' >/dev/null; then
1.204 + printf "already tagged\n"
1.205 + exit 1
1.206 +fi
1.207 +printf "no\n"
1.208 +
1.209 +if [ ${ver_p} -eq 0 ]; then
1.210 + print_mail="yes"
1.211 + print_intro_changelog="print_intro_changelog_full_release"
1.212 + label="parent"
1.213 + msg="create maintenance branch, (update|bump) version to [[:digit:]]+"'\'".[[:digit:]]+"'\'".0"'$'
1.214 + branch="default"
1.215 + log_offset=0
1.216 +else
1.217 + print_mail="no"
1.218 + print_intro_changelog="print_intro_changelog_bug_fix"
1.219 + label="changeset"
1.220 + msg="(update|bump) version to ${ver_M}"'\'".${ver_m}"'\'".$((ver_p-1))"'\+hg$'
1.221 + branch="${ver_M}.${ver_m}"
1.222 + log_offset=1
1.223 +fi
1.224 +
1.225 +printf "Computing boundary revisions:"
1.226 +gen_bound_revs
1.227 +printf " %d:%d\n" ${r1} ${r2}
1.228 +
1.229 +printf "Tagging release:"
1.230 +hg up "${branch}" >/dev/null
1.231 +if [ ${ver_p} -eq 0 ]; then
1.232 + printf " update version"
1.233 + hg branch "${ver_M}.${ver_m}" >/dev/null
1.234 + echo "${version}" >".version"
1.235 + hg ci -m "${ver_M}.${ver_m}: create maintenance branch, update version to ${version}"
1.236 +else
1.237 + printf " update version"
1.238 + echo "${version}" >".version"
1.239 + hg ci -m "${ver_M}.${ver_m}: update version to ${version}"
1.240 +fi
1.241 +
1.242 +printf ", tag"
1.243 +hg tag -m "Tagging release ${version}" crosstool-ng-${version}
1.244 +
1.245 +printf ", update version"
1.246 +echo "${version}+hg" >".version"
1.247 +hg ci -m "${ver_M}.${ver_m}: update version to ${version}+hg"
1.248 +
1.249 +printf ", date"
1.250 +date="$( hg log -r crosstool-ng-${version} --template '{date|isodate}\n' \
1.251 + |sed -r -e 's/-|://g; s/ /./; s/ //;' \
1.252 + )"
1.253 +printf ", done.\n"
1.254 +
1.255 +if [ ${ver_p} -eq 0 ]; then
1.256 + printf "Generating release mail:"
1.257 + printf " intro"
1.258 + print_intro_mail > "${prefix}.mail"
1.259 + printf ", stats"
1.260 + print_author_stats >>"${prefix}.mail"
1.261 + printf ", shortlog"
1.262 + print_author_shortlog >>"${prefix}.mail"
1.263 + printf ", done.\n"
1.264 +fi
1.265 +
1.266 +printf "Generating release changelog:"
1.267 +printf " intro"
1.268 +${print_intro_changelog} > "${prefix}.changelog"
1.269 +printf ", stats"
1.270 +print_author_stats >>"${prefix}.changelog"
1.271 +printf ", shortlog"
1.272 +print_author_shortlog >>"${prefix}.changelog"
1.273 +printf ", diffstat"
1.274 +print_diffstat >>"${prefix}.changelog"
1.275 +printf ", done.\n"
1.276 +
1.277 +popd >/dev/null 2>&1
1.278 +
1.279 +printf "Creating tarball:"
1.280 +prefix="crosstool-ng-${version}"
1.281 +printf " cloning"
1.282 +hg clone "${repos}" "${prefix}" >/dev/null
1.283 +hg up -R "${prefix}" "${prefix}" >/dev/null
1.284 +date="$( hg log -R "${prefix}" -r "${prefix}" --template '{date|rfc822date}\n' )"
1.285 +printf ", purging"
1.286 +rm -rf "${prefix}/"{.hg,.hgtags,.hgignore}
1.287 +printf ", tarball"
1.288 +tar cjf "${prefix}.tar.bz2" "${prefix}"
1.289 +printf ", sum"
1.290 +for s in md5 sha1 sha512; do
1.291 + ${s}sum "${prefix}.tar.bz2" >"${prefix}.tar.bz2.${s}"
1.292 +done
1.293 +printf ", cleaning"
1.294 +rm -rf "${prefix}"
1.295 +printf ", touch"
1.296 +touch -d "${date}" "${prefix}"*
1.297 +printf ", done.\n"
1.298 +
1.299 +if [ ${ver_p} -eq 0 ]; then
1.300 + printf "\nAn editor will be launched for you to edit the mail.\n"
1.301 + read -p "Press enter when ready..." foo
1.302 + cp "${prefix}.mail"{,.orig}
1.303 + vi "${prefix}.mail"
1.304 + diff -du -U 1 "${prefix}.mail"{.orig,} |patch -p0 "${prefix}.changelog" >/dev/null
1.305 +fi
1.306 +
1.307 +printf "\nAn editor will be launched for you to review the changelog.\n"
1.308 +read -p "Press enter when ready..." foo
1.309 +vi "${prefix}.changelog"
1.310 +
1.311 +printf "\nNow, you can push the changes with: hg push -R '${repos}'\n"