1 # $NetBSD: tzdata2netbsd,v 1.7 2015/08/11 18:10:13 apb Exp $
3 # For use by NetBSD developers when updating to new versions of tzdata.
5 # 0. Be in an up-to-date checkout of src/external/public-domain/tz
7 # 1. Edit OLDVER and NEWVER below.
8 # 2. Run this script. You will be prompted for confirmation before
9 # anything major (such as a cvs operation).
10 # 3. If something fails, abort the script and fix it.
11 # 4. Re-run this script until you are happy. It's designed to
12 # be re-run over and over, and later runs will try not to
13 # redo non-trivial work done by earlier runs.
19 # Uppercase variants of OLDVER and NEWVER
20 OLDVER_UC="$( echo "${OLDVER}" | tr '[a-z]' '[A-Z]' )"
21 NEWVER_UC="$( echo "${NEWVER}" | tr '[a-z]' '[A-Z]' )"
23 # Tags for use with version control systems
24 CVSOLDTAG="TZDATA${OLDVER_UC}"
25 CVSNEWTAG="TZDATA${NEWVER_UC}"
29 # URLs for fetching distribution files, etc.
30 DISTURL="ftp://ftp.iana.org/tz/releases/tzdata${NEWVER}.tar.gz"
31 SIGURL="${DISTURL}.asc"
32 NEWSURL="https://github.com/eggert/tz/raw/${GITHUBTAG}/NEWS"
35 REPODIR="src/external/public-domain/tz/dist" # relative to the NetBSD CVS repo
36 TZDISTDIR="$(pwd)/dist" # should be .../external/public-domain/tz/dist
37 WORKDIR="$(pwd)/update-work/${NEWVER}"
38 EXTRACTDIR="${WORKDIR}/extract"
40 # Files in the work directory
41 DISTFILE="${WORKDIR}/${DISTURL##*/}"
42 SIGFILE="${DISTFILE}.sig"
43 PGPVERIFYLOG="${WORKDIR}/pgpverify.log"
44 NEWSFILE="${WORKDIR}/NEWS"
45 NEWSTRIMFILE="${WORKDIR}/NEWS.trimmed"
46 IMPORTMSGFILE="${WORKDIR}/import.msg"
47 IMPORTDONEFILE="${WORKDIR}/import.done"
48 MERGSMSGFILE="${WORKDIR}/merge.msg"
49 MERGEDONEFILE="${WORKDIR}/merge.done"
50 COMMITMERGEDONEFILE="${WORKDIR}/commitmerge.done"
54 local really_do_it=false
57 echo "In directory $(pwd)"
58 echo "ABOUT TO DO:" "$(shell_quote "$@")"
59 read -p "Really do it? [yes/no/quit] " reply
61 [yY]*) really_do_it=true ;;
62 [nN]*) really_do_it=false ;;
68 if $really_do_it; then
69 echo "REALLY DOING IT NOW..."
72 echo "NOT REALLY DOING THE ABOVE COMMAND"
76 # Quote args to make them safe in the shell.
77 # Usage: quotedlist="$(shell_quote args...)"
79 # After building up a quoted list, use it by evaling it inside
80 # double quotes, like this:
81 # eval "set -- $quotedlist"
83 # eval "\$command $quotedlist \$filename"
89 LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII
96 # Convert each embedded ' to '\'',
97 # then insert ' at the beginning of the first line,
98 # and append ' at the end of the last line.
99 # Finally, elide unnecessary '' pairs at the
100 # beginning and end of the result and as part of
101 # '\'''\'' sequences that result from multiple
102 # adjacent quotes in he input.
103 qarg="$(printf "%s\n" "$arg" | \
104 ${SED:-sed} -e "s/'/'\\\\''/g" \
105 -e "1s/^/'/" -e "\$s/\$/'/" \
106 -e "1s/^''//" -e "\$s/''\$//" \
111 # Arg is not the empty string, and does not contain
112 # any unsafe characters. Leave it unchanged for
117 result="${result}${result:+ }${qarg}"
119 printf "%s\n" "$result"
124 [ -n "${CVSROOT}" ] && return 0
125 CVSROOT="$( cat ./CVS/Root )"
126 [ -n "${CVSROOT}" ] && return 0
127 echo >&2 "Failed to set CVSROOT value"
133 mkdir -p "${WORKDIR}"
138 [ -f "${DISTFILE}" ] || ftp -o "${DISTFILE}" "${DISTURL}"
139 [ -f "${SIGFILE}" ] || ftp -o "${SIGFILE}" "${SIGURL}"
140 [ -f "${NEWSFILE}" ] || ftp -o "${NEWSFILE}" "${NEWSURL}"
145 { gpg --verify "${SIGFILE}" "${DISTFILE}"
146 echo gpg exit status $?
147 } 2>&1 | tee "${PGPVERIFYLOG}"
149 # The output should contain lines that match all the following regexps
152 if ! grep -q -e "^${line}\$" "${PGPVERIFYLOG}"; then
153 echo >&2 "Failed to verify signature: ${line}"
157 gpg: Signature made .* using RSA key ID 62AA7E34
158 gpg: Good signature from "Paul Eggert <eggert@cs.ucla.edu>"
159 Primary key fingerprint: 7E37 92A9 D8AC F7D6 33BC 1588 ED97 E90E 62AA 7E34
166 [ -f "${EXTRACTDIR}/zone.tab" ] && return
167 mkdir -p "${EXTRACTDIR}"
168 tar -z -xf "${DISTFILE}" -C "${EXTRACTDIR}"
173 [ -f "${EXTRACTDIR}/NEWS" ] && return
174 cp -p "${NEWSFILE}" "${EXTRACTDIR}"/NEWS
177 # Find the relevant part of the NEWS file for all releases between
178 # OLDVER and NEWVER, and save them to NEWSTRIMFILE.
182 [ -s "${NEWSTRIMFILE}" ] && return
183 awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
186 /^Release [0-9]+[a-z]+ - .*/ {
187 # "Release <version> - <date>"
188 inrange = ($2 > oldver && $2 <= newver)
190 // { if (inrange) print; }
192 <"${NEWSFILE}" >"${NEWSTRIMFILE}"
195 # Create IMPORTMSGFILE from NEWSTRIMFILE, by ignoring some sections,
196 # keeping only the first sentence from paragraphs in other sections,
197 # and changing the format.
199 # The result should be edited by hand before performing a cvs commit.
200 # A message to that effect is inserted at the beginning of the file.
204 [ -s "${IMPORTMSGFILE}" ] && return
206 EDIT ME: Edit this file and then delete the lines marked "EDIT ME".
207 EDIT ME: This file will be used as a log message for the "cvs commit" that
208 EDIT ME: imports tzdata${NEWVER}. The initial contents of this file were
209 EDIT ME: generated from ${NEWSFILE}.
212 awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
213 -v disturl="${DISTURL}" -v newsurl="${NEWSURL}" \
221 print "Import tzdata"newver" from "disturl;
222 #print "and NEWS file from "newsurl;
225 # "Release <version> - <date>"
227 date = gensub(".* - ", "", 1, $0);
229 print "Summary of changes in tzdata"ver \
232 /^$/ { blankline = 1; havesentence = 0; }
233 /^ Changes affecting/ { goodsection = 0; }
234 /^ Changes affecting.*time/ { goodsection = 1; }
235 /^ Changes affecting.*data/ { goodsection = 1; }
236 /^ Changes affecting.*documentation/ || \
237 /^ Changes affecting.*commentary/ {
238 t = gensub("^ *", "", 1, $0);
239 t = gensub("\\.*$", ".", 1, t);
243 /^ .*/ && goodsection {
244 # In a paragraph in a "good" section.
245 # Ignore leading spaces, and ignore anything
246 # after the first sentence.
247 # First line of paragraph gets a bullet.
248 t = gensub("^ *", "", 1, $0);
249 t = gensub("\\. .*", ".", 1, t);
250 if (blankline) print bullet t;
251 else if (! havesentence) print indent t;
252 havesentence = (havesentence || (t ~ "\\.$"));
254 /./ { blankline = 0; }
257 } >"${IMPORTMSGFILE}"
262 if [ -s "${IMPORTMSGFILE}" ] \
263 && ! grep -q '^EDIT' "${IMPORTMSGFILE}"
265 return 0 # file has already been edited
267 # Pass both IMPORTMSGFILE and NEWSFILE to the editor, so that the
268 # user can easily consult NEWSFILE while editing IMPORTMSGFILE.
269 vi "${IMPORTMSGFILE}" "${NEWSFILE}"
274 if [ -e "${IMPORTDONEFILE}" ]; then
276 The CVS import has already been performed.
280 if ! [ -s "${IMPORTMSGFILE}" ] \
281 || grep -q '^EDIT' "${IMPORTMSGFILE}"
284 The message file ${IMPORTMSGFILE}
285 has not been properly edited.
286 Not performing cvs import.
290 ( cd "${EXTRACTDIR}" &&
291 DOIT cvs -d "${CVSROOT}" import -m "$(cat "${IMPORTMSGFILE}")" \
292 "${REPODIR}" "${CVSBRANCHTAG}" "${CVSNEWTAG}"
293 ) && touch "${IMPORTDONEFILE}"
299 cd "${TZDISTDIR}" || exit 1
300 if [ -e "${MERGEDONEFILE}" ]; then
302 The CVS merge has already been performed.
306 DOIT cvs -d "${CVSROOT}" update -j"${CVSOLDTAG}" -j"${CVSNEWTAG}" \
307 && touch "${MERGEDONEFILE}"
312 cd "${TZDISTDIR}" || exit 1
313 if grep -l '^[<=>][<=>][<=>]' *
316 There appear to be conflicts in the files listed above.
317 Resolve conflicts, then re-run this script.
325 cd "${TZDISTDIR}" || exit 1
326 if grep -l '^[<=>][<=>][<=>]' *
329 There still appear to be conflicts in the files listed above.
330 Not performing cvs commit.
334 if [ -e "${COMMITMERGEDONEFILE}" ]; then
336 The CVS commmit (of the merge result) has already been performed.
340 DOIT cvs -d "${CVSROOT}" commit -m "Merge tzdata${NEWVER}" \
341 && touch "${COMMITMERGEDONEFILE}"
347 Also do the following:
348 * Edit src/doc/3RDPARTY
349 * Edit src/doc/CHANGES
350 * Edit src/distrib/sets/base/mi if the set of installed files has changed.
351 * Submit pullup requests for all active release branches.