| #!/bin/bash |
| |
| # This script is a helper to process backports in batch from the main |
| # spreadsheet. |
| |
| # Typical use: export the spreadsheet page in TSV (tab-separated |
| # values), then call this script with the TSV as std input. |
| # The script prints the list of backflip commands needed to perform |
| # all the backports described in the TSV file. |
| # |
| # For simple backports (with no dependency), it's as easy as calling |
| # backflip with the revision number as parameter. |
| |
| # When several commits have to be stacked, the script parses the |
| # 'Stack with' column and build the stack of commits to be backported |
| # together. The dependencies need not be all on the same line, nor in |
| # order. The script builds the union of the stacks describing one |
| # backport. |
| |
| # Simple backports are generated as they are read, stacks are |
| # processed at the end of the script, once all the TSV table has been |
| # parsed. |
| |
| lineno=0 |
| declare -A stack |
| verbose= |
| |
| trap "rm -f /tmp/backflip-stack.keys.$$ /tmp/backflip-stack.$$" EXIT |
| |
| usage() |
| { |
| echo Usage: $0 [-v] '<' TSV-table |
| exit 1 |
| } |
| |
| if [ $# -gt 1 ] |
| then |
| usage |
| fi |
| |
| if [ x"$1" = x-v ] |
| then |
| verbose=1 |
| else |
| if [ x"$1" != x ] |
| then |
| usage |
| fi |
| fi |
| |
| while read line |
| do |
| lineno=$(( lineno = lineno + 1 )) |
| # We replace the tab separator by a comma in the sed command at |
| # the bottom of the loop. This is needed to use IFS. |
| saved_IFS=$IFS |
| IFS=',' |
| |
| set $line |
| IFS=$saved_IFS |
| |
| svn=$1 |
| fsf=$2 |
| linaro=$3 |
| summary=$4 |
| target=$5 |
| type=$6 |
| stackwith=$7 |
| notes=$8 |
| status=$9 |
| owner=${10} |
| author=${11} |
| #echo svn $svn fsf $fsf linaro $linaro |
| |
| case $svn in |
| Colors*|revs) |
| [ $verbose ] && echo "skipping line $lineno" |
| continue |
| ;; |
| "") |
| [ $verbose ] && echo "skipping line $lineno with empty 1st elem" |
| continue |
| ;; |
| [0-9][0-9][0-9][0-9][0-9][0-9]) |
| [ $verbose ] && echo "Handling revision $svn" |
| if [ x"$fsf" != x ]; then |
| [ $verbose ] && echo "$svn will come from branch merge, skipping (fsf rev=$fsf)" |
| continue |
| fi |
| case $status in |
| on*going) |
| [ $verbose ] && echo "$svn backport already on-going" |
| continue |
| ;; |
| esac |
| case $linaro in |
| "") |
| [ $verbose ] && echo "$svn needs to be backported, alone" |
| echo backflip -x $svn "|| echo failed to backport $svn" |
| ;; |
| auto) |
| [$verbose ] && echo "$svn backported automatically, skipping" |
| continue |
| ;; |
| no) |
| [ $verbose ] && echo "$svn not wanted, skipping" |
| continue |
| ;; |
| stack) |
| [ $verbose ] && echo "$svn should be stacked with $stackwith" |
| # Sort stack, use a tmp file to avoid shell |
| # sub-processes. |
| for rev in $stackwith |
| do |
| echo $rev |
| done | sort > /tmp/backflip-stack.$$ |
| while read rev |
| do |
| # The stacks we build are ordered (increasing |
| # revisions), but there may be overlaps. We'll |
| # merge them later. |
| |
| # revisions in the 'svn' column are sorted, so |
| # if $rev < $svn, it means that this stack has |
| # already been started. Append to the existing |
| # stack. |
| if [ $rev -lt $svn ] |
| then |
| stack[${rev}]="${stack[${rev}]} ${svn}" |
| else |
| stack[${svn}]="${stack[${svn}]} $rev" |
| fi |
| done < /tmp/backflip-stack.$$ |
| continue # FIXME |
| ;; |
| *not*yet) |
| [ $verbose ] && echo "$svn is part of a stack which is not ready yet" |
| continue |
| ;; |
| "via merge") |
| echo "ERROR: rev $svn should already be handled" |
| continue |
| ;; |
| *) |
| [ $verbose ] && echo "$svn type $linaro already backported, skipping" |
| continue |
| ;; |
| esac |
| ;; |
| *) |
| echo "Unsupported line $svn" |
| ;; |
| esac |
| done < <(sed -e 's/,//g' -e 's/ /,/g') |
| |
| # Sort the keys, to process them in order, so that we can build the |
| # union of the stacks in case of overlap |
| for key in ${!stack[@]} |
| do |
| echo ${key} |
| done | sort > /tmp/backflip-stack.keys.$$ |
| |
| for key in `cat /tmp/backflip-stack.keys.$$` |
| do |
| backport= |
| # If the stack of $key is empty, it means it has already been |
| # processed as part of a previous stack: ignore it. |
| if [ x"${stack[${key}]}" != x ] |
| then |
| backport="${key}" |
| for rev in ${stack[${key}]} |
| do |
| backport="${backport} ${rev} ${stack[${rev}]}" |
| stack[${rev}]= |
| done |
| [ $verbose ] && echo stack: ${backport} |
| echo backflip -x ${backport} "|| echo failed to backport ${backport}" |
| fi |
| done |