Initial commit of vpp code.
[vpp.git] / build-root / autowank
1 #!/bin/bash
2
3 # Copyright (c) 2015 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # This aptly-named script verifies and fixes time ordering
17 # problems with Makefile.{am,in} aclocal.m4 configure* files.
18
19 set -eu
20 #set -vx
21
22 touch=""
23 commit=""
24 comma_v=""
25 aclocal=""
26 optimize=""
27
28 # The old autowank scheme used "touch <foo> ; sleep 1"
29 # to ensure differentiable, ordered timestamps. Worked, but
30 # took N seconds given N files to fix. We have an example
31 # which wastes multiple minutes given the old scheme.
32 #
33 # This version generates a sequence of timestamps 
34 # starting an hour ago. That gives us
35 # lots to play with, in case some obnoxious program feels the need
36 # to complain about timestamps in the future.
37
38 # If we're in UTC+N land, generate UTC+(N+1) 
39 # If we're in UTC-N land, generate UTC-(N-1)
40
41 my_tz=`date +%z`
42 sign=`echo $my_tz | sed -n -e 's/^\(.\{1\}\).*$/\1/p'`
43 t=`echo $my_tz | sed -n -e 's/^\(.\{1\}\)//p'`
44 tz_hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
45 tz_hour=`echo $tz_hour | sed 's/^0//'`
46
47 if [ $sign = "-" ] ; then
48     sign="+"
49     let tz_hour=$tz_hour+1
50     if [[ $tz_hour -ge "24" ]] ; then
51         tz_hour=0
52     fi
53 else
54     sign="-"
55     let tz_hour=$tz_hour-1 || true
56     if [[ $tz_hour -lt "0" ]] ; then
57         tz_hour=23
58     fi
59 fi
60
61 # Timestamp, an hour ago:
62 ts_begin=`TZ=UTC${sign}${tz_hour} date +%Y%m%d%H%M.%S`
63
64 # break into constituent parts
65 year=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\).*$/\1/p'`
66 t=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\)//p'`
67 month=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
68 t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
69 day=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
70 t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
71 hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
72 t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
73 min=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
74 t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
75 sec=`echo $t | sed -n -e 's/\.//p'`
76
77 # How many days in the current month?
78 # Good until someone changes the calendar rules
79 days_in_current_month() {
80     if [[ $month -eq 9 || $month -eq 4 \
81         || $month -eq 6 || $month -eq 11 ]] ; then
82         return 30;
83     fi
84     if [[ $month -eq 2 ]] ; then
85         let t=($year/400)*400
86         if [[ $t -eq $year ]] ; then
87             return 29;
88         fi
89         let t=($year/100)*100
90         if [[ $t -eq $year ]] ; then
91             return 28;
92         fi
93         let t=($year/4)*4
94         if [[ $t -eq $year ]] ; then
95             return 29;
96         fi
97         return 28;
98     fi
99     return 31;
100 }
101
102 # The next timestamp to issue via touch
103 # A real hemorrhoid because bash isnt easily convinced
104 # that 08 is a decimal number
105 next_ts() {
106     sec=`echo $sec | sed 's/^0//'`
107     let sec=$sec+1
108     if [[ "$sec" -lt "60" ]] ; then
109         if [[ "$sec" -lt "10" ]] ; then
110             sec=0$sec
111         fi
112         return 0;
113     fi
114     sec="00"
115     min=`echo $min | sed 's/^0//'`
116     let min=$min+1
117     if [[ "$min" -lt "60" ]] ; then
118         if [[ "$min" -lt "10" ]] ; then
119             min=0$min
120         fi
121         return 0;
122     fi
123     min="00"
124     hour=`echo $hour | sed 's/^0//'`
125     let hour=$hour+1
126     if [[ "$hour" -lt "24" ]] ; then
127         if [[ "$hour" -lt "10" ]] ; then
128             hour=0$hour
129         fi
130         return 0;
131     fi
132     hour="00"
133     days_in_current_month
134     days_in_month=$?
135     if [[ "$day" -lt "$days_in_month" ]] ; then
136         day=`echo $day | sed 's/^0//'`
137         let day=$day+1
138         if [[ "$day" -lt "10" ]] ; then
139             day=0$day
140         fi
141         return 0;
142     fi
143     day="01"
144     month=`echo $month | sed 's/^0//'`
145     let month=$month+1
146     if [[ "$month" -lt "13" ]] ; then
147         if [[ "$month" -lt "10" ]] ; then
148             month=0$month
149         fi
150         return 0;
151     fi
152     month="01"
153     let year=$year+1
154     return 0;
155 }
156
157 while [ $# != 0 ] ; do
158   case "$1" in
159     (--commav) comma_v=",v" ;;
160     (--touch) touch=yes ;;
161     (--aclocal) aclocal=yes ;;
162     (--nooptimize) optimize="" ;;
163     (--commit=*) commit="$1" ;;
164     (*) echo "$0: usage [--touch|--commit|]" > /dev/stderr
165         exit 17 ;;
166   esac
167   shift
168 done
169
170 if [ "${aclocal}" != "" ] ; then
171     if [ -f aclocal.m4 ] ; then
172         echo touching aclocal.m4
173         sleep 1
174         touch aclocal.m4
175     else
176         echo aclocal.m4 not found
177     fi
178 fi
179
180 if [ "${comma_v}" != "" -a "${commit}" != "" ] ; then
181   echo "No, you may NOT molest ,v files directly.  Go away." > /dev/stderr
182   exit 1
183 fi
184
185 function touchme ()
186 {
187   local victim="${1}"
188   shift
189   local touchmebaby=""
190   local sein="is"
191   local newer="no"
192   local older="no"
193
194   if [ ! -r "$victim" ] ; then
195     echo "  Possible problem: No $victim exists. " > /dev/stderr 
196     return
197   fi
198
199   while [ $# != 0 ] ; do
200     if [ "${1}" -nt "${victim}" ] ; then
201         newer="yes"
202     fi
203     if [ "${1}" -ot "${victim}" ] ; then
204         older="yes"
205     fi
206     if [ "${newer}" = "no" -a "${older}" = "no" ] ; then
207         newer="yes"
208     fi
209
210     if [ "${newer}" = "yes" ] ; then
211       if [ "${touchmebaby}" = "" ] ; then
212         touchmebaby="${1}"
213       else
214         sein="are"
215         touchmebaby="${touchmebaby} ${1}"
216       fi
217     fi
218     shift
219   done
220   if [ -n "${touchmebaby}" ] ; then
221     echo "*** ${touchmebaby} ${sein} newer than ${victim}  "
222     if [ -n "${touch}" ] ; then
223       # 
224       # This is the old version, in case something backfires...
225       if [ "${optimize}" != "yes" ] ; then 
226           echo "Fixing " ;touch -c "$victim" ; sleep 1
227       else
228           echo "Fixing "
229       # echo touch -c -t $year$month$day$hour$min.$sec "$victim"
230           touch -c -t $year$month$day$hour$min.$sec "$victim"
231           next_ts
232       fi
233     fi
234   fi
235 }
236
237 makefileins="`/usr/bin/find . -name Attic -prune -o -name Makefile.in${comma_v}`"
238
239 # aclocal.m4 depends on ***/Makefile.am, configure.ac, acinclude.m4, *.m4 crap
240 touchme aclocal.m4${comma_v} \
241         `/usr/bin/find . -name Attic -prune -o -name Makefile.am${comma_v}` \
242         "configure.in${comma_v}" "configure.ac${comma_v}" \
243         "acinclude.m4${comma_v}"
244
245 # Makefile.in must be newer than Makefile.am
246 for f in $makefileins ; do
247   d="`dirname ${f}`"
248   touchme "${d}/Makefile.in${comma_v}" "${d}/Makefile.am${comma_v}"
249 done
250
251 # Makefile.in depends on aclocal.m4
252 for f in $makefileins ; do
253   d="`dirname $f`"
254   touchme "${d}/Makefile.in${comma_v}" "aclocal.m4${comma_v}"
255 done
256
257 # config.in must be newer than aclocal.m4 and configure.ac
258 if [ -f "config.in${comma_v}" ] ; then
259   touchme "config.in${comma_v}" "aclocal.m4${comma_v}" \
260                                 "configure.ac${comma_v}" \
261                                 "configure.in${comma_v}"
262 fi
263
264 # config.h.in (or More Thoroughly Modern configh.in)
265 # must be newer than aclocal.m4 and (obsolete) acconfig.h
266 for c_h_in in config.h.in configh.in ; do
267   if [ -f "${c_h_in}${comma_v}" ]; then
268     touchme "${c_h_in}${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}"
269     #>>>> WTF?  Why?  This is nonsensical
270     ## ***/Makefile.in must be newer than config.h.in
271     #for f in $makefileins ; do
272     #  touchme "$f" "${c_h_in}${comma_v}"
273     #done
274   fi
275 done
276
277 # configure must be newer than everything
278 # touchme configure $makefileins -- why would this be needed?
279 touchme "configure${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}" \
280                               "config.in${comma_v}" "config.h.in${comma_v}" \
281                               "configh.in${comma_v}"
282
283 if [ -n "${commit}" ] ; then
284   commit="${commit:9}" # strip off "--commit="
285   # First ***/Makefile.am,
286   # configure.in, configure.ac,
287   # ***/*.m4
288   # acconfig.h
289   cvs commit -m "${commit}" \
290              `for f in ${makefileins} ; do \
291                 [ -f "$${f%.in}.am" ] && echo "$${f%.in}.am" ; \
292               done` \
293              `[ -f configure.in ] && echo configure.in` \
294              `[ -f configure.ac ] && echo configure.ac` \
295              `[ -f acconfig.h ] && echo acconfig.h` \
296              `/usr/bin/find . -name '*.m4' -mindepth 2`
297
298   # Next aclocal.m4
299   [ -f "aclocal.m4" ] && cvs commit -m "${commit}" aclocal.m4
300
301   # Next config.in, config.h.in, configh.in
302   [ -f "config.in" ] && cvs commit -m "${commit}" config.in
303   [ -f "config.h.in" ] && cvs commit -m "${commit}" config.h.in
304   [ -f "configh.in" ] && cvs commit -m "${commit}" configh.in
305
306   # Last ***/Makefile.in, configure
307   cvs commit -m "${commit}" ${makefileins} configure
308 fi