From cbc8a652373455cb7475ebd7d7e0c041f623871a Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN\"" Date: Sun, 7 Mar 2010 13:17:27 +0100 Subject: scripts: add script to make a release diff --git a/scripts/mk-release.sh b/scripts/mk-release.sh new file mode 100755 index 0000000..d7a8cfb --- /dev/null +++ b/scripts/mk-release.sh @@ -0,0 +1,308 @@ +#!/bin/bash +#set -x + +my_name="$( basename "${0}" )" + +usage() { + cat <<-_EOF_ + Usage: + ${my_name} + _EOF_ +} + +repos="${1}" +version="${2}" + +[ -n "${repos}" ] || { usage; exit 1; } +[ -d "${repos}" ] || { printf "${my_name}: ${repos}: no such file or directory\n"; exit 1; } +[ -n "${version}" ] || { usage; exit 1; } + +gen_bound_revs() { + r1=$( hg log \ + |awk 'BEGIN { + found=0; + } + $1=="'"${label}"':" { + split($2,a,":"); rev=a[1]; + } + $0~/^summary:[[:space:]]*[[:digit:]]+\.[[:digit:]]+: '"${msg}"'/ \ + && found==0 { + printf( "%d\n", rev ); found=1; + }' + ) + + r2=$( hg log -b "${branch}" \ + |awk '$1=="changeset:" { + split($2,a,":"); + printf( "%d\n", a[1] ); + nextfile; + }' + ) + + r1_log=$((r1+log_offset)) + if [ ${#r1_log} -gt ${#r2} ]; then + rev_w=${#r1_log} + else + rev_w=${#r2} + fi +} + +print_intro_mail() { + cat <<-_EOF_ + Hello all! + + I'm pleased to announce the release of crosstool-NG ${version}! + + As usual, there has been quite a number of improvements, new features, + and bug fixes all around. The most notable changes are listed below: + + YEM: + YEM: PUT YOUR MESSAGE HERE + YEM: + + This marks the beginning of the ${ver_M}.${ver_m} maintenance branch, and the end of + the previous maintenance branch. As always, comments and suggestions + are most welcome! + + The release can be found at the following URLs: + Changelog: http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.changelog + Tarball: http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.tar.bz2 + Patches: http://ymorin.is-a-geek.org/download/crosstool-ng/01-fixes/${version} + + As a reminder, the home for crosstool-NG is: + http://ymorin.is-a-geek.org/projects/crosstool + + Crosstool-NG also has a Freshmeat page: + http://freshmeat.net/projects/crosstool-ng/ + _EOF_ +} + +print_intro_changelog_full_release() { + cat <<-_EOF_ + crosstool-NG ${version} -- ${date} + + This is a feature-release. Significant changes are: + + YEM: + YEM: PUT YOUR MESSAGE HERE + YEM: + _EOF_ +} + +print_intro_changelog_bug_fix() { + cat <<-_EOF_ + crosstool-NG ${version} -- ${date} + + This is a bug-fix-only release. + _EOF_ +} + +print_author_stats() { + printf "\nMany thanks to the people who contributed to this release:\n\n" + prev_author="" + template='{author|person}\n' + hg log -b "${branch}" -r "${r1_log}:${r2}" \ + --template "${template}" \ + |sed -r -e 's/"//g;' \ + |awk -F '' '{ + nb[$0]++; + } + END { + for( author in nb ) { + printf( " %4d %s\n", nb[author], author ); + } + }' \ + |sort -rn +} + +print_author_shortlog() { + printf "\nHere is the per-author shortlog:\n" + prev_author="" + template='{author|person}|{rev}|{branches}|{desc|firstline}\n' + hg log -b "${branch}" -r "${r1_log}:${r2}" \ + --template "${template}" \ + |awk -F '' '{ + n=split( $0,a,"|" ); + printf( "%s", gensub("\"","","g",a[1]) ); + printf( "|%0*d", '${rev_w}', a[2] ); + for(i=3;i<=n;i++) { + printf( "|%s", a[i] ); + } + printf( "\n" ); + }' \ + |sort \ + |while read line; do + author="$( echo "${line}" |cut -d \| -f 1 )" + rev="$( echo "${line}" |cut -d \| -f 2 )" + br="$( echo "${line}" |cut -d \| -f 3 )" + desc="$( echo "${line}" |cut -d \| -f 4- )" + + case "${br}" in + ${branch}) ;; + [0-9]*.*) continue;; + *) ;; + esac + + case "${desc}" in + Merge.) continue;; + *": close "*" branch"*) continue;; +# *\(merged\)) continue;; + esac + + author="$( echo "${author}" |sed -r -e 's/"//g;' )" + + if [ ! "${prev_author}" = "${author}" ]; then + printf "\n" + printf " ${author}:\n" + prev_author="${author}" + fi + rev="$( echo "${rev}" |sed -r -e 's/^0*//;' )" + + printf "%s\n" "${desc}" \ + |fmt -w 65 \ + |(first=1; while read l; do + if [ -n "${first}" ]; then + printf " [%*d] %s\n" ${rev_w} ${rev} "${l}" + first= + else + printf " %*.*s %s\n" ${rev_w} ${rev_w} '' "${l}" + fi + done) + done +} + +print_diffstat() { + printf "\nThe diffstat follows:\n\n" + hg diff -r "${r1}:${r2}" --color=never \ + |diffstat -r 2 -p 1 -w 10 \ + |tail -n 1 \ + |sed -r -e 's/^ */ /;' + + hg diff -r "${r1}:${r2}" --color=never \ + |diffstat -f 1 -r 2 -p 1 -w 10 \ + |head -n -1 \ + |while read file line; do + if [ ${#file} -gt 57 ]; then + file="...$( echo "${file}" |sed -r -e 's/^.*(.{54})$/\1/;' )" + fi + printf " %-57s %s\n" "${file}" "${line}" + done +} + +ver_M="$( printf "${version}" |cut -d . -f 1 )" +ver_m="$( printf "${version}" |cut -d . -f 2 )" +ver_p="$( printf "${version}" |cut -d . -f 3 )" + +prefix="$(pwd)/crosstool-ng-${version}" +pushd "${repos}" >/dev/null 2>&1 + +printf "Checking for existing tag: " +if hg tags |grep -E '^'"crosstool-ng-${version}"'\>' >/dev/null; then + printf "already tagged\n" + exit 1 +fi +printf "no\n" + +if [ ${ver_p} -eq 0 ]; then + print_mail="yes" + print_intro_changelog="print_intro_changelog_full_release" + label="parent" + msg="create maintenance branch, (update|bump) version to [[:digit:]]+"'\'".[[:digit:]]+"'\'".0"'$' + branch="default" + log_offset=0 +else + print_mail="no" + print_intro_changelog="print_intro_changelog_bug_fix" + label="changeset" + msg="(update|bump) version to ${ver_M}"'\'".${ver_m}"'\'".$((ver_p-1))"'\+hg$' + branch="${ver_M}.${ver_m}" + log_offset=1 +fi + +printf "Computing boundary revisions:" +gen_bound_revs +printf " %d:%d\n" ${r1} ${r2} + +printf "Tagging release:" +hg up "${branch}" >/dev/null +if [ ${ver_p} -eq 0 ]; then + printf " update version" + hg branch "${ver_M}.${ver_m}" >/dev/null + echo "${version}" >".version" + hg ci -m "${ver_M}.${ver_m}: create maintenance branch, update version to ${version}" +else + printf " update version" + echo "${version}" >".version" + hg ci -m "${ver_M}.${ver_m}: update version to ${version}" +fi + +printf ", tag" +hg tag -m "Tagging release ${version}" crosstool-ng-${version} + +printf ", update version" +echo "${version}+hg" >".version" +hg ci -m "${ver_M}.${ver_m}: update version to ${version}+hg" + +printf ", date" +date="$( hg log -r crosstool-ng-${version} --template '{date|isodate}\n' \ + |sed -r -e 's/-|://g; s/ /./; s/ //;' \ + )" +printf ", done.\n" + +if [ ${ver_p} -eq 0 ]; then + printf "Generating release mail:" + printf " intro" + print_intro_mail > "${prefix}.mail" + printf ", stats" + print_author_stats >>"${prefix}.mail" + printf ", shortlog" + print_author_shortlog >>"${prefix}.mail" + printf ", done.\n" +fi + +printf "Generating release changelog:" +printf " intro" +${print_intro_changelog} > "${prefix}.changelog" +printf ", stats" +print_author_stats >>"${prefix}.changelog" +printf ", shortlog" +print_author_shortlog >>"${prefix}.changelog" +printf ", diffstat" +print_diffstat >>"${prefix}.changelog" +printf ", done.\n" + +popd >/dev/null 2>&1 + +printf "Creating tarball:" +prefix="crosstool-ng-${version}" +printf " cloning" +hg clone "${repos}" "${prefix}" >/dev/null +hg up -R "${prefix}" "${prefix}" >/dev/null +date="$( hg log -R "${prefix}" -r "${prefix}" --template '{date|rfc822date}\n' )" +printf ", purging" +rm -rf "${prefix}/"{.hg,.hgtags,.hgignore} +printf ", tarball" +tar cjf "${prefix}.tar.bz2" "${prefix}" +printf ", sum" +for s in md5 sha1 sha512; do + ${s}sum "${prefix}.tar.bz2" >"${prefix}.tar.bz2.${s}" +done +printf ", cleaning" +rm -rf "${prefix}" +printf ", touch" +touch -d "${date}" "${prefix}"* +printf ", done.\n" + +if [ ${ver_p} -eq 0 ]; then + printf "\nAn editor will be launched for you to edit the mail.\n" + read -p "Press enter when ready..." foo + cp "${prefix}.mail"{,.orig} + vi "${prefix}.mail" + diff -du -U 1 "${prefix}.mail"{.orig,} |patch -p0 "${prefix}.changelog" >/dev/null +fi + +printf "\nAn editor will be launched for you to review the changelog.\n" +read -p "Press enter when ready..." foo +vi "${prefix}.changelog" + +printf "\nNow, you can push the changes with: hg push -R '${repos}'\n" -- cgit v0.10.2-6-g49f6