summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/mk-release.sh308
1 files changed, 308 insertions, 0 deletions
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} <repos_dir> <M.m.p>
+ _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"