Home | History | Annotate | Line # | Download | only in tz
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