Improved unifier and checker script
authorBalazs Dezso <deba@inf.elte.hu>
Sun, 19 Oct 2008 16:19:32 +0200
changeset 324e05633b02e40
parent 322 6dbd5184c6a9
child 325 0fbbb4bc42dd
child 328 cdbff91c2166
Improved unifier and checker script

- Unify and check modes
- Several file listing modes
scripts/unify-sources.sh
     1.1 --- a/scripts/unify-sources.sh	Sun Oct 12 19:35:48 2008 +0100
     1.2 +++ b/scripts/unify-sources.sh	Sun Oct 19 16:19:32 2008 +0200
     1.3 @@ -3,9 +3,166 @@
     1.4  YEAR=`date +2003-%Y`
     1.5  HGROOT=`hg root`
     1.6  
     1.7 -function update_header() {
     1.8 +# file enumaration modes
     1.9 +
    1.10 +function all_files() {
    1.11 +    hg status -a -m -c |
    1.12 +    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
    1.13 +    while read file; do echo $HGROOT/$file; done
    1.14 +}
    1.15 +
    1.16 +function modified_files() {
    1.17 +    hg status -a -m |
    1.18 +    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
    1.19 +    while read file; do echo $HGROOT/$file; done
    1.20 +}
    1.21 +
    1.22 +function changed_files() {
    1.23 +    {
    1.24 +        if [ -n "$HG_PARENT1" ]
    1.25 +        then
    1.26 +            hg status --rev $HG_PARENT1:$HG_NODE -a -m
    1.27 +        fi
    1.28 +        if [ -n "$HG_PARENT2" ]
    1.29 +        then
    1.30 +            hg status --rev $HG_PARENT2:$HG_NODE -a -m
    1.31 +        fi
    1.32 +    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
    1.33 +    sort | uniq |
    1.34 +    while read file; do echo $HGROOT/$file; done
    1.35 +}
    1.36 +
    1.37 +function given_files() {
    1.38 +    for file in $GIVEN_FILES
    1.39 +    do
    1.40 +	echo $file
    1.41 +    done
    1.42 +}
    1.43 +
    1.44 +# actions
    1.45 +
    1.46 +function update_action() {
    1.47 +    if ! diff -q $1 $2 >/dev/null
    1.48 +    then
    1.49 +	echo -n " [$3 updated]"
    1.50 +	rm $2
    1.51 +	mv $1 $2
    1.52 +	CHANGED=YES
    1.53 +    fi
    1.54 +}
    1.55 +
    1.56 +function update_warning() {
    1.57 +    echo -n " [$2 warning]"
    1.58 +    WARNED=YES
    1.59 +}
    1.60 +
    1.61 +function update_init() {
    1.62 +    echo Update source files...
    1.63 +    TOTAL_FILES=0
    1.64 +    CHANGED_FILES=0
    1.65 +    WARNED_FILES=0
    1.66 +}
    1.67 +
    1.68 +function update_done() {
    1.69 +    echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
    1.70 +    echo $WARNED_FILES out of $TOTAL_FILES files has been warned.
    1.71 +}
    1.72 +
    1.73 +function update_begin() {
    1.74 +    ((TOTAL_FILES++))
    1.75 +    CHANGED=NO
    1.76 +    WARNED=NO
    1.77 +}
    1.78 +
    1.79 +function update_end() {
    1.80 +    if [ $CHANGED == YES ]
    1.81 +    then
    1.82 +	((++CHANGED_FILES))
    1.83 +    fi
    1.84 +    if [ $WARNED == YES ]
    1.85 +    then
    1.86 +	((++WARNED_FILES))
    1.87 +    fi
    1.88 +}
    1.89 +
    1.90 +function check_action() {
    1.91 +    if ! diff -q $1 $2 >/dev/null
    1.92 +    then
    1.93 +	echo -n " [$3 failed]"
    1.94 +	FAILED=YES
    1.95 +    fi
    1.96 +}
    1.97 +
    1.98 +function check_warning() {
    1.99 +    echo -n " [$2 warning]"
   1.100 +    WARNED=YES
   1.101 +}
   1.102 +
   1.103 +function check_init() {
   1.104 +    echo Check source files...
   1.105 +    FAILED_FILES=0
   1.106 +    WARNED_FILES=0
   1.107 +    TOTAL_FILES=0
   1.108 +}
   1.109 +
   1.110 +function check_done() {
   1.111 +    echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
   1.112 +    echo $WARNED_FILES out of $TOTAL_FILES files has been warned.
   1.113 +
   1.114 +    if [ $FAILED_FILES -gt 0 ]
   1.115 +    then
   1.116 +	return 1
   1.117 +    elif [ $WARNED_FILES -gt 0 ]
   1.118 +    then
   1.119 +	if [ "$WARNING" == 'INTERACTIVE' ]
   1.120 +	then
   1.121 +	    echo -n "Assume as normal behaviour? (yes/no) "
   1.122 +	    while read answer
   1.123 +	    do
   1.124 +		if [ "$answer" == 'yes' ]
   1.125 +		then
   1.126 +		    return 0
   1.127 +		elif [ "$answer" == 'no' ]
   1.128 +		then
   1.129 +		    return 1
   1.130 +		fi
   1.131 +		echo -n "Assume as normal behaviour? (yes/no) "		    
   1.132 +	    done
   1.133 +	elif [ "$WARNING" == 'WERROR' ]
   1.134 +	then
   1.135 +	    return 1
   1.136 +	fi
   1.137 +    fi
   1.138 +}
   1.139 +
   1.140 +function check_begin() {
   1.141 +    ((TOTAL_FILES++))
   1.142 +    FAILED=NO
   1.143 +    WARNED=NO
   1.144 +}
   1.145 +
   1.146 +function check_end() {
   1.147 +    if [ $FAILED == YES ]
   1.148 +    then
   1.149 +	((++FAILED_FILES))
   1.150 +    fi
   1.151 +    if [ $WARNED == YES ]
   1.152 +    then
   1.153 +	((++WARNED_FILES))
   1.154 +    fi
   1.155 +}
   1.156 +
   1.157 +
   1.158 +
   1.159 +# checks
   1.160 +
   1.161 +function header_check() {
   1.162 +    if echo $1 | grep -q -E 'Makefile\.am$'
   1.163 +    then
   1.164 +	return
   1.165 +    fi
   1.166 +
   1.167      TMP_FILE=`mktemp`
   1.168 -    FILE_NAME=$1
   1.169  
   1.170      (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
   1.171   *
   1.172 @@ -25,110 +182,156 @@
   1.173   *
   1.174   */
   1.175  "
   1.176 -	awk 'BEGIN { pm=0; }
   1.177 +    awk 'BEGIN { pm=0; }
   1.178       pm==3 { print }
   1.179       /\/\* / && pm==0 { pm=1;}
   1.180       /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
   1.181       /\*\// && pm==1 { pm=2;}
   1.182      ' $1
   1.183 -	) >$TMP_FILE
   1.184 +    ) >$TMP_FILE
   1.185  
   1.186 -    HEADER_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
   1.187 -
   1.188 -    rm $FILE_NAME
   1.189 -    mv $TMP_FILE $FILE_NAME
   1.190 +    "$ACTION"_action "$TMP_FILE" "$1" header
   1.191  }
   1.192  
   1.193 -function update_tabs() {
   1.194 +function tabs_check() {
   1.195 +    if echo $1 | grep -q -v -E 'Makefile\.am$'
   1.196 +    then
   1.197 +        OLD_PATTERN=$(echo -e '\t')
   1.198 +        NEW_PATTERN='        '
   1.199 +    else
   1.200 +        OLD_PATTERN='        '
   1.201 +        NEW_PATTERN=$(echo -e '\t')
   1.202 +    fi
   1.203      TMP_FILE=`mktemp`
   1.204 -    FILE_NAME=$1
   1.205 +    cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
   1.206  
   1.207 -    cat $1 |
   1.208 -    sed -e 's/\t/        /g' >$TMP_FILE
   1.209 -
   1.210 -    TABS_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
   1.211 -
   1.212 -    rm $FILE_NAME
   1.213 -    mv $TMP_FILE $FILE_NAME
   1.214 +    "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
   1.215  }
   1.216  
   1.217 -function remove_trailing_space() {
   1.218 +function spaces_check() {
   1.219      TMP_FILE=`mktemp`
   1.220 -    FILE_NAME=$1
   1.221 +    cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
   1.222  
   1.223 -    cat $1 |
   1.224 -    sed -e 's/ \+$//g' >$TMP_FILE
   1.225 -
   1.226 -    SPACES_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
   1.227 -
   1.228 -    rm $FILE_NAME
   1.229 -    mv $TMP_FILE $FILE_NAME
   1.230 +    "$ACTION"_action "$TMP_FILE" "$1" 'spaces'
   1.231  }
   1.232  
   1.233 -function long_line_test() {
   1.234 -    cat $1 |grep -q -E '.{81,}'
   1.235 -}
   1.236 -
   1.237 -function update_file() {
   1.238 -    echo -n '    update' $i ...
   1.239 -
   1.240 -    update_header $1
   1.241 -    update_tabs $1
   1.242 -    remove_trailing_space $1
   1.243 -
   1.244 -    CHANGED=NO;
   1.245 -    if [[ $HEADER_CH = YES ]];
   1.246 +function long_lines_check() {
   1.247 +    if cat $1 | grep -q -E '.{81,}'
   1.248      then
   1.249 -	echo -n '  [header updated]'
   1.250 -	CHANGED=YES;
   1.251 -    fi
   1.252 -    if [[ $TABS_CH = YES ]];
   1.253 -    then
   1.254 -	echo -n ' [tabs removed]'
   1.255 -	CHANGED=YES;
   1.256 -    fi
   1.257 -    if [[ $SPACES_CH = YES ]];
   1.258 -    then
   1.259 -	echo -n ' [trailing spaces removed]'
   1.260 -	CHANGED=YES;
   1.261 -    fi
   1.262 -    if long_line_test $1 ;
   1.263 -    then
   1.264 -	echo -n ' [LONG LINES]'
   1.265 -	((LONG_LINE_FILES++))
   1.266 -    fi
   1.267 -    echo
   1.268 -    if [[ $CHANGED = YES ]];
   1.269 -    then
   1.270 -	((CHANGED_FILES++))
   1.271 +	"$ACTION"_warning $1 'long lines'
   1.272      fi
   1.273  }
   1.274  
   1.275 -CHANGED_FILES=0
   1.276 -TOTAL_FILES=0
   1.277 -LONG_LINE_FILES=0
   1.278 -if [ $# == 0 ]; then
   1.279 -    echo Update all source files...
   1.280 -    for i in `hg manifest|grep -E  '\.(cc|h|dox)$'`
   1.281 +# process the file
   1.282 +
   1.283 +function process_file() {
   1.284 +    echo -n "    $ACTION " $1...
   1.285 +
   1.286 +    CHECKING="header tabs spaces long_lines"
   1.287 +
   1.288 +    "$ACTION"_begin $1
   1.289 +    for check in $CHECKING
   1.290      do
   1.291 -	update_file $HGROOT/$i
   1.292 -	((TOTAL_FILES++))
   1.293 +	"$check"_check $1
   1.294      done
   1.295 -    echo '  done.'
   1.296 -else
   1.297 -    for i in $*
   1.298 +    "$ACTION"_end $1
   1.299 +    echo
   1.300 +}
   1.301 +
   1.302 +function process_all {
   1.303 +    "$ACTION"_init
   1.304 +    while read file
   1.305      do
   1.306 -	update_file $i
   1.307 -	((TOTAL_FILES++))
   1.308 -    done
   1.309 +	process_file $file
   1.310 +    done < <($FILES)
   1.311 +    "$ACTION"_done
   1.312 +}
   1.313 +
   1.314 +while [ $# -gt 0 ]
   1.315 +do
   1.316 +    
   1.317 +    if [ "$1" == '--help' ] || [ "$1" == '-h' ]
   1.318 +    then
   1.319 +	echo -n \
   1.320 +"Usage:
   1.321 +  $0 [OPTIONS] [files]
   1.322 +Options:
   1.323 +  --dry-run|-n
   1.324 +     Check the given files, but do not modify them.
   1.325 +  --interactive|-i
   1.326 +     If --dry-run is specified and files are warned then a message is
   1.327 +     prompted whether the warnings should be turned to errors.
   1.328 +  --werror|-w
   1.329 +     If --dry-run is specified and the warnings are turned to errors.
   1.330 +  --all|-a
   1.331 +     All files in the repository will be checked.
   1.332 +  --modified|-m
   1.333 +     Check only the modified source files. This option is proper to
   1.334 +     use before a commit. E.g. all files which are modified or added
   1.335 +     into the repository will be updated.
   1.336 +  --changed|-c
   1.337 +     Check only the changed source files compared to the parent(s) of
   1.338 +     the current hg node.  This option is proper to use as hg hook
   1.339 +     script. E.g. to check all your commited source files with this
   1.340 +     script add the following section to the appropriate .hg/hgrc
   1.341 +     file.
   1.342 +
   1.343 +       [hooks]
   1.344 +       pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
   1.345 +
   1.346 +  --help|-h
   1.347 +     Print this help message.
   1.348 +  files
   1.349 +     The files to check/unify. If no file names are given, the
   1.350 +     modified source will be checked/unified
   1.351 +
   1.352 +"
   1.353 +        exit 0
   1.354 +    elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
   1.355 +    then
   1.356 +	[ -n "$ACTION" ] && echo "Invalid option $1" >&2 && exit 1
   1.357 +	ACTION=check
   1.358 +    elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
   1.359 +    then
   1.360 +	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
   1.361 +	FILES=all_files
   1.362 +    elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
   1.363 +    then
   1.364 +	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
   1.365 +	FILES=changed_files
   1.366 +    elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
   1.367 +    then
   1.368 +	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
   1.369 +	FILES=modified_files
   1.370 +    elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
   1.371 +    then
   1.372 +	[ -n "$WARNING" ] && echo "Invalid option $1" >&2 && exit 1
   1.373 +	WARNING='INTERACTIVE'
   1.374 +    elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
   1.375 +    then
   1.376 +	[ -n "$WARNING" ] && echo "Invalid option $1" >&2 && exit 1
   1.377 +	WARNING='WERROR'
   1.378 +    elif [ $(echo $1 | cut -c 1) == '-' ]
   1.379 +    then
   1.380 +	echo "Invalid option $1" >&2 && exit 1
   1.381 +    else
   1.382 +	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
   1.383 +	GIVEN_FILES=$@
   1.384 +	FILES=given_files
   1.385 +	break
   1.386 +    fi
   1.387 +    
   1.388 +    shift
   1.389 +done
   1.390 +
   1.391 +if [ -z $FILES ]
   1.392 +then
   1.393 +    FILES=modified_files
   1.394  fi
   1.395 -echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
   1.396 -if [[ $LONG_LINE_FILES -gt 1 ]]; then
   1.397 -    echo
   1.398 -    echo WARNING: $LONG_LINE_FILES files contains long lines!    
   1.399 -    echo
   1.400 -elif [[ $LONG_LINE_FILES -gt 0 ]]; then
   1.401 -    echo
   1.402 -    echo WARNING: a file contains long lines!
   1.403 -    echo
   1.404 +
   1.405 +if [ -z $ACTION ]
   1.406 +then
   1.407 +    ACTION=update
   1.408  fi
   1.409 +
   1.410 +process_all