Home | History | Annotate | Line # | Download | only in tz
tzdata2netbsd revision 1.11
      1  1.11  kre # $NetBSD: tzdata2netbsd,v 1.11 2016/11/03 10:11:05 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.1  apb # 1. Edit OLDVER and NEWVER below.
      8   1.9  agc # 2. Make sure that you have Paul Eggert's 4K RSA public key in your
      9   1.9  agc #    keyring (62AA7E34, eggert (a] cs.ucla.edu)
     10   1.9  agc # 3. Run this script.  You will be prompted for confirmation before
     11   1.1  apb #    anything major (such as a cvs operation).
     12   1.9  agc # 4. If something fails, abort the script and fix it.
     13   1.9  agc # 5. Re-run this script until you are happy.  It's designed to
     14   1.1  apb #    be re-run over and over, and later runs will try not to
     15   1.1  apb #    redo non-trivial work done by earlier runs.
     16   1.1  apb #
     17   1.1  apb 
     18  1.11  kre OLDVER=2016h
     19  1.11  kre NEWVER=2016i
     20   1.1  apb 
     21   1.1  apb # Uppercase variants of OLDVER and NEWVER
     22   1.1  apb OLDVER_UC="$( echo "${OLDVER}" | tr '[a-z]' '[A-Z]' )"
     23   1.1  apb NEWVER_UC="$( echo "${NEWVER}" | tr '[a-z]' '[A-Z]' )"
     24   1.1  apb 
     25   1.1  apb # Tags for use with version control systems
     26   1.1  apb CVSOLDTAG="TZDATA${OLDVER_UC}"
     27   1.1  apb CVSNEWTAG="TZDATA${NEWVER_UC}"
     28   1.1  apb CVSBRANCHTAG="TZDATA"
     29   1.1  apb GITHUBTAG="${NEWVER}"
     30   1.1  apb 
     31   1.1  apb # URLs for fetching distribution files, etc.
     32   1.1  apb DISTURL="ftp://ftp.iana.org/tz/releases/tzdata${NEWVER}.tar.gz"
     33   1.1  apb SIGURL="${DISTURL}.asc"
     34   1.1  apb NEWSURL="https://github.com/eggert/tz/raw/${GITHUBTAG}/NEWS"
     35   1.1  apb 
     36   1.1  apb # Directories
     37   1.2  apb REPODIR="src/external/public-domain/tz/dist" # relative to the NetBSD CVS repo
     38   1.3  apb TZDISTDIR="$(pwd)/dist" # should be .../external/public-domain/tz/dist
     39   1.1  apb WORKDIR="$(pwd)/update-work/${NEWVER}"
     40   1.1  apb EXTRACTDIR="${WORKDIR}/extract"
     41   1.1  apb 
     42   1.1  apb # Files in the work directory
     43   1.1  apb DISTFILE="${WORKDIR}/${DISTURL##*/}"
     44   1.1  apb SIGFILE="${DISTFILE}.sig"
     45   1.5  apb PGPVERIFYLOG="${WORKDIR}/pgpverify.log"
     46   1.1  apb NEWSFILE="${WORKDIR}/NEWS"
     47   1.1  apb NEWSTRIMFILE="${WORKDIR}/NEWS.trimmed"
     48   1.1  apb IMPORTMSGFILE="${WORKDIR}/import.msg"
     49   1.5  apb IMPORTDONEFILE="${WORKDIR}/import.done"
     50   1.1  apb MERGSMSGFILE="${WORKDIR}/merge.msg"
     51   1.5  apb MERGEDONEFILE="${WORKDIR}/merge.done"
     52   1.5  apb COMMITMERGEDONEFILE="${WORKDIR}/commitmerge.done"
     53   1.1  apb 
     54   1.9  agc EDITOR=${EDITOR:-vi}
     55   1.9  agc 
     56   1.1  apb DOIT()
     57   1.1  apb {
     58   1.1  apb 	local really_do_it=false
     59   1.1  apb 	local reply
     60   1.1  apb 
     61   1.3  apb 	echo "In directory $(pwd)"
     62   1.1  apb 	echo "ABOUT TO DO:" "$(shell_quote "$@")"
     63   1.1  apb 	read -p "Really do it? [yes/no/quit] " reply
     64   1.1  apb 	case "${reply}" in
     65   1.1  apb 	[yY]*)	really_do_it=true ;;
     66   1.1  apb 	[nN]*)	really_do_it=false ;;
     67   1.1  apb 	[qQ]*)
     68   1.1  apb 		echo "Aborting"
     69   1.1  apb 		return 1
     70   1.1  apb 		;;
     71   1.1  apb 	esac
     72   1.1  apb 	if $really_do_it; then
     73   1.1  apb 		echo "REALLY DOING IT NOW..."
     74   1.1  apb 		"$@"
     75   1.1  apb 	else
     76   1.1  apb 		echo "NOT REALLY DOING THE ABOVE COMMAND"
     77   1.1  apb 	fi
     78   1.1  apb }
     79   1.1  apb 
     80   1.1  apb # Quote args to make them safe in the shell.
     81   1.1  apb # Usage: quotedlist="$(shell_quote args...)"
     82   1.1  apb #
     83   1.1  apb # After building up a quoted list, use it by evaling it inside
     84   1.1  apb # double quotes, like this:
     85   1.1  apb #    eval "set -- $quotedlist"
     86   1.1  apb # or like this:
     87   1.1  apb #    eval "\$command $quotedlist \$filename"
     88   1.1  apb #
     89   1.1  apb shell_quote()
     90   1.1  apb {(
     91   1.1  apb 	local result=''
     92   1.1  apb 	local arg qarg
     93   1.1  apb 	LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII
     94   1.1  apb 	for arg in "$@" ; do
     95   1.1  apb 		case "${arg}" in
     96   1.1  apb 		'')
     97   1.1  apb 			qarg="''"
     98   1.1  apb 			;;
     99   1.1  apb 		*[!-./a-zA-Z0-9]*)
    100   1.1  apb 			# Convert each embedded ' to '\'',
    101   1.1  apb 			# then insert ' at the beginning of the first line,
    102   1.1  apb 			# and append ' at the end of the last line.
    103   1.1  apb 			# Finally, elide unnecessary '' pairs at the
    104   1.1  apb 			# beginning and end of the result and as part of
    105   1.1  apb 			# '\'''\'' sequences that result from multiple
    106   1.1  apb 			# adjacent quotes in he input.
    107   1.1  apb 			qarg="$(printf "%s\n" "$arg" | \
    108   1.1  apb 			    ${SED:-sed} -e "s/'/'\\\\''/g" \
    109   1.1  apb 				-e "1s/^/'/" -e "\$s/\$/'/" \
    110   1.1  apb 				-e "1s/^''//" -e "\$s/''\$//" \
    111   1.1  apb 				-e "s/'''/'/g"
    112   1.1  apb 				)"
    113   1.1  apb 			;;
    114   1.1  apb 		*)
    115   1.1  apb 			# Arg is not the empty string, and does not contain
    116   1.1  apb 			# any unsafe characters.  Leave it unchanged for
    117   1.1  apb 			# readability.
    118   1.1  apb 			qarg="${arg}"
    119   1.1  apb 			;;
    120   1.1  apb 		esac
    121   1.1  apb 		result="${result}${result:+ }${qarg}"
    122   1.1  apb 	done
    123   1.1  apb 	printf "%s\n" "$result"
    124   1.1  apb )}
    125   1.1  apb 
    126   1.1  apb findcvsroot()
    127   1.1  apb {
    128   1.1  apb 	[ -n "${CVSROOT}" ] && return 0
    129   1.1  apb 	CVSROOT="$( cat ./CVS/Root )"
    130   1.1  apb 	[ -n "${CVSROOT}" ] && return 0
    131   1.1  apb 	echo >&2 "Failed to set CVSROOT value"
    132   1.1  apb 	return 1
    133   1.1  apb }
    134   1.1  apb 
    135   1.1  apb mkworkdir()
    136   1.1  apb {
    137   1.1  apb 	mkdir -p "${WORKDIR}"
    138   1.1  apb }
    139   1.1  apb 
    140   1.1  apb fetch()
    141   1.1  apb {
    142   1.1  apb 	[ -f "${DISTFILE}" ] || ftp -o "${DISTFILE}" "${DISTURL}"
    143   1.1  apb 	[ -f "${SIGFILE}" ] || ftp -o "${SIGFILE}" "${SIGURL}"
    144   1.1  apb 	[ -f "${NEWSFILE}" ] || ftp -o "${NEWSFILE}" "${NEWSURL}"
    145   1.1  apb }
    146   1.1  apb 
    147   1.1  apb checksig()
    148   1.1  apb {
    149   1.1  apb 	{ gpg --verify "${SIGFILE}" "${DISTFILE}"
    150   1.1  apb 	  echo gpg exit status $?
    151   1.1  apb 	} 2>&1 | tee "${PGPVERIFYLOG}"
    152   1.1  apb 
    153   1.1  apb 	# The output should contain lines that match all the following regexps
    154   1.1  apb 	#
    155   1.1  apb 	while read line; do
    156  1.11  kre 		if ! grep -E -q -e "^${line}\$" "${PGPVERIFYLOG}"; then
    157   1.1  apb 			echo >&2 "Failed to verify signature: ${line}"
    158   1.1  apb 			return 1
    159   1.1  apb 		fi
    160   1.1  apb 	done <<'EOF'
    161  1.11  kre gpg: Signature made .* using RSA key ID (62AA7E34|44AD418C)
    162   1.1  apb gpg: Good signature from "Paul Eggert <eggert (a] cs.ucla.edu>"
    163   1.1  apb gpg exit status 0
    164   1.1  apb EOF
    165   1.1  apb }
    166   1.1  apb 
    167   1.1  apb extract()
    168   1.1  apb {
    169   1.1  apb 	[ -f "${EXTRACTDIR}/zone.tab" ] && return
    170   1.1  apb 	mkdir -p "${EXTRACTDIR}"
    171   1.1  apb 	tar -z -xf "${DISTFILE}" -C "${EXTRACTDIR}"
    172   1.1  apb }
    173   1.1  apb 
    174   1.2  apb addnews()
    175   1.2  apb {
    176   1.2  apb 	[ -f "${EXTRACTDIR}/NEWS" ] && return
    177   1.2  apb 	cp -p "${NEWSFILE}" "${EXTRACTDIR}"/NEWS
    178   1.2  apb }
    179   1.2  apb 
    180   1.1  apb # Find the relevant part of the NEWS file for all releases between
    181   1.1  apb # OLDVER and NEWVER, and save them to NEWSTRIMFILE.
    182   1.1  apb #
    183   1.1  apb trimnews()
    184   1.1  apb {
    185   1.1  apb 	[ -s "${NEWSTRIMFILE}" ] && return
    186   1.1  apb 	awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
    187   1.1  apb 	    '
    188   1.1  apb 		BEGIN {inrange = 0}
    189   1.1  apb 		/^Release [0-9]+[a-z]+ - .*/ {
    190   1.1  apb 			# "Release <version> - <date>"
    191   1.1  apb 			inrange = ($2 > oldver && $2 <= newver)
    192   1.1  apb 		}
    193   1.1  apb 		// { if (inrange) print; }
    194   1.1  apb 		' \
    195   1.1  apb 		<"${NEWSFILE}" >"${NEWSTRIMFILE}"
    196  1.10  agc 	echo "tzdata-${NEWVER}" > ${TZDISTDIR}/TZDATA_VERSION
    197   1.1  apb }
    198   1.1  apb 
    199   1.1  apb # Create IMPORTMSGFILE from NEWSTRIMFILE, by ignoring some sections,
    200   1.1  apb # keeping only the first sentence from paragraphs in other sections,
    201   1.1  apb # and changing the format.
    202   1.1  apb #
    203   1.1  apb # The result should be edited by hand before performing a cvs commit.
    204   1.1  apb # A message to that effect is inserted at the beginning of the file.
    205   1.1  apb #
    206   1.1  apb mkimportmsg()
    207   1.1  apb {
    208   1.1  apb 	[ -s "${IMPORTMSGFILE}" ] && return
    209   1.1  apb 	{ cat <<EOF
    210   1.1  apb EDIT ME: Edit this file and then delete the lines marked "EDIT ME".
    211   1.1  apb EDIT ME: This file will be used as a log message for the "cvs commit" that
    212   1.1  apb EDIT ME: imports tzdata${NEWVER}.  The initial contents of this file were
    213   1.1  apb EDIT ME: generated from ${NEWSFILE}.
    214   1.1  apb EDIT ME: 
    215   1.1  apb EOF
    216   1.1  apb 	awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
    217   1.2  apb 	    -v disturl="${DISTURL}" -v newsurl="${NEWSURL}" \
    218   1.1  apb 	    '
    219   1.1  apb 		BEGIN {
    220   1.1  apb 			bullet = "  * ";
    221   1.1  apb 			indent = "    ";
    222   1.1  apb 			blankline = 0;
    223   1.1  apb 			goodsection = 0;
    224   1.1  apb 			havesentence = 0;
    225   1.1  apb 			print "Import tzdata"newver" from "disturl;
    226   1.4  apb 			#print "and NEWS file from "newsurl;
    227   1.1  apb 		}
    228   1.1  apb 		/^Release/ {
    229   1.1  apb 			# "Release <version> - <date>"
    230   1.1  apb 			ver = $2;
    231   1.1  apb 			date = gensub(".* - ", "", 1, $0);
    232   1.1  apb 			print "";
    233   1.1  apb 			print "Summary of changes in tzdata"ver \
    234   1.1  apb 				" ("date"):";
    235   1.1  apb 		}
    236   1.1  apb 		/^$/ { blankline = 1; havesentence = 0; }
    237   1.1  apb 		/^  Changes affecting/ { goodsection = 0; }
    238   1.1  apb 		/^  Changes affecting.*time/ { goodsection = 1; }
    239   1.7  apb 		/^  Changes affecting.*data/ { goodsection = 1; }
    240   1.1  apb 		/^  Changes affecting.*documentation/ || \
    241   1.1  apb 		/^  Changes affecting.*commentary/ {
    242   1.1  apb 			t = gensub("^ *", "", 1, $0);
    243   1.1  apb 			t = gensub("\\.*$", ".", 1, t);
    244   1.1  apb 			print bullet t;
    245   1.1  apb 			goodsection = 0;
    246   1.1  apb 		}
    247   1.1  apb 		/^    .*/ && goodsection {
    248   1.1  apb 			# In a paragraph in a "good" section.
    249   1.1  apb 			# Ignore leading spaces, and ignore anything
    250   1.1  apb 			# after the first sentence.
    251   1.1  apb 			# First line of paragraph gets a bullet.
    252   1.1  apb 			t = gensub("^ *", "", 1, $0);
    253   1.1  apb 			t = gensub("\\. .*", ".", 1, t);
    254   1.1  apb 			if (blankline) print bullet t;
    255   1.1  apb 			else if (! havesentence) print indent t;
    256   1.1  apb 			havesentence = (havesentence || (t ~ "\\.$"));
    257   1.1  apb 		}
    258   1.1  apb 		/./ { blankline = 0; }
    259   1.1  apb 		' \
    260   1.1  apb 		<"${NEWSTRIMFILE}"
    261   1.1  apb 	} >"${IMPORTMSGFILE}"
    262   1.1  apb }
    263   1.1  apb 
    264   1.1  apb editimportmsg()
    265   1.1  apb {
    266   1.1  apb 	if [ -s "${IMPORTMSGFILE}" ] \
    267   1.1  apb 	&& ! grep -q '^EDIT' "${IMPORTMSGFILE}"
    268   1.1  apb 	then
    269   1.1  apb 		return 0 # file has already been edited
    270   1.1  apb 	fi
    271   1.1  apb 	# Pass both IMPORTMSGFILE and NEWSFILE to the editor, so that the
    272   1.1  apb 	# user can easily consult NEWSFILE while editing IMPORTMSGFILE.
    273   1.9  agc 	${EDITOR} "${IMPORTMSGFILE}" "${NEWSFILE}"
    274   1.1  apb }
    275   1.1  apb 
    276   1.1  apb cvsimport()
    277   1.1  apb {
    278   1.6  apb 	if [ -e "${IMPORTDONEFILE}" ]; then
    279   1.5  apb 		cat >&2 <<EOF
    280   1.5  apb The CVS import has already been performed.
    281   1.5  apb EOF
    282   1.5  apb 		return 0
    283   1.5  apb 	fi
    284   1.1  apb 	if ! [ -s "${IMPORTMSGFILE}" ] \
    285   1.1  apb 	|| grep -q '^EDIT' "${IMPORTMSGFILE}"
    286   1.1  apb 	then
    287   1.1  apb 		cat >&2 <<EOF
    288   1.1  apb The message file ${IMPORTMSGFILE}
    289   1.1  apb has not been properly edited.
    290   1.1  apb Not performing cvs import.
    291   1.1  apb EOF
    292   1.1  apb 		return 1
    293   1.1  apb 	fi
    294   1.1  apb 	( cd "${EXTRACTDIR}" &&
    295   1.1  apb 	  DOIT cvs -d "${CVSROOT}" import -m "$(cat "${IMPORTMSGFILE}")" \
    296   1.1  apb 		"${REPODIR}" "${CVSBRANCHTAG}" "${CVSNEWTAG}"
    297   1.6  apb 	) && touch "${IMPORTDONEFILE}"
    298   1.1  apb }
    299   1.1  apb 
    300   1.1  apb cvsmerge()
    301   1.5  apb {
    302   1.3  apb 
    303   1.3  apb 	cd "${TZDISTDIR}" || exit 1
    304   1.6  apb 	if [ -e "${MERGEDONEFILE}" ]; then
    305   1.5  apb 		cat >&2 <<EOF
    306   1.5  apb The CVS merge has already been performed.
    307   1.5  apb EOF
    308   1.5  apb 		return 0
    309   1.5  apb 	fi
    310   1.6  apb 	DOIT cvs -d "${CVSROOT}" update -j"${CVSOLDTAG}" -j"${CVSNEWTAG}" \
    311   1.6  apb 	&& touch "${MERGEDONEFILE}"
    312   1.5  apb }
    313   1.1  apb 
    314   1.1  apb resolveconflicts()
    315   1.1  apb {
    316   1.5  apb 	cd "${TZDISTDIR}" || exit 1
    317   1.5  apb 	if grep -l '^[<=>][<=>][<=>]' *
    318   1.5  apb 	then
    319   1.5  apb 		cat <<EOF
    320   1.5  apb There appear to be conflicts in the files listed above.
    321   1.5  apb Resolve conflicts, then re-run this script.
    322   1.1  apb EOF
    323   1.5  apb 		return 1
    324   1.5  apb 	fi
    325   1.1  apb }
    326   1.1  apb 
    327   1.1  apb cvscommitmerge()
    328   1.5  apb {
    329   1.3  apb 	cd "${TZDISTDIR}" || exit 1
    330   1.1  apb 	if grep -l '^[<=>][<=>][<=>]' *
    331   1.1  apb 	then
    332   1.1  apb 		cat >&2 <<EOF
    333   1.1  apb There still appear to be conflicts in the files listed above.
    334   1.1  apb Not performing cvs commit.
    335   1.1  apb EOF
    336   1.1  apb 		return 1
    337   1.1  apb 	fi
    338   1.6  apb 	if [ -e "${COMMITMERGEDONEFILE}" ]; then
    339   1.5  apb 		cat >&2 <<EOF
    340   1.5  apb The CVS commmit (of the merge result) has already been performed.
    341   1.5  apb EOF
    342   1.5  apb 		return 0
    343   1.5  apb 	fi
    344   1.6  apb 	DOIT cvs -d "${CVSROOT}" commit -m "Merge tzdata${NEWVER}" \
    345   1.6  apb 	&& touch "${COMMITMERGEDONEFILE}"
    346   1.5  apb }
    347   1.1  apb 
    348   1.1  apb extra()
    349   1.1  apb {
    350   1.1  apb 	cat <<EOF
    351   1.1  apb Also do the following:
    352   1.1  apb  * Edit src/doc/3RDPARTY
    353   1.1  apb  * Edit src/doc/CHANGES
    354  1.11  kre  * Edit src/distrib/sets/lists/base/mi if the set of installed files altered.
    355   1.1  apb  * Submit pullup requests for all active release branches.
    356   1.1  apb  * rm -rf ${WORKDIR}
    357   1.1  apb EOF
    358   1.1  apb }
    359   1.1  apb 
    360   1.1  apb main()
    361   1.1  apb {
    362   1.1  apb 	set -e
    363   1.1  apb 	findcvsroot
    364   1.1  apb 	mkworkdir
    365   1.1  apb 	fetch
    366   1.1  apb 	checksig
    367   1.1  apb 	extract
    368   1.2  apb 	addnews
    369   1.1  apb 	trimnews
    370   1.1  apb 	mkimportmsg
    371   1.1  apb 	editimportmsg
    372   1.1  apb 	cvsimport
    373   1.1  apb 	cvsmerge
    374   1.1  apb 	resolveconflicts
    375   1.1  apb 	cvscommitmerge
    376   1.1  apb 	extra
    377   1.1  apb }
    378   1.1  apb 
    379   1.1  apb main "$@"
    380