 7210e9470e
			
		
	
	7210e9470e
	
	
	
		
			
			Change-Id: I7f23b8b8e5136cb56768bac3a7473e6df5ee4993 Signed-off-by: Dave Barach <dave@barachs.net>
		
			
				
	
	
		
			308 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			308 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| # Copyright (c) 2015 Cisco and/or its affiliates.
 | |
| # Licensed under the Apache License, Version 2.0 (the "License");
 | |
| # you may not use this file except in compliance with the License.
 | |
| # You may obtain a copy of the License at:
 | |
| #
 | |
| #     http://www.apache.org/licenses/LICENSE-2.0
 | |
| #
 | |
| # Unless required by applicable law or agreed to in writing, software
 | |
| # distributed under the License is distributed on an "AS IS" BASIS,
 | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| # See the License for the specific language governing permissions and
 | |
| # limitations under the License.
 | |
| 
 | |
| # This aptly-named script verifies and fixes time ordering
 | |
| # problems with Makefile.{am,in} aclocal.m4 configure* files.
 | |
| 
 | |
| set -eu
 | |
| #set -vx
 | |
| 
 | |
| touch=""
 | |
| commit=""
 | |
| comma_v=""
 | |
| aclocal=""
 | |
| optimize=""
 | |
| 
 | |
| # The old autowank scheme used "touch <foo> ; sleep 1"
 | |
| # to ensure differentiable, ordered timestamps. Worked, but
 | |
| # took N seconds given N files to fix. We have an example
 | |
| # which wastes multiple minutes given the old scheme.
 | |
| #
 | |
| # This version generates a sequence of timestamps 
 | |
| # starting an hour ago. That gives us
 | |
| # lots to play with, in case some obnoxious program feels the need
 | |
| # to complain about timestamps in the future.
 | |
| 
 | |
| # If we're in UTC+N land, generate UTC+(N+1) 
 | |
| # If we're in UTC-N land, generate UTC-(N-1)
 | |
| 
 | |
| my_tz=`date +%z`
 | |
| sign=`echo $my_tz | sed -n -e 's/^\(.\{1\}\).*$/\1/p'`
 | |
| t=`echo $my_tz | sed -n -e 's/^\(.\{1\}\)//p'`
 | |
| tz_hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
 | |
| tz_hour=`echo $tz_hour | sed 's/^0//'`
 | |
| 
 | |
| if [ $sign = "-" ] ; then
 | |
|     sign="+"
 | |
|     let tz_hour=$tz_hour+1
 | |
|     if [[ $tz_hour -ge "24" ]] ; then
 | |
|         tz_hour=0
 | |
|     fi
 | |
| else
 | |
|     sign="-"
 | |
|     let tz_hour=$tz_hour-1 || true
 | |
|     if [[ $tz_hour -lt "0" ]] ; then
 | |
|         tz_hour=23
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| # Timestamp, an hour ago:
 | |
| ts_begin=`TZ=UTC${sign}${tz_hour} date +%Y%m%d%H%M.%S`
 | |
| 
 | |
| # break into constituent parts
 | |
| year=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\).*$/\1/p'`
 | |
| t=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\)//p'`
 | |
| month=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
 | |
| t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
 | |
| day=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
 | |
| t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
 | |
| hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
 | |
| t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
 | |
| min=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
 | |
| t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
 | |
| sec=`echo $t | sed -n -e 's/\.//p'`
 | |
| 
 | |
| # How many days in the current month?
 | |
| # Good until someone changes the calendar rules
 | |
| days_in_current_month() {
 | |
|     if [[ $month -eq 9 || $month -eq 4 \
 | |
|         || $month -eq 6 || $month -eq 11 ]] ; then
 | |
| 	return 30;
 | |
|     fi
 | |
|     if [[ $month -eq 2 ]] ; then
 | |
| 	let t=($year/400)*400
 | |
| 	if [[ $t -eq $year ]] ; then
 | |
| 	    return 29;
 | |
| 	fi
 | |
| 	let t=($year/100)*100
 | |
| 	if [[ $t -eq $year ]] ; then
 | |
| 	    return 28;
 | |
| 	fi
 | |
| 	let t=($year/4)*4
 | |
| 	if [[ $t -eq $year ]] ; then
 | |
| 	    return 29;
 | |
| 	fi
 | |
| 	return 28;
 | |
|     fi
 | |
|     return 31;
 | |
| }
 | |
| 
 | |
| # The next timestamp to issue via touch
 | |
| # A real hemorrhoid because bash isnt easily convinced
 | |
| # that 08 is a decimal number
 | |
| next_ts() {
 | |
|     sec=`echo $sec | sed 's/^0//'`
 | |
|     let sec=$sec+1
 | |
|     if [[ "$sec" -lt "60" ]] ; then
 | |
|         if [[ "$sec" -lt "10" ]] ; then
 | |
|             sec=0$sec
 | |
|         fi
 | |
| 	return 0;
 | |
|     fi
 | |
|     sec="00"
 | |
|     min=`echo $min | sed 's/^0//'`
 | |
|     let min=$min+1
 | |
|     if [[ "$min" -lt "60" ]] ; then
 | |
|         if [[ "$min" -lt "10" ]] ; then
 | |
|             min=0$min
 | |
|         fi
 | |
| 	return 0;
 | |
|     fi
 | |
|     min="00"
 | |
|     hour=`echo $hour | sed 's/^0//'`
 | |
|     let hour=$hour+1
 | |
|     if [[ "$hour" -lt "24" ]] ; then
 | |
|         if [[ "$hour" -lt "10" ]] ; then
 | |
|             hour=0$hour
 | |
|         fi
 | |
| 	return 0;
 | |
|     fi
 | |
|     hour="00"
 | |
|     days_in_current_month
 | |
|     days_in_month=$?
 | |
|     if [[ "$day" -lt "$days_in_month" ]] ; then
 | |
|         day=`echo $day | sed 's/^0//'`
 | |
| 	let day=$day+1
 | |
|         if [[ "$day" -lt "10" ]] ; then
 | |
|             day=0$day
 | |
|         fi
 | |
| 	return 0;
 | |
|     fi
 | |
|     day="01"
 | |
|     month=`echo $month | sed 's/^0//'`
 | |
|     let month=$month+1
 | |
|     if [[ "$month" -lt "13" ]] ; then
 | |
|         if [[ "$month" -lt "10" ]] ; then
 | |
|             month=0$month
 | |
|         fi
 | |
| 	return 0;
 | |
|     fi
 | |
|     month="01"
 | |
|     let year=$year+1
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| while [ $# != 0 ] ; do
 | |
|   case "$1" in
 | |
|     (--commav) comma_v=",v" ;;
 | |
|     (--touch) touch=yes ;;
 | |
|     (--aclocal) aclocal=yes ;;
 | |
|     (--nooptimize) optimize="" ;;
 | |
|     (--commit=*) commit="$1" ;;
 | |
|     (*) echo "$0: usage [--touch|--commit|]" > /dev/stderr
 | |
|         exit 17 ;;
 | |
|   esac
 | |
|   shift
 | |
| done
 | |
| 
 | |
| if [ "${aclocal}" != "" ] ; then
 | |
|     if [ -f aclocal.m4 ] ; then
 | |
|         echo touching aclocal.m4
 | |
|         sleep 1
 | |
|         touch aclocal.m4
 | |
|     else
 | |
|         echo aclocal.m4 not found
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| if [ "${comma_v}" != "" -a "${commit}" != "" ] ; then
 | |
|   echo "No, you may NOT molest ,v files directly.  Go away." > /dev/stderr
 | |
|   exit 1
 | |
| fi
 | |
| 
 | |
| function touchme ()
 | |
| {
 | |
|   local victim="${1}"
 | |
|   shift
 | |
|   local touchmebaby=""
 | |
|   local sein="is"
 | |
|   local newer="no"
 | |
|   local older="no"
 | |
| 
 | |
|   if [ ! -r "$victim" ] ; then
 | |
|     return
 | |
|   fi
 | |
| 
 | |
|   while [ $# != 0 ] ; do
 | |
|     if [ "${1}" -nt "${victim}" ] ; then
 | |
|         newer="yes"
 | |
|     fi
 | |
|     if [ "${1}" -ot "${victim}" ] ; then
 | |
|         older="yes"
 | |
|     fi
 | |
|     if [ "${newer}" = "no" -a "${older}" = "no" ] ; then
 | |
|         newer="yes"
 | |
|     fi
 | |
| 
 | |
|     if [ "${newer}" = "yes" ] ; then
 | |
|       if [ "${touchmebaby}" = "" ] ; then
 | |
|         touchmebaby="${1}"
 | |
|       else
 | |
|         sein="are"
 | |
|         touchmebaby="${touchmebaby} ${1}"
 | |
|       fi
 | |
|     fi
 | |
|     shift
 | |
|   done
 | |
|   if [ -n "${touchmebaby}" ] ; then
 | |
|     echo "*** ${touchmebaby} ${sein} newer than ${victim}  "
 | |
|     if [ -n "${touch}" ] ; then
 | |
|       # 
 | |
|       # This is the old version, in case something backfires...
 | |
|       if [ "${optimize}" != "yes" ] ; then 
 | |
|           echo "Fixing " ;touch -c "$victim" ; sleep 1
 | |
|       else
 | |
|           echo "Fixing "
 | |
|       # echo touch -c -t $year$month$day$hour$min.$sec "$victim"
 | |
|           touch -c -t $year$month$day$hour$min.$sec "$victim"
 | |
|           next_ts
 | |
|       fi
 | |
|     fi
 | |
|   fi
 | |
| }
 | |
| 
 | |
| makefileins="`/usr/bin/find . -name Attic -prune -o -name Makefile.in${comma_v}`"
 | |
| 
 | |
| # aclocal.m4 depends on ***/Makefile.am, configure.ac, acinclude.m4, *.m4 crap
 | |
| touchme aclocal.m4${comma_v} \
 | |
|         `/usr/bin/find . -name Attic -prune -o -name Makefile.am${comma_v}` \
 | |
|         "configure.in${comma_v}" "configure.ac${comma_v}" \
 | |
|         "acinclude.m4${comma_v}"
 | |
| 
 | |
| # Makefile.in must be newer than Makefile.am
 | |
| for f in $makefileins ; do
 | |
|   d="`dirname ${f}`"
 | |
|   touchme "${d}/Makefile.in${comma_v}" "${d}/Makefile.am${comma_v}"
 | |
| done
 | |
| 
 | |
| # Makefile.in depends on aclocal.m4
 | |
| for f in $makefileins ; do
 | |
|   d="`dirname $f`"
 | |
|   touchme "${d}/Makefile.in${comma_v}" "aclocal.m4${comma_v}"
 | |
| done
 | |
| 
 | |
| # config.in must be newer than aclocal.m4 and configure.ac
 | |
| if [ -f "config.in${comma_v}" ] ; then
 | |
|   touchme "config.in${comma_v}" "aclocal.m4${comma_v}" \
 | |
|                                 "configure.ac${comma_v}" \
 | |
|                                 "configure.in${comma_v}"
 | |
| fi
 | |
| 
 | |
| # config.h.in (or More Thoroughly Modern configh.in)
 | |
| # must be newer than aclocal.m4 and (obsolete) acconfig.h
 | |
| for c_h_in in config.h.in configh.in ; do
 | |
|   if [ -f "${c_h_in}${comma_v}" ]; then
 | |
|     touchme "${c_h_in}${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}"
 | |
|     #>>>> WTF?  Why?  This is nonsensical
 | |
|     ## ***/Makefile.in must be newer than config.h.in
 | |
|     #for f in $makefileins ; do
 | |
|     #  touchme "$f" "${c_h_in}${comma_v}"
 | |
|     #done
 | |
|   fi
 | |
| done
 | |
| 
 | |
| # configure must be newer than everything
 | |
| # touchme configure $makefileins -- why would this be needed?
 | |
| touchme "configure${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}" \
 | |
|                               "config.in${comma_v}" "config.h.in${comma_v}" \
 | |
|                               "configh.in${comma_v}"
 | |
| 
 | |
| if [ -n "${commit}" ] ; then
 | |
|   commit="${commit:9}" # strip off "--commit="
 | |
|   # First ***/Makefile.am,
 | |
|   # configure.in, configure.ac,
 | |
|   # ***/*.m4
 | |
|   # acconfig.h
 | |
|   cvs commit -m "${commit}" \
 | |
|              `for f in ${makefileins} ; do \
 | |
|                 [ -f "$${f%.in}.am" ] && echo "$${f%.in}.am" ; \
 | |
|               done` \
 | |
|              `[ -f configure.in ] && echo configure.in` \
 | |
|              `[ -f configure.ac ] && echo configure.ac` \
 | |
|              `[ -f acconfig.h ] && echo acconfig.h` \
 | |
|              `/usr/bin/find . -name '*.m4' -mindepth 2`
 | |
| 
 | |
|   # Next aclocal.m4
 | |
|   [ -f "aclocal.m4" ] && cvs commit -m "${commit}" aclocal.m4
 | |
| 
 | |
|   # Next config.in, config.h.in, configh.in
 | |
|   [ -f "config.in" ] && cvs commit -m "${commit}" config.in
 | |
|   [ -f "config.h.in" ] && cvs commit -m "${commit}" config.h.in
 | |
|   [ -f "configh.in" ] && cvs commit -m "${commit}" configh.in
 | |
| 
 | |
|   # Last ***/Makefile.in, configure
 | |
|   cvs commit -m "${commit}" ${makefileins} configure
 | |
| fi
 |