etc/protocols - sync with NetBSD-8
[minix.git] / external / public-domain / tz / tzdata2netbsd
blob03da91fc244f98b6a5078daffe603d2fdca53921
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
6 #    from NetBSD-current.
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.
16 OLDVER=2015e
17 NEWVER=2015f
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}"
26 CVSBRANCHTAG="TZDATA"
27 GITHUBTAG="${NEWVER}"
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"
34 # Directories
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"
52 DOIT()
54         local really_do_it=false
55         local reply
57         echo "In directory $(pwd)"
58         echo "ABOUT TO DO:" "$(shell_quote "$@")"
59         read -p "Really do it? [yes/no/quit] " reply
60         case "${reply}" in
61         [yY]*)  really_do_it=true ;;
62         [nN]*)  really_do_it=false ;;
63         [qQ]*)
64                 echo "Aborting"
65                 return 1
66                 ;;
67         esac
68         if $really_do_it; then
69                 echo "REALLY DOING IT NOW..."
70                 "$@"
71         else
72                 echo "NOT REALLY DOING THE ABOVE COMMAND"
73         fi
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"
82 # or like this:
83 #    eval "\$command $quotedlist \$filename"
85 shell_quote()
87         local result=''
88         local arg qarg
89         LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII
90         for arg in "$@" ; do
91                 case "${arg}" in
92                 '')
93                         qarg="''"
94                         ;;
95                 *[!-./a-zA-Z0-9]*)
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/''\$//" \
107                                 -e "s/'''/'/g"
108                                 )"
109                         ;;
110                 *)
111                         # Arg is not the empty string, and does not contain
112                         # any unsafe characters.  Leave it unchanged for
113                         # readability.
114                         qarg="${arg}"
115                         ;;
116                 esac
117                 result="${result}${result:+ }${qarg}"
118         done
119         printf "%s\n" "$result"
122 findcvsroot()
124         [ -n "${CVSROOT}" ] && return 0
125         CVSROOT="$( cat ./CVS/Root )"
126         [ -n "${CVSROOT}" ] && return 0
127         echo >&2 "Failed to set CVSROOT value"
128         return 1
131 mkworkdir()
133         mkdir -p "${WORKDIR}"
136 fetch()
138         [ -f "${DISTFILE}" ] || ftp -o "${DISTFILE}" "${DISTURL}"
139         [ -f "${SIGFILE}" ] || ftp -o "${SIGFILE}" "${SIGURL}"
140         [ -f "${NEWSFILE}" ] || ftp -o "${NEWSFILE}" "${NEWSURL}"
143 checksig()
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
150         #
151         while read line; do
152                 if ! grep -q -e "^${line}\$" "${PGPVERIFYLOG}"; then
153                         echo >&2 "Failed to verify signature: ${line}"
154                         return 1
155                 fi
156         done <<'EOF'
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
160 gpg exit status 0
164 extract()
166         [ -f "${EXTRACTDIR}/zone.tab" ] && return
167         mkdir -p "${EXTRACTDIR}"
168         tar -z -xf "${DISTFILE}" -C "${EXTRACTDIR}"
171 addnews()
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.
180 trimnews()
182         [ -s "${NEWSTRIMFILE}" ] && return
183         awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
184             '
185                 BEGIN {inrange = 0}
186                 /^Release [0-9]+[a-z]+ - .*/ {
187                         # "Release <version> - <date>"
188                         inrange = ($2 > oldver && $2 <= newver)
189                 }
190                 // { if (inrange) print; }
191                 ' \
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.
202 mkimportmsg()
204         [ -s "${IMPORTMSGFILE}" ] && return
205         { cat <<EOF
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}.
210 EDIT ME: 
212         awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
213             -v disturl="${DISTURL}" -v newsurl="${NEWSURL}" \
214             '
215                 BEGIN {
216                         bullet = "  * ";
217                         indent = "    ";
218                         blankline = 0;
219                         goodsection = 0;
220                         havesentence = 0;
221                         print "Import tzdata"newver" from "disturl;
222                         #print "and NEWS file from "newsurl;
223                 }
224                 /^Release/ {
225                         # "Release <version> - <date>"
226                         ver = $2;
227                         date = gensub(".* - ", "", 1, $0);
228                         print "";
229                         print "Summary of changes in tzdata"ver \
230                                 " ("date"):";
231                 }
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);
240                         print bullet t;
241                         goodsection = 0;
242                 }
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 ~ "\\.$"));
253                 }
254                 /./ { blankline = 0; }
255                 ' \
256                 <"${NEWSTRIMFILE}"
257         } >"${IMPORTMSGFILE}"
260 editimportmsg()
262         if [ -s "${IMPORTMSGFILE}" ] \
263         && ! grep -q '^EDIT' "${IMPORTMSGFILE}"
264         then
265                 return 0 # file has already been edited
266         fi
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}"
272 cvsimport()
274         if [ -e "${IMPORTDONEFILE}" ]; then
275                 cat >&2 <<EOF
276 The CVS import has already been performed.
278                 return 0
279         fi
280         if ! [ -s "${IMPORTMSGFILE}" ] \
281         || grep -q '^EDIT' "${IMPORTMSGFILE}"
282         then
283                 cat >&2 <<EOF
284 The message file ${IMPORTMSGFILE}
285 has not been properly edited.
286 Not performing cvs import.
288                 return 1
289         fi
290         ( cd "${EXTRACTDIR}" &&
291           DOIT cvs -d "${CVSROOT}" import -m "$(cat "${IMPORTMSGFILE}")" \
292                 "${REPODIR}" "${CVSBRANCHTAG}" "${CVSNEWTAG}"
293         ) && touch "${IMPORTDONEFILE}"
296 cvsmerge()
299         cd "${TZDISTDIR}" || exit 1
300         if [ -e "${MERGEDONEFILE}" ]; then
301                 cat >&2 <<EOF
302 The CVS merge has already been performed.
304                 return 0
305         fi
306         DOIT cvs -d "${CVSROOT}" update -j"${CVSOLDTAG}" -j"${CVSNEWTAG}" \
307         && touch "${MERGEDONEFILE}"
310 resolveconflicts()
312         cd "${TZDISTDIR}" || exit 1
313         if grep -l '^[<=>][<=>][<=>]' *
314         then
315                 cat <<EOF
316 There appear to be conflicts in the files listed above.
317 Resolve conflicts, then re-run this script.
319                 return 1
320         fi
323 cvscommitmerge()
325         cd "${TZDISTDIR}" || exit 1
326         if grep -l '^[<=>][<=>][<=>]' *
327         then
328                 cat >&2 <<EOF
329 There still appear to be conflicts in the files listed above.
330 Not performing cvs commit.
332                 return 1
333         fi
334         if [ -e "${COMMITMERGEDONEFILE}" ]; then
335                 cat >&2 <<EOF
336 The CVS commmit (of the merge result) has already been performed.
338                 return 0
339         fi
340         DOIT cvs -d "${CVSROOT}" commit -m "Merge tzdata${NEWVER}" \
341         && touch "${COMMITMERGEDONEFILE}"
344 extra()
346         cat <<EOF
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.
352  * rm -rf ${WORKDIR}
356 main()
358         set -e
359         findcvsroot
360         mkworkdir
361         fetch
362         checksig
363         extract
364         addnews
365         trimnews
366         mkimportmsg
367         editimportmsg
368         cvsimport
369         cvsmerge
370         resolveconflicts
371         cvscommitmerge
372         extra
375 main "$@"