blob: 21a440df484f306fa870ad0af4b2fe3b4ad9ed03 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001#!/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
19set -eu
20#set -vx
21
22touch=""
23commit=""
24comma_v=""
25aclocal=""
26optimize=""
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
41my_tz=`date +%z`
42sign=`echo $my_tz | sed -n -e 's/^\(.\{1\}\).*$/\1/p'`
43t=`echo $my_tz | sed -n -e 's/^\(.\{1\}\)//p'`
44tz_hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
45tz_hour=`echo $tz_hour | sed 's/^0//'`
46
47if [ $sign = "-" ] ; then
48 sign="+"
49 let tz_hour=$tz_hour+1
50 if [[ $tz_hour -ge "24" ]] ; then
51 tz_hour=0
52 fi
53else
54 sign="-"
55 let tz_hour=$tz_hour-1 || true
56 if [[ $tz_hour -lt "0" ]] ; then
57 tz_hour=23
58 fi
59fi
60
61# Timestamp, an hour ago:
62ts_begin=`TZ=UTC${sign}${tz_hour} date +%Y%m%d%H%M.%S`
63
64# break into constituent parts
65year=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\).*$/\1/p'`
66t=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\)//p'`
67month=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
68t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
69day=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
70t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
71hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
72t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
73min=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
74t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
75sec=`echo $t | sed -n -e 's/\.//p'`
76
77# How many days in the current month?
78# Good until someone changes the calendar rules
79days_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
105next_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
157while [ $# != 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
168done
169
170if [ "${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
178fi
179
180if [ "${comma_v}" != "" -a "${commit}" != "" ] ; then
181 echo "No, you may NOT molest ,v files directly. Go away." > /dev/stderr
182 exit 1
183fi
184
185function 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
Ed Warnickecb9cada2015-12-08 15:45:58 -0700195 return
196 fi
197
198 while [ $# != 0 ] ; do
199 if [ "${1}" -nt "${victim}" ] ; then
200 newer="yes"
201 fi
202 if [ "${1}" -ot "${victim}" ] ; then
203 older="yes"
204 fi
205 if [ "${newer}" = "no" -a "${older}" = "no" ] ; then
206 newer="yes"
207 fi
208
209 if [ "${newer}" = "yes" ] ; then
210 if [ "${touchmebaby}" = "" ] ; then
211 touchmebaby="${1}"
212 else
213 sein="are"
214 touchmebaby="${touchmebaby} ${1}"
215 fi
216 fi
217 shift
218 done
219 if [ -n "${touchmebaby}" ] ; then
220 echo "*** ${touchmebaby} ${sein} newer than ${victim} "
221 if [ -n "${touch}" ] ; then
222 #
223 # This is the old version, in case something backfires...
224 if [ "${optimize}" != "yes" ] ; then
225 echo "Fixing " ;touch -c "$victim" ; sleep 1
226 else
227 echo "Fixing "
228 # echo touch -c -t $year$month$day$hour$min.$sec "$victim"
229 touch -c -t $year$month$day$hour$min.$sec "$victim"
230 next_ts
231 fi
232 fi
233 fi
234}
235
236makefileins="`/usr/bin/find . -name Attic -prune -o -name Makefile.in${comma_v}`"
237
238# aclocal.m4 depends on ***/Makefile.am, configure.ac, acinclude.m4, *.m4 crap
239touchme aclocal.m4${comma_v} \
240 `/usr/bin/find . -name Attic -prune -o -name Makefile.am${comma_v}` \
241 "configure.in${comma_v}" "configure.ac${comma_v}" \
242 "acinclude.m4${comma_v}"
243
244# Makefile.in must be newer than Makefile.am
245for f in $makefileins ; do
246 d="`dirname ${f}`"
247 touchme "${d}/Makefile.in${comma_v}" "${d}/Makefile.am${comma_v}"
248done
249
250# Makefile.in depends on aclocal.m4
251for f in $makefileins ; do
252 d="`dirname $f`"
253 touchme "${d}/Makefile.in${comma_v}" "aclocal.m4${comma_v}"
254done
255
256# config.in must be newer than aclocal.m4 and configure.ac
257if [ -f "config.in${comma_v}" ] ; then
258 touchme "config.in${comma_v}" "aclocal.m4${comma_v}" \
259 "configure.ac${comma_v}" \
260 "configure.in${comma_v}"
261fi
262
263# config.h.in (or More Thoroughly Modern configh.in)
264# must be newer than aclocal.m4 and (obsolete) acconfig.h
265for c_h_in in config.h.in configh.in ; do
266 if [ -f "${c_h_in}${comma_v}" ]; then
267 touchme "${c_h_in}${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}"
268 #>>>> WTF? Why? This is nonsensical
269 ## ***/Makefile.in must be newer than config.h.in
270 #for f in $makefileins ; do
271 # touchme "$f" "${c_h_in}${comma_v}"
272 #done
273 fi
274done
275
276# configure must be newer than everything
277# touchme configure $makefileins -- why would this be needed?
278touchme "configure${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}" \
279 "config.in${comma_v}" "config.h.in${comma_v}" \
280 "configh.in${comma_v}"
281
282if [ -n "${commit}" ] ; then
283 commit="${commit:9}" # strip off "--commit="
284 # First ***/Makefile.am,
285 # configure.in, configure.ac,
286 # ***/*.m4
287 # acconfig.h
288 cvs commit -m "${commit}" \
289 `for f in ${makefileins} ; do \
290 [ -f "$${f%.in}.am" ] && echo "$${f%.in}.am" ; \
291 done` \
292 `[ -f configure.in ] && echo configure.in` \
293 `[ -f configure.ac ] && echo configure.ac` \
294 `[ -f acconfig.h ] && echo acconfig.h` \
295 `/usr/bin/find . -name '*.m4' -mindepth 2`
296
297 # Next aclocal.m4
298 [ -f "aclocal.m4" ] && cvs commit -m "${commit}" aclocal.m4
299
300 # Next config.in, config.h.in, configh.in
301 [ -f "config.in" ] && cvs commit -m "${commit}" config.in
302 [ -f "config.h.in" ] && cvs commit -m "${commit}" config.h.in
303 [ -f "configh.in" ] && cvs commit -m "${commit}" configh.in
304
305 # Last ***/Makefile.in, configure
306 cvs commit -m "${commit}" ${makefileins} configure
307fi