scripts/mk-release.sh
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Jan 22 23:20:18 2011 +0100 (2011-01-22)
changeset 2305 2ed26c646568
parent 1943 48e107b35ba9
child 2725 32aa23619dfd
permissions -rwxr-xr-x
scripts: create the makeinfo wrapper before we set PATH

If we set PATH to the tools wrappers before we create the
makeinfo wrapper, then we may well wrap an existing wrapper
from a previous run.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     1 #!/bin/bash
     2 #set -x
     3 
     4 export LC_ALL=C
     5 
     6 my_name="$( basename "${0}" )"
     7 
     8 usage() {
     9     cat <<-_EOF_
    10 		Usage:
    11 		    ${my_name} <repos_dir> <M.m.p>
    12 	_EOF_
    13 }
    14 
    15 repos="${1}"
    16 version="${2}"
    17 
    18 [ -n "${repos}"   ] || { usage; exit 1; }
    19 [ -d "${repos}"   ] || { printf "${my_name}: ${repos}: no such file or directory\n"; exit 1; }
    20 [ -n "${version}" ] || { usage; exit 1; }
    21 
    22 gen_bound_revs() {
    23     r1=$( hg log    \
    24           |awk 'BEGIN {
    25                   found=0;
    26                 }
    27                 $1=="'"${label}"':" {
    28                   split($2,a,":"); rev=a[1];
    29                 }
    30                 $0~/^summary:[[:space:]]*[[:digit:]]+\.[[:digit:]]+: '"${msg}"'/ \
    31                 && found==0 {
    32                   printf( "%d\n", rev ); found=1;
    33                 }'
    34         )
    35 
    36     r2=$( hg log -b "${branch}" \
    37           |awk '$1=="changeset:" {
    38                   split($2,a,":");
    39                   printf( "%d\n", a[1] );
    40                   nextfile;
    41                 }'
    42         )
    43 
    44     r1_log=$((r1+log_offset))
    45     if [ ${#r1_log} -gt ${#r2} ]; then
    46         rev_w=${#r1_log}
    47     else
    48         rev_w=${#r2}
    49     fi
    50 }
    51 
    52 print_intro_mail() {
    53     cat <<-_EOF_
    54 		Hello all!
    55 		
    56 		I'm pleased to announce the release of crosstool-NG ${version}!
    57 		
    58 		As usual, there has been quite a number of improvements, new features,
    59 		and bug fixes all around. The most notable changes are listed below:
    60 		
    61 		YEM:
    62 		YEM: PUT YOUR MESSAGE HERE
    63 		YEM:
    64 		
    65 		This marks the beginning of the ${ver_M}.${ver_m} maintenance branch, and the end of
    66 		the previous maintenance branch. As always, comments and suggestions
    67 		are most welcome!
    68 		
    69 		The release can be found at the following URLs:
    70 		Changelog: http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.changelog
    71 		Tarball:   http://ymorin.is-a-geek.org/download/crosstool-ng/crosstool-ng-${version}.tar.bz2
    72 		Patches:   http://ymorin.is-a-geek.org/download/crosstool-ng/01-fixes/${version}/
    73 		
    74 		As a reminder, the home for crosstool-NG is:
    75 		http://ymorin.is-a-geek.org/projects/crosstool
    76 		
    77 		Crosstool-NG also has a Freshmeat page:
    78 		http://freshmeat.net/projects/crosstool-ng
    79 	_EOF_
    80 }
    81 
    82 print_intro_changelog_full_release() {
    83     cat <<-_EOF_
    84 		crosstool-NG ${version} -- ${date}
    85 		
    86 		This is a feature-release. Significant changes are:
    87 		
    88 		YEM:
    89 		YEM: PUT YOUR MESSAGE HERE
    90 		YEM:
    91 	_EOF_
    92 }
    93 
    94 print_intro_changelog_bug_fix() {
    95     cat <<-_EOF_
    96 		crosstool-NG ${version} -- ${date}
    97 		
    98 		This is a bug-fix-only release.
    99 	_EOF_
   100 }
   101 
   102 print_author_stats() {
   103     printf "\nMany thanks to the people who contributed to this release:\n\n"
   104     prev_author=""
   105     template='{author|person}\n'
   106     hg log -b "${branch}" -r "${r1_log}:${r2}"                  \
   107            --template "${template}"                             \
   108     |sed -r -e 's/"//g;'                                        \
   109     |awk -F '' '{
   110                   nb[$0]++;
   111                 }
   112                 END {
   113                   for( author in nb ) {
   114                     printf( "   %4d  %s\n", nb[author], author );
   115                   }
   116                 }'                                              \
   117     |sort -s -k1nr -k2
   118 }
   119 
   120 print_author_shortlog() {
   121     printf "\nHere is the per-author shortlog:\n"
   122     prev_author=""
   123     template='{author|person}|{rev}|{branches}|{desc|firstline}\n'
   124     hg log -b "${branch}" -r "${r1_log}:${r2}"              \
   125            --template "${template}"                         \
   126     |awk -F '' '{
   127                   n=split( $0,a,"|" );
   128                   printf( "%s", gensub("\"","","g",a[1]) );
   129                   printf( "|%0*d", '${rev_w}', a[2] );
   130                   for(i=3;i<=n;i++) {
   131                     printf( "|%s", a[i] );
   132                   }
   133                   printf( "\n" );
   134                 }'                                          \
   135     |sort                                                   \
   136     |while read line; do
   137         author="$( echo "${line}" |cut -d \| -f 1 )"
   138         rev="$( echo "${line}" |cut -d \| -f 2 )"
   139         br="$( echo "${line}" |cut -d \| -f 3 )"
   140         desc="$( echo "${line}" |cut -d \| -f 4- )"
   141 
   142         case "${br}" in
   143             ${branch})  ;;
   144             [0-9]*.*)    continue;;
   145             *) ;;
   146         esac
   147 
   148         case "${desc}" in
   149             Merge.)                 continue;;
   150             *": close "*" branch"*) continue;;
   151 #           *\(merged\))            continue;;
   152         esac
   153 
   154         author="$( echo "${author}" |sed -r -e 's/"//g;' )"
   155 
   156         if [ ! "${prev_author}" = "${author}" ]; then
   157             printf "\n"
   158             printf "    ${author}:\n"
   159             prev_author="${author}"
   160         fi
   161         rev="$( echo "${rev}" |sed -r -e 's/^0*//;' )"
   162 
   163         printf "%s\n" "${desc}"     \
   164         |fmt -w 65                  \
   165         |(first=1; while read l; do
   166             if [ -n "${first}" ]; then
   167                 printf "        [%*d] %s\n" ${rev_w} ${rev} "${l}"
   168                 first=
   169             else
   170                 printf "         %*.*s  %s\n" ${rev_w} ${rev_w} '' "${l}"
   171             fi
   172         done)
   173     done
   174 }
   175 
   176 print_diffstat() {
   177     printf "\nThe diffstat follows:\n\n"
   178     hg diff -r "${r1}:${r2}" --color=never  \
   179     |diffstat -r 2 -p 1 -w 10               \
   180     |tail -n 1                              \
   181     |sed -r -e 's/^ */    /;'
   182 
   183     hg diff -r "${r1}:${r2}" --color=never  \
   184     |diffstat -f 1 -r 2 -p 1 -w 10          \
   185     |head -n -1                             \
   186     |while read file line; do
   187         if [ ${#file} -gt 57 ]; then
   188             file="$( echo "${file}" |sed -r -e 's/^(.{,24}).*(.{28})$/\1.....\2/;' )"
   189         fi
   190         printf "    %-57s %s\n" "${file}" "${line}"
   191     done
   192 }
   193 
   194 print_short_diffstat() {
   195     printf "\nThe short diffstat follows:\n\n"
   196 
   197     eval total=$(( $(
   198         hg diff -r "${r1}:${r2}" --color=never "${i}"                               \
   199         |diffstat -r 2 -p 1 -w 10                                                   \
   200         |tail -n 1                                                                  \
   201         |sed -r -e 's/^[[:space:]]*[[:digit:]]+ files? changed(,[[:space:]]+|$)//;' \
   202                 -e 's/([[:digit:]]+)[^-\+]+\((-|\+)\)/\1/g;'                        \
   203                 -e 's/,//g; s/ /+/; s/^$/0/;'
   204     ) ))
   205     printf "    %-24.24s %5d(+/-)\n" "Total" ${total}
   206     others=${total}
   207 
   208     { for i in              \
   209         kconfig/            \
   210         patches/            \
   211         config/*/           \
   212         scripts/build/*/    \
   213         samples/            \
   214         ; do
   215         eval val=$(( $(
   216             hg diff -r "${r1}:${r2}" --color=never "${i}"                               \
   217             |diffstat -r 2 -p 1 -w 10                                                   \
   218             |tail -n 1                                                                  \
   219             |sed -r -e 's/^[[:space:]]*[[:digit:]]+ files? changed(,[[:space:]]+|$)//;' \
   220                     -e 's/([[:digit:]]+)[^-\+]+\((-|\+)\)/\1/g;'                        \
   221                     -e 's/,//g; s/ /+/; s/^$/0/;'
   222         ) ))
   223         if [ ${val} -gt $((total/100)) ]; then
   224             printf "%d %s\n" $(((1000*val)/total)) "${i}"
   225             others=$((others-val))
   226         fi
   227     done; printf "%d Others\n" $(((1000*others)/total)); }  \
   228     |sort -nr                                               \
   229     |{ while read v i; do
   230         if [ "${i}" = "Others" ]; then
   231             others=${v}
   232         else
   233             printf "    %-24.24s %3d.%d%%\n" "${i}" $((v/10)) $((v%10))
   234         fi
   235        done; printf "    %-24.24s %3d.%d%%\n" "Others" $((others/10)) $((others%10)); }
   236 }
   237 
   238 ver_M="$( printf "${version}" |cut -d . -f 1 )"
   239 ver_m="$( printf "${version}" |cut -d . -f 2 )"
   240 ver_p="$( printf "${version}" |cut -d . -f 3 )"
   241 
   242 prefix="$(pwd)/crosstool-ng-${version}"
   243 pushd "${repos}" >/dev/null 2>&1
   244 
   245 printf "Checking for existing tag: "
   246 if hg tags |grep -E '^'"crosstool-ng-${version}"'\>' >/dev/null; then
   247     printf "already tagged\n"
   248     exit 1
   249 fi
   250 printf "no\n"
   251 
   252 if [ ${ver_p} -eq 0 ]; then
   253     print_mail="yes"
   254     print_intro_changelog="print_intro_changelog_full_release"
   255     label="parent"
   256     msg="create maintenance branch, (update|bump) version to [[:digit:]]+"'\'".[[:digit:]]+"'\'".0"'$'
   257     branch="default"
   258     log_offset=0
   259 else
   260     print_mail="no"
   261     print_intro_changelog="print_intro_changelog_bug_fix"
   262     label="changeset"
   263     msg="(update|bump) version to ${ver_M}"'\'".${ver_m}"'\'".$((ver_p-1))"'\+hg$'
   264     branch="${ver_M}.${ver_m}"
   265     log_offset=1
   266 fi
   267 
   268 printf "Computing boundary revisions:"
   269 gen_bound_revs
   270 printf " %d:%d\n" ${r1} ${r2}
   271 
   272 printf "Tagging release:"
   273 hg up "${branch}" >/dev/null
   274 if [ ${ver_p} -eq 0 ]; then
   275     printf " update version"
   276     hg branch "${ver_M}.${ver_m}" >/dev/null
   277     echo "${version}" >".version"
   278     hg ci -m "${ver_M}.${ver_m}: create maintenance branch, update version to ${version}"
   279 else
   280     printf " update version"
   281     echo "${version}" >".version"
   282     hg ci -m "${ver_M}.${ver_m}: update version to ${version}"
   283 fi
   284 
   285 printf ", tag"
   286 hg tag -m "Tagging release ${version}" crosstool-ng-${version}
   287 
   288 printf ", update version"
   289 echo "${version}+hg" >".version"
   290 hg ci -m "${ver_M}.${ver_m}: update version to ${version}+hg"
   291 
   292 printf ", date"
   293 date="$( hg log -r crosstool-ng-${version} --template '{date|isodate}\n'    \
   294          |sed -r -e 's/-|://g; s/ /./; s/ //;'                              \
   295        )"
   296 printf ", done.\n"
   297 
   298 if [ ${ver_p} -eq 0 ]; then
   299     printf "Generating release mail:"
   300     printf " intro"
   301     print_intro_mail        > "${prefix}.mail"
   302     printf ", stats"
   303     print_author_stats      >>"${prefix}.mail"
   304     printf ", shortlog"
   305     print_author_shortlog   >>"${prefix}.mail"
   306     printf ", diffstat"
   307     print_short_diffstat    >>"${prefix}.mail"
   308     printf ", done.\n"
   309 fi
   310 
   311 printf "Generating release changelog:"
   312 printf " intro"
   313 ${print_intro_changelog}    > "${prefix}.changelog"
   314 printf ", stats"
   315 print_author_stats          >>"${prefix}.changelog"
   316 printf ", shortlog"
   317 print_author_shortlog       >>"${prefix}.changelog"
   318 printf ", diffstat"
   319 print_diffstat              >>"${prefix}.changelog"
   320 printf ", done.\n"
   321 
   322 popd >/dev/null 2>&1
   323 
   324 printf "Creating tarball:"
   325 prefix="crosstool-ng-${version}"
   326 printf " archive"
   327 hg archive --cwd "${repos}" -r "${prefix}" -X '.hg*' "$(pwd)/${prefix}.tar.bz2"
   328 date="$( hg log -R "${repos}" -r "${prefix}" --template '{date|rfc822date}\n' )"
   329 printf ", sum"
   330 for s in md5 sha1 sha512; do
   331     ${s}sum "${prefix}.tar.bz2" >"${prefix}.tar.bz2.${s}"
   332 done
   333 printf ", touch"
   334 touch -d "${date}" "${prefix}"*
   335 printf ", done.\n"
   336 
   337 if [ ${ver_p} -eq 0 ]; then
   338     printf "\nAn editor will be launched for you to edit the mail.\n"
   339     read -p "Press enter when ready..." foo
   340     cp "${prefix}.mail"{,.orig}
   341     vi "${prefix}.mail"
   342     diff -du -U 1 "${prefix}.mail"{.orig,} |patch -p0 "${prefix}.changelog" >/dev/null
   343     rm -f "${prefix}".{mail,changelog}.orig
   344 fi
   345 
   346 printf "\nAn editor will be launched for you to review the changelog.\n"
   347 read -p "Press enter when ready..." foo
   348 vi "${prefix}.changelog"
   349 
   350 printf "\nNow, you can push the changes with:   hg push -R '${repos}'\n"