scripts/mk-release.sh
changeset 1822 7893174d0fe8
child 1833 a4c371728d07
     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"