#!/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