tzdata2netbsd revision 1.12 1 1.12 kre # $NetBSD: tzdata2netbsd,v 1.12 2018/03/24 01:54:48 kre Exp $
2 1.1 apb
3 1.1 apb # For use by NetBSD developers when updating to new versions of tzdata.
4 1.1 apb #
5 1.2 apb # 0. Be in an up-to-date checkout of src/external/public-domain/tz
6 1.2 apb # from NetBSD-current.
7 1.12 kre # 1. Make sure that you have Paul Eggert's 4K RSA public key in your
8 1.12 kre # keyring (62AA7E34, eggert (a] cs.ucla.edu) It is not required that it be trusted.
9 1.12 kre # 2. Run this script. You will be prompted for confirmation before
10 1.12 kre # anything major (such as a cvs operation). The tz versions can be
11 1.12 kre # specified as args (new version first, and the previous second) if
12 1.12 kre # needed to override the calculated values
13 1.12 kre # 3. If something fails, abort the script and fix it.
14 1.12 kre # 4. Re-run this script until you are happy. It's designed to
15 1.1 apb # be re-run over and over, and later runs will try not to
16 1.1 apb # redo non-trivial work done by earlier runs.
17 1.1 apb #
18 1.1 apb
19 1.12 kre VERS_PATTERN='2[0-9][0-9][0-9][a-z]'
20 1.12 kre # This needs to be updated twice every millennium to allow for the
21 1.12 kre # new millenium's years.
22 1.12 kre # First in the late xx90's sometime, allow the new one by changing the leading
23 1.12 kre # digit from a specific value to the class containing the current and
24 1.12 kre # following values (eg: in 2098 or so, change '2' to be '[23]').
25 1.12 kre # Tnen in the following early xx00's sometime, delete the class, and insert
26 1.12 kre # leave only the current value as valid (eg: in 3001 or 3002,
27 1.12 kre # change '[23]' to be just '3'
28 1.12 kre # Doing it this way helps guard against invalid specifications.
29 1.12 kre # We could automate this, but it is (IMO) not worth the cost, to avoid a
30 1.12 kre # twice a millenium edit requirement.
31 1.12 kre # A more significant (and harder) change will be needed in the late 9990's
32 1.12 kre # If this script lasts until then, send me a postcard, I'll be waiting for it!
33 1.12 kre # Things get easier again after that until the late 99990's (etc.)
34 1.12 kre
35 1.12 kre # Note the pattern is used on both the old and new version specifiers,
36 1.12 kre # so it must be able to cope with the shift from one form (eg 2999g)
37 1.12 kre # to the new one (eg: 3000a) without failing (or the code that uses it
38 1.12 kre # below needs to be updated).
39 1.12 kre
40 1.12 kre # Also note that the option of having a second alpha (1997aa or something)
41 1.12 kre # to handle years with much activity is handled below, the pattern does not
42 1.12 kre # need to match those.
43 1.12 kre # If that convention changes (as of date of writing, it has never been
44 1.12 kre # exercised) then code changes below will be required.
45 1.12 kre
46 1.12 kre DIST_HOST=ftp.iana.org
47 1.12 kre DIST_PATH=tz
48 1.12 kre DIST_FILES=releases
49 1.1 apb
50 1.12 kre EDITOR=${EDITOR:-vi}
51 1.12 kre WORK_PFX=$(pwd)/update-work || fail "Cannot obtain PWD"
52 1.12 kre UPDATE_FROM=${WORK_PFX}/updating.from.version
53 1.12 kre
54 1.12 kre usage()
55 1.12 kre {
56 1.12 kre printf >&2 '%s\n' \
57 1.12 kre "Usage: $0 [new-version-id [old-version-id]]" \
58 1.12 kre " where a version-id is of the form YYYYx (eg: 2018c)" \
59 1.12 kre " or '' for new-version-id (to specify only the old)"
60 1.12 kre exit 2
61 1.12 kre }
62 1.12 kre
63 1.12 kre fail()
64 1.12 kre {
65 1.12 kre local IFS=' '
66 1.12 kre
67 1.12 kre printf >&2 '%s\n' "Error detected:" " $*" "Aborting."
68 1.12 kre exit 1
69 1.12 kre }
70 1.12 kre
71 1.12 kre valid_vers()
72 1.12 kre {
73 1.12 kre case "$2" in
74 1.12 kre ${VERS_PATTERN} | ${VERS_PATTERN}[a-z] )
75 1.12 kre ;;
76 1.12 kre *) printf >&2 '%s: %s\n' \
77 1.12 kre "Bad form for $1 version specifier '$2'" \
78 1.12 kre "should (usually) be 'YYYYx'"
79 1.12 kre return 1
80 1.12 kre ;;
81 1.12 kre esac
82 1.12 kre return 0
83 1.12 kre }
84 1.12 kre
85 1.12 kre get_curvers()
86 1.12 kre {
87 1.12 kre local LF=''
88 1.12 kre local LIST=iana-listing
89 1.12 kre local SED_SCRIPT='
90 1.12 kre /tzdata-latest.*-> /{
91 1.12 kre s/^.*-> //
92 1.12 kre s/\..*$//
93 1.12 kre s;^releases/tzdata;;p
94 1.12 kre q
95 1.12 kre }
96 1.12 kre d'
97 1.12 kre
98 1.12 kre test -d "${WORK_PFX}" &&
99 1.12 kre test -s "${WORK_PFX}/${LIST}" &&
100 1.12 kre test "${WORK_PFX}/${LIST}" -nt dist/CVS &&
101 1.12 kre LF=$(find "${WORK_PFX}" -name "${LIST}" -mtime -1 -print) &&
102 1.12 kre test -n "${LF}" &&
103 1.12 kre NEWVER=$(sed -n < "${LF}" "${SED_SCRIPT}") &&
104 1.12 kre valid_vers new "${NEWVER}" ||
105 1.12 kre
106 1.12 kre ftp >/dev/null 2>&1 -ia "${DIST_HOST}" <<- EOF &&
107 1.12 kre dir ${DIST_PATH} ${WORK_PFX}/${LIST}
108 1.12 kre quit
109 1.12 kre EOF
110 1.12 kre test -s "${WORK_PFX}/${LIST}" &&
111 1.12 kre NEWVER=$(sed -n < "${WORK_PFX}/${LIST}" "${SED_SCRIPT}") &&
112 1.12 kre valid_vers new "${NEWVER}" ||
113 1.12 kre
114 1.12 kre {
115 1.12 kre rm -f "${WORK_PFX}/${LIST}"
116 1.12 kre fail "Cannot fetch current tzdata version from ${DIST_HOST}"
117 1.12 kre }
118 1.12 kre
119 1.12 kre printf '%s\n' "Updating from ${OLDVER} to ${NEWVER}"
120 1.12 kre }
121 1.12 kre
122 1.12 kre argparse()
123 1.12 kre {
124 1.12 kre local OVF
125 1.12 kre
126 1.12 kre if OVF=$(find "${WORK_PFX}" -name "${UPDATE_FROM##*/}" -mtime +2 -print)
127 1.12 kre then
128 1.12 kre # delete anything old
129 1.12 kre test -n "${OVF}" && rm -f "${OVF}"
130 1.12 kre fi
131 1.12 kre
132 1.12 kre case "$#" in
133 1.12 kre 0|1)
134 1.12 kre # once we have obtained OLDVER once, never guess it again.
135 1.12 kre test -f "${UPDATE_FROM}" && OLDVER=$(cat "${UPDATE_FROM}") ||
136 1.12 kre
137 1.12 kre OLDVER=$(cat dist/version) || {
138 1.12 kre printf >&2 '%s\n' \
139 1.12 kre "Cannot determine current installed version" \
140 1.12 kre "Specify it on the command line." \
141 1.12 kre ""
142 1.12 kre usage
143 1.12 kre }
144 1.12 kre
145 1.12 kre valid_vers old "${OLDVER}" ||
146 1.12 kre fail "Calculated bad OLDVER, give as 2nd arg"
147 1.12 kre ;;
148 1.1 apb
149 1.12 kre 2) valid_vers old "$2" && OLDVER="$2" || usage
150 1.12 kre ;;
151 1.12 kre
152 1.12 kre *) usage
153 1.12 kre ;;
154 1.12 kre esac
155 1.12 kre
156 1.12 kre case "$#:$1" in
157 1.12 kre 0: | 1: | 2: )
158 1.12 kre ;;
159 1.12 kre 1:?*|2:?*)
160 1.12 kre valid_vers new "$1" && NEWVER="$1" || usage
161 1.12 kre ;;
162 1.12 kre *) usage
163 1.12 kre ;;
164 1.12 kre esac
165 1.12 kre
166 1.12 kre test -z "${NEWVER}" && get_curvers
167 1.12 kre
168 1.12 kre test "${NEWVER}" = "${OLDVER}" && {
169 1.12 kre printf '%s\n' \
170 1.12 kre "New and old versions both ${NEWVER}: nothing to do"
171 1.12 kre exit 0
172 1.12 kre
173 1.12 kre }
174 1.12 kre
175 1.12 kre printf '%s\n' "${OLDVER}" > "${UPDATE_FROM}" ||
176 1.12 kre fail "Unable to preserve old version ${OLDVER} in ${UPDATE_FROM}"
177 1.12 kre
178 1.12 kre test "${#NEWVER}" -gt "${#OLDVER}" ||
179 1.12 kre test "${NEWVER}" '>' "${OLDVER}" ||
180 1.12 kre {
181 1.12 kre local reply
182 1.12 kre
183 1.12 kre printf '%s\n' \
184 1.12 kre "Update would revert ${OLDVER} to ${NEWVER}"
185 1.12 kre read -p "Is reversion intended? " reply
186 1.12 kre case "${reply}" in
187 1.12 kre [Yy]*) ;;
188 1.12 kre *) printf '%s\n' OK. Aborted.
189 1.12 kre rm -f "${UPDATE_FROM}"
190 1.12 kre exit 1
191 1.12 kre ;;
192 1.12 kre esac
193 1.12 kre }
194 1.12 kre
195 1.12 kre return 0
196 1.12 kre }
197 1.12 kre
198 1.12 kre setup_versions()
199 1.12 kre {
200 1.12 kre # Uppercase variants of OLDVER and NEWVER
201 1.12 kre OLDVER_UC="$( echo "${OLDVER}" | tr '[a-z]' '[A-Z]' )"
202 1.12 kre NEWVER_UC="$( echo "${NEWVER}" | tr '[a-z]' '[A-Z]' )"
203 1.12 kre
204 1.12 kre # Tags for use with version control systems
205 1.12 kre CVSOLDTAG="TZDATA${OLDVER_UC}"
206 1.12 kre CVSNEWTAG="TZDATA${NEWVER_UC}"
207 1.12 kre CVSBRANCHTAG="TZDATA"
208 1.12 kre GITHUBTAG="${NEWVER}"
209 1.12 kre
210 1.12 kre # URLs for fetching distribution files, etc.
211 1.12 kre DISTURL="ftp://${DIST_HOST}/${DIST_PATH}/${DIST_FILES}"
212 1.12 kre DISTURL="${DISTURL}/tzdata${NEWVER}.tar.gz"
213 1.12 kre SIGURL="${DISTURL}.asc"
214 1.12 kre NEWSURL="https://github.com/eggert/tz/raw/${GITHUBTAG}/NEWS"
215 1.12 kre
216 1.12 kre # Directories
217 1.12 kre REPODIR="src/external/public-domain/tz/dist"
218 1.12 kre # relative to the NetBSD CVS repo
219 1.12 kre TZDISTDIR="$(pwd)/dist" # should be .../external/public-domain/tz/dist
220 1.12 kre WORKDIR="${WORK_PFX}/${NEWVER}"
221 1.12 kre EXTRACTDIR="${WORKDIR}/extract"
222 1.12 kre
223 1.12 kre # Files in the work directory
224 1.12 kre DISTFILE="${WORKDIR}/${DISTURL##*/}"
225 1.12 kre SIGFILE="${DISTFILE}.asc"
226 1.12 kre PGPVERIFYLOG="${WORKDIR}/pgpverify.log"
227 1.12 kre NEWSFILE="${WORKDIR}/NEWS"
228 1.12 kre NEWSTRIMFILE="${WORKDIR}/NEWS.trimmed"
229 1.12 kre IMPORTMSGFILE="${WORKDIR}/import.msg"
230 1.12 kre IMPORTDONEFILE="${WORKDIR}/import.done"
231 1.12 kre MERGSMSGFILE="${WORKDIR}/merge.msg"
232 1.12 kre MERGEDONEFILE="${WORKDIR}/merge.done"
233 1.12 kre COMMITMERGEDONEFILE="${WORKDIR}/commitmerge.done"
234 1.12 kre
235 1.12 kre printf '%s\n' "${CVSOLDTAG}" > "${WORK_PFX}/updating_from"
236 1.12 kre }
237 1.9 agc
238 1.1 apb DOIT()
239 1.1 apb {
240 1.1 apb local really_do_it=false
241 1.1 apb local reply
242 1.1 apb
243 1.3 apb echo "In directory $(pwd)"
244 1.1 apb echo "ABOUT TO DO:" "$(shell_quote "$@")"
245 1.1 apb read -p "Really do it? [yes/no/quit] " reply
246 1.1 apb case "${reply}" in
247 1.1 apb [yY]*) really_do_it=true ;;
248 1.1 apb [nN]*) really_do_it=false ;;
249 1.1 apb [qQ]*)
250 1.1 apb echo "Aborting"
251 1.1 apb return 1
252 1.1 apb ;;
253 1.12 kre *) echo "Huh?"
254 1.12 kre return 1
255 1.12 kre ;;
256 1.1 apb esac
257 1.1 apb if $really_do_it; then
258 1.1 apb echo "REALLY DOING IT NOW..."
259 1.1 apb "$@"
260 1.1 apb else
261 1.1 apb echo "NOT REALLY DOING THE ABOVE COMMAND"
262 1.1 apb fi
263 1.1 apb }
264 1.1 apb
265 1.1 apb # Quote args to make them safe in the shell.
266 1.1 apb # Usage: quotedlist="$(shell_quote args...)"
267 1.1 apb #
268 1.1 apb # After building up a quoted list, use it by evaling it inside
269 1.1 apb # double quotes, like this:
270 1.1 apb # eval "set -- $quotedlist"
271 1.1 apb # or like this:
272 1.1 apb # eval "\$command $quotedlist \$filename"
273 1.1 apb #
274 1.1 apb shell_quote()
275 1.12 kre (
276 1.1 apb local result=''
277 1.1 apb local arg qarg
278 1.1 apb LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII
279 1.1 apb for arg in "$@" ; do
280 1.1 apb case "${arg}" in
281 1.1 apb '')
282 1.1 apb qarg="''"
283 1.1 apb ;;
284 1.1 apb *[!-./a-zA-Z0-9]*)
285 1.1 apb # Convert each embedded ' to '\'',
286 1.1 apb # then insert ' at the beginning of the first line,
287 1.1 apb # and append ' at the end of the last line.
288 1.1 apb # Finally, elide unnecessary '' pairs at the
289 1.1 apb # beginning and end of the result and as part of
290 1.1 apb # '\'''\'' sequences that result from multiple
291 1.1 apb # adjacent quotes in he input.
292 1.12 kre qarg="$(printf '%s\n' "$arg" | \
293 1.1 apb ${SED:-sed} -e "s/'/'\\\\''/g" \
294 1.1 apb -e "1s/^/'/" -e "\$s/\$/'/" \
295 1.1 apb -e "1s/^''//" -e "\$s/''\$//" \
296 1.1 apb -e "s/'''/'/g"
297 1.1 apb )"
298 1.1 apb ;;
299 1.1 apb *)
300 1.1 apb # Arg is not the empty string, and does not contain
301 1.1 apb # any unsafe characters. Leave it unchanged for
302 1.1 apb # readability.
303 1.1 apb qarg="${arg}"
304 1.1 apb ;;
305 1.1 apb esac
306 1.1 apb result="${result}${result:+ }${qarg}"
307 1.1 apb done
308 1.12 kre printf '%s\n' "$result"
309 1.12 kre )
310 1.12 kre
311 1.12 kre validate_pwd()
312 1.12 kre {
313 1.12 kre local P="$(pwd)" || return 1
314 1.12 kre
315 1.12 kre test -d "${P}" &&
316 1.12 kre test -d "${P}/CVS" &&
317 1.12 kre test -d "${P}/dist" &&
318 1.12 kre test -f "${P}/dist/zone.tab" &&
319 1.12 kre test -f "${P}/tzdata2netbsd" || {
320 1.12 kre printf >&2 '%s\n' "Please change to the correct directory"
321 1.12 kre return 1
322 1.12 kre }
323 1.12 kre
324 1.12 kre test -f "${P}/CVS/Tag" && {
325 1.12 kre
326 1.12 kre # Here (for local use only) if needed for private branch work
327 1.12 kre # insert tests for the value of $(cat "${P}/CVS/Tag") and
328 1.12 kre # allow your private branch tag to pass. Eg:
329 1.12 kre
330 1.12 kre # case "$(cat "${P}/CVS/Tag")" in
331 1.12 kre # my-branch-name) return 0;;
332 1.12 kre # esac
333 1.12 kre
334 1.12 kre # Do not commit a version of this script modified that way,
335 1.12 kre # (not even on the private branch) - keep it as a local
336 1.12 kre # modified file. (This script will not commit it.)
337 1.12 kre
338 1.12 kre printf >&2 '%s\n' \
339 1.12 kre "This script should be run in a checkout of HEAD only"
340 1.12 kre return 1
341 1.12 kre }
342 1.12 kre
343 1.12 kre return 0
344 1.12 kre }
345 1.1 apb
346 1.1 apb findcvsroot()
347 1.1 apb {
348 1.1 apb [ -n "${CVSROOT}" ] && return 0
349 1.1 apb CVSROOT="$( cat ./CVS/Root )"
350 1.1 apb [ -n "${CVSROOT}" ] && return 0
351 1.1 apb echo >&2 "Failed to set CVSROOT value"
352 1.1 apb return 1
353 1.1 apb }
354 1.1 apb
355 1.12 kre mkworkpfx()
356 1.12 kre {
357 1.12 kre mkdir -p "${WORK_PFX}" || fail "Unable to make missing ${WORK_PFX}"
358 1.12 kre }
359 1.1 apb mkworkdir()
360 1.1 apb {
361 1.12 kre mkdir -p "${WORKDIR}" || fail "Unable to make missing ${WORKDIR}"
362 1.1 apb }
363 1.1 apb
364 1.1 apb fetch()
365 1.1 apb {
366 1.12 kre [ -f "${DISTFILE}" ] || ftp -o "${DISTFILE}" "${DISTURL}" ||
367 1.12 kre fail "fetch of ${DISTFILE} failed"
368 1.12 kre [ -f "${SIGFILE}" ] || ftp -o "${SIGFILE}" "${SIGURL}" ||
369 1.12 kre fail "fetch of ${SIGFILE} failed"
370 1.12 kre [ -f "${NEWSFILE}" ] || ftp -o "${NEWSFILE}" "${NEWSURL}" ||
371 1.12 kre fail "fetch of ${NEWSFILE} failed"
372 1.1 apb }
373 1.1 apb
374 1.1 apb checksig()
375 1.1 apb {
376 1.1 apb { gpg --verify "${SIGFILE}" "${DISTFILE}"
377 1.1 apb echo gpg exit status $?
378 1.1 apb } 2>&1 | tee "${PGPVERIFYLOG}"
379 1.1 apb
380 1.1 apb # The output should contain lines that match all the following regexps
381 1.1 apb #
382 1.1 apb while read line; do
383 1.11 kre if ! grep -E -q -e "^${line}\$" "${PGPVERIFYLOG}"; then
384 1.1 apb echo >&2 "Failed to verify signature: ${line}"
385 1.1 apb return 1
386 1.1 apb fi
387 1.1 apb done <<'EOF'
388 1.11 kre gpg: Signature made .* using RSA key ID (62AA7E34|44AD418C)
389 1.1 apb gpg: Good signature from "Paul Eggert <eggert (a] cs.ucla.edu>"
390 1.1 apb gpg exit status 0
391 1.1 apb EOF
392 1.1 apb }
393 1.1 apb
394 1.1 apb extract()
395 1.1 apb {
396 1.1 apb [ -f "${EXTRACTDIR}/zone.tab" ] && return
397 1.1 apb mkdir -p "${EXTRACTDIR}"
398 1.1 apb tar -z -xf "${DISTFILE}" -C "${EXTRACTDIR}"
399 1.1 apb }
400 1.1 apb
401 1.2 apb addnews()
402 1.2 apb {
403 1.2 apb [ -f "${EXTRACTDIR}/NEWS" ] && return
404 1.2 apb cp -p "${NEWSFILE}" "${EXTRACTDIR}"/NEWS
405 1.2 apb }
406 1.2 apb
407 1.1 apb # Find the relevant part of the NEWS file for all releases between
408 1.1 apb # OLDVER and NEWVER, and save them to NEWSTRIMFILE.
409 1.1 apb #
410 1.1 apb trimnews()
411 1.1 apb {
412 1.1 apb [ -s "${NEWSTRIMFILE}" ] && return
413 1.1 apb awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
414 1.1 apb '
415 1.1 apb BEGIN {inrange = 0}
416 1.1 apb /^Release [0-9]+[a-z]+ - .*/ {
417 1.1 apb # "Release <version> - <date>"
418 1.12 kre # Note: must handle transition from 2018z to 2018aa
419 1.12 kre # Assumptions: OLDVER and NEWVER have been sanitized,
420 1.12 kre # and format of NEWS file does not alter (and
421 1.12 kre # contains valid data)
422 1.12 kre inrange = ((length($2) > length(oldver) || \
423 1.12 kre $2 > oldver) && \
424 1.12 kre (length($2) < newver || $2 <= newver))
425 1.1 apb }
426 1.1 apb // { if (inrange) print; }
427 1.12 kre ' \
428 1.1 apb <"${NEWSFILE}" >"${NEWSTRIMFILE}"
429 1.10 agc echo "tzdata-${NEWVER}" > ${TZDISTDIR}/TZDATA_VERSION
430 1.1 apb }
431 1.1 apb
432 1.1 apb # Create IMPORTMSGFILE from NEWSTRIMFILE, by ignoring some sections,
433 1.1 apb # keeping only the first sentence from paragraphs in other sections,
434 1.1 apb # and changing the format.
435 1.1 apb #
436 1.1 apb # The result should be edited by hand before performing a cvs commit.
437 1.1 apb # A message to that effect is inserted at the beginning of the file.
438 1.1 apb #
439 1.1 apb mkimportmsg()
440 1.1 apb {
441 1.1 apb [ -s "${IMPORTMSGFILE}" ] && return
442 1.1 apb { cat <<EOF
443 1.1 apb EDIT ME: Edit this file and then delete the lines marked "EDIT ME".
444 1.1 apb EDIT ME: This file will be used as a log message for the "cvs commit" that
445 1.1 apb EDIT ME: imports tzdata${NEWVER}. The initial contents of this file were
446 1.1 apb EDIT ME: generated from ${NEWSFILE}.
447 1.1 apb EDIT ME:
448 1.1 apb EOF
449 1.1 apb awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
450 1.2 apb -v disturl="${DISTURL}" -v newsurl="${NEWSURL}" \
451 1.1 apb '
452 1.1 apb BEGIN {
453 1.1 apb bullet = " * ";
454 1.1 apb indent = " ";
455 1.1 apb blankline = 0;
456 1.1 apb goodsection = 0;
457 1.1 apb havesentence = 0;
458 1.1 apb print "Import tzdata"newver" from "disturl;
459 1.4 apb #print "and NEWS file from "newsurl;
460 1.1 apb }
461 1.1 apb /^Release/ {
462 1.1 apb # "Release <version> - <date>"
463 1.1 apb ver = $2;
464 1.1 apb date = gensub(".* - ", "", 1, $0);
465 1.1 apb print "";
466 1.1 apb print "Summary of changes in tzdata"ver \
467 1.1 apb " ("date"):";
468 1.1 apb }
469 1.1 apb /^$/ { blankline = 1; havesentence = 0; }
470 1.1 apb /^ Changes affecting/ { goodsection = 0; }
471 1.1 apb /^ Changes affecting.*time/ { goodsection = 1; }
472 1.7 apb /^ Changes affecting.*data/ { goodsection = 1; }
473 1.1 apb /^ Changes affecting.*documentation/ || \
474 1.1 apb /^ Changes affecting.*commentary/ {
475 1.1 apb t = gensub("^ *", "", 1, $0);
476 1.1 apb t = gensub("\\.*$", ".", 1, t);
477 1.1 apb print bullet t;
478 1.1 apb goodsection = 0;
479 1.1 apb }
480 1.1 apb /^ .*/ && goodsection {
481 1.1 apb # In a paragraph in a "good" section.
482 1.1 apb # Ignore leading spaces, and ignore anything
483 1.1 apb # after the first sentence.
484 1.1 apb # First line of paragraph gets a bullet.
485 1.1 apb t = gensub("^ *", "", 1, $0);
486 1.1 apb t = gensub("\\. .*", ".", 1, t);
487 1.1 apb if (blankline) print bullet t;
488 1.1 apb else if (! havesentence) print indent t;
489 1.1 apb havesentence = (havesentence || (t ~ "\\.$"));
490 1.1 apb }
491 1.1 apb /./ { blankline = 0; }
492 1.12 kre ' \
493 1.1 apb <"${NEWSTRIMFILE}"
494 1.1 apb } >"${IMPORTMSGFILE}"
495 1.1 apb }
496 1.1 apb
497 1.1 apb editimportmsg()
498 1.1 apb {
499 1.1 apb if [ -s "${IMPORTMSGFILE}" ] \
500 1.1 apb && ! grep -q '^EDIT' "${IMPORTMSGFILE}"
501 1.1 apb then
502 1.1 apb return 0 # file has already been edited
503 1.1 apb fi
504 1.1 apb # Pass both IMPORTMSGFILE and NEWSFILE to the editor, so that the
505 1.1 apb # user can easily consult NEWSFILE while editing IMPORTMSGFILE.
506 1.9 agc ${EDITOR} "${IMPORTMSGFILE}" "${NEWSFILE}"
507 1.1 apb }
508 1.1 apb
509 1.1 apb cvsimport()
510 1.1 apb {
511 1.6 apb if [ -e "${IMPORTDONEFILE}" ]; then
512 1.5 apb cat >&2 <<EOF
513 1.5 apb The CVS import has already been performed.
514 1.5 apb EOF
515 1.5 apb return 0
516 1.5 apb fi
517 1.1 apb if ! [ -s "${IMPORTMSGFILE}" ] \
518 1.1 apb || grep -q '^EDIT' "${IMPORTMSGFILE}"
519 1.1 apb then
520 1.1 apb cat >&2 <<EOF
521 1.1 apb The message file ${IMPORTMSGFILE}
522 1.1 apb has not been properly edited.
523 1.1 apb Not performing cvs import.
524 1.1 apb EOF
525 1.1 apb return 1
526 1.1 apb fi
527 1.1 apb ( cd "${EXTRACTDIR}" &&
528 1.1 apb DOIT cvs -d "${CVSROOT}" import -m "$(cat "${IMPORTMSGFILE}")" \
529 1.1 apb "${REPODIR}" "${CVSBRANCHTAG}" "${CVSNEWTAG}"
530 1.6 apb ) && touch "${IMPORTDONEFILE}"
531 1.1 apb }
532 1.1 apb
533 1.1 apb cvsmerge()
534 1.5 apb {
535 1.3 apb
536 1.3 apb cd "${TZDISTDIR}" || exit 1
537 1.6 apb if [ -e "${MERGEDONEFILE}" ]; then
538 1.5 apb cat >&2 <<EOF
539 1.5 apb The CVS merge has already been performed.
540 1.5 apb EOF
541 1.5 apb return 0
542 1.5 apb fi
543 1.6 apb DOIT cvs -d "${CVSROOT}" update -j"${CVSOLDTAG}" -j"${CVSNEWTAG}" \
544 1.6 apb && touch "${MERGEDONEFILE}"
545 1.5 apb }
546 1.1 apb
547 1.1 apb resolveconflicts()
548 1.1 apb {
549 1.5 apb cd "${TZDISTDIR}" || exit 1
550 1.5 apb if grep -l '^[<=>][<=>][<=>]' *
551 1.5 apb then
552 1.5 apb cat <<EOF
553 1.5 apb There appear to be conflicts in the files listed above.
554 1.5 apb Resolve conflicts, then re-run this script.
555 1.1 apb EOF
556 1.5 apb return 1
557 1.5 apb fi
558 1.1 apb }
559 1.1 apb
560 1.1 apb cvscommitmerge()
561 1.5 apb {
562 1.3 apb cd "${TZDISTDIR}" || exit 1
563 1.1 apb if grep -l '^[<=>][<=>][<=>]' *
564 1.1 apb then
565 1.1 apb cat >&2 <<EOF
566 1.1 apb There still appear to be conflicts in the files listed above.
567 1.1 apb Not performing cvs commit.
568 1.1 apb EOF
569 1.1 apb return 1
570 1.1 apb fi
571 1.6 apb if [ -e "${COMMITMERGEDONEFILE}" ]; then
572 1.5 apb cat >&2 <<EOF
573 1.5 apb The CVS commmit (of the merge result) has already been performed.
574 1.5 apb EOF
575 1.5 apb return 0
576 1.5 apb fi
577 1.6 apb DOIT cvs -d "${CVSROOT}" commit -m "Merge tzdata${NEWVER}" \
578 1.6 apb && touch "${COMMITMERGEDONEFILE}"
579 1.5 apb }
580 1.1 apb
581 1.1 apb extra()
582 1.1 apb {
583 1.1 apb cat <<EOF
584 1.1 apb Also do the following:
585 1.12 kre * Edit and commit src/doc/3RDPARTY
586 1.12 kre * Edit and commit src/doc/CHANGES
587 1.12 kre * Edit and commit src/distrib/sets/lists/base/mi
588 1.12 kre * if the set of installed files altered.
589 1.1 apb * Submit pullup requests for all active release branches.
590 1.12 kre * rm -rf ${WORK_PFX} (optional)
591 1.12 kre * Verify that
592 1.12 kre ${UPDATE_FROM}
593 1.12 kre * no longer exists.
594 1.1 apb EOF
595 1.1 apb }
596 1.1 apb
597 1.1 apb main()
598 1.1 apb {
599 1.1 apb set -e
600 1.12 kre validate_pwd
601 1.1 apb findcvsroot
602 1.12 kre mkworkpfx
603 1.12 kre argparse "$@"
604 1.12 kre setup_versions
605 1.1 apb mkworkdir
606 1.1 apb fetch
607 1.1 apb checksig
608 1.1 apb extract
609 1.2 apb addnews
610 1.1 apb trimnews
611 1.1 apb mkimportmsg
612 1.1 apb editimportmsg
613 1.1 apb cvsimport
614 1.1 apb cvsmerge
615 1.1 apb resolveconflicts
616 1.1 apb cvscommitmerge
617 1.12 kre rm -f "${UPDATE_FROM}"
618 1.1 apb extra
619 1.1 apb }
620 1.1 apb
621 1.1 apb main "$@"
622