[BACK]Return to tzdata2netbsd CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / public-domain / tz

File: [cvs.NetBSD.org] / src / external / public-domain / tz / tzdata2netbsd (download)

Revision 1.11, Thu Nov 3 10:11:05 2016 UTC (5 years, 9 months ago) by kre
Branch: MAIN
CVS Tags: prg-localcount2-base3, prg-localcount2-base2, prg-localcount2-base1, prg-localcount2-base, prg-localcount2, pgoyette-localcount-20170426, pgoyette-localcount-20170320, pgoyette-localcount-20170107, pgoyette-localcount-20161104, pgoyette-compat-base, pgoyette-compat-0322, pgoyette-compat-0315, perseant-stdc-iso10646-base, perseant-stdc-iso10646, netbsd-8-base, matt-nb8-mediatek-base, matt-nb8-mediatek, bouyer-socketcan-base1, bouyer-socketcan-base, bouyer-socketcan
Branch point for: pgoyette-compat, netbsd-8
Changes since 1.10: +6 -7 lines


This script needed some updates for an earlier tzdata upgrade
(one which used a different key for the signature of the data file...)
Allow either key to work.   Also update the name of the sets list
file to match modern reality (only affects instructions issued to user.)

I skipped committing these changes until it had been used a few times
to verify that it actually works properly...   it seems to.

# $NetBSD: tzdata2netbsd,v 1.11 2016/11/03 10:11:05 kre Exp $

# For use by NetBSD developers when updating to new versions of tzdata.
#
# 0. Be in an up-to-date checkout of src/external/public-domain/tz
#    from NetBSD-current.
# 1. Edit OLDVER and NEWVER below.
# 2. Make sure that you have Paul Eggert's 4K RSA public key in your
#    keyring (62AA7E34, eggert@cs.ucla.edu)
# 3. Run this script.  You will be prompted for confirmation before
#    anything major (such as a cvs operation).
# 4. If something fails, abort the script and fix it.
# 5. Re-run this script until you are happy.  It's designed to
#    be re-run over and over, and later runs will try not to
#    redo non-trivial work done by earlier runs.
#

OLDVER=2016h
NEWVER=2016i

# Uppercase variants of OLDVER and NEWVER
OLDVER_UC="$( echo "${OLDVER}" | tr '[a-z]' '[A-Z]' )"
NEWVER_UC="$( echo "${NEWVER}" | tr '[a-z]' '[A-Z]' )"

# Tags for use with version control systems
CVSOLDTAG="TZDATA${OLDVER_UC}"
CVSNEWTAG="TZDATA${NEWVER_UC}"
CVSBRANCHTAG="TZDATA"
GITHUBTAG="${NEWVER}"

# URLs for fetching distribution files, etc.
DISTURL="ftp://ftp.iana.org/tz/releases/tzdata${NEWVER}.tar.gz"
SIGURL="${DISTURL}.asc"
NEWSURL="https://github.com/eggert/tz/raw/${GITHUBTAG}/NEWS"

# Directories
REPODIR="src/external/public-domain/tz/dist" # relative to the NetBSD CVS repo
TZDISTDIR="$(pwd)/dist" # should be .../external/public-domain/tz/dist
WORKDIR="$(pwd)/update-work/${NEWVER}"
EXTRACTDIR="${WORKDIR}/extract"

# Files in the work directory
DISTFILE="${WORKDIR}/${DISTURL##*/}"
SIGFILE="${DISTFILE}.sig"
PGPVERIFYLOG="${WORKDIR}/pgpverify.log"
NEWSFILE="${WORKDIR}/NEWS"
NEWSTRIMFILE="${WORKDIR}/NEWS.trimmed"
IMPORTMSGFILE="${WORKDIR}/import.msg"
IMPORTDONEFILE="${WORKDIR}/import.done"
MERGSMSGFILE="${WORKDIR}/merge.msg"
MERGEDONEFILE="${WORKDIR}/merge.done"
COMMITMERGEDONEFILE="${WORKDIR}/commitmerge.done"

EDITOR=${EDITOR:-vi}

DOIT()
{
	local really_do_it=false
	local reply

	echo "In directory $(pwd)"
	echo "ABOUT TO DO:" "$(shell_quote "$@")"
	read -p "Really do it? [yes/no/quit] " reply
	case "${reply}" in
	[yY]*)	really_do_it=true ;;
	[nN]*)	really_do_it=false ;;
	[qQ]*)
		echo "Aborting"
		return 1
		;;
	esac
	if $really_do_it; then
		echo "REALLY DOING IT NOW..."
		"$@"
	else
		echo "NOT REALLY DOING THE ABOVE COMMAND"
	fi
}

# Quote args to make them safe in the shell.
# Usage: quotedlist="$(shell_quote args...)"
#
# After building up a quoted list, use it by evaling it inside
# double quotes, like this:
#    eval "set -- $quotedlist"
# or like this:
#    eval "\$command $quotedlist \$filename"
#
shell_quote()
{(
	local result=''
	local arg qarg
	LC_COLLATE=C ; export LC_COLLATE # so [a-zA-Z0-9] works in ASCII
	for arg in "$@" ; do
		case "${arg}" in
		'')
			qarg="''"
			;;
		*[!-./a-zA-Z0-9]*)
			# Convert each embedded ' to '\'',
			# then insert ' at the beginning of the first line,
			# and append ' at the end of the last line.
			# Finally, elide unnecessary '' pairs at the
			# beginning and end of the result and as part of
			# '\'''\'' sequences that result from multiple
			# adjacent quotes in he input.
			qarg="$(printf "%s\n" "$arg" | \
			    ${SED:-sed} -e "s/'/'\\\\''/g" \
				-e "1s/^/'/" -e "\$s/\$/'/" \
				-e "1s/^''//" -e "\$s/''\$//" \
				-e "s/'''/'/g"
				)"
			;;
		*)
			# Arg is not the empty string, and does not contain
			# any unsafe characters.  Leave it unchanged for
			# readability.
			qarg="${arg}"
			;;
		esac
		result="${result}${result:+ }${qarg}"
	done
	printf "%s\n" "$result"
)}

findcvsroot()
{
	[ -n "${CVSROOT}" ] && return 0
	CVSROOT="$( cat ./CVS/Root )"
	[ -n "${CVSROOT}" ] && return 0
	echo >&2 "Failed to set CVSROOT value"
	return 1
}

mkworkdir()
{
	mkdir -p "${WORKDIR}"
}

fetch()
{
	[ -f "${DISTFILE}" ] || ftp -o "${DISTFILE}" "${DISTURL}"
	[ -f "${SIGFILE}" ] || ftp -o "${SIGFILE}" "${SIGURL}"
	[ -f "${NEWSFILE}" ] || ftp -o "${NEWSFILE}" "${NEWSURL}"
}

checksig()
{
	{ gpg --verify "${SIGFILE}" "${DISTFILE}"
	  echo gpg exit status $?
	} 2>&1 | tee "${PGPVERIFYLOG}"

	# The output should contain lines that match all the following regexps
	#
	while read line; do
		if ! grep -E -q -e "^${line}\$" "${PGPVERIFYLOG}"; then
			echo >&2 "Failed to verify signature: ${line}"
			return 1
		fi
	done <<'EOF'
gpg: Signature made .* using RSA key ID (62AA7E34|44AD418C)
gpg: Good signature from "Paul Eggert <eggert@cs.ucla.edu>"
gpg exit status 0
EOF
}

extract()
{
	[ -f "${EXTRACTDIR}/zone.tab" ] && return
	mkdir -p "${EXTRACTDIR}"
	tar -z -xf "${DISTFILE}" -C "${EXTRACTDIR}"
}

addnews()
{
	[ -f "${EXTRACTDIR}/NEWS" ] && return
	cp -p "${NEWSFILE}" "${EXTRACTDIR}"/NEWS
}

# Find the relevant part of the NEWS file for all releases between
# OLDVER and NEWVER, and save them to NEWSTRIMFILE.
#
trimnews()
{
	[ -s "${NEWSTRIMFILE}" ] && return
	awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
	    '
		BEGIN {inrange = 0}
		/^Release [0-9]+[a-z]+ - .*/ {
			# "Release <version> - <date>"
			inrange = ($2 > oldver && $2 <= newver)
		}
		// { if (inrange) print; }
		' \
		<"${NEWSFILE}" >"${NEWSTRIMFILE}"
	echo "tzdata-${NEWVER}" > ${TZDISTDIR}/TZDATA_VERSION
}

# Create IMPORTMSGFILE from NEWSTRIMFILE, by ignoring some sections,
# keeping only the first sentence from paragraphs in other sections,
# and changing the format.
#
# The result should be edited by hand before performing a cvs commit.
# A message to that effect is inserted at the beginning of the file.
#
mkimportmsg()
{
	[ -s "${IMPORTMSGFILE}" ] && return
	{ cat <<EOF
EDIT ME: Edit this file and then delete the lines marked "EDIT ME".
EDIT ME: This file will be used as a log message for the "cvs commit" that
EDIT ME: imports tzdata${NEWVER}.  The initial contents of this file were
EDIT ME: generated from ${NEWSFILE}.
EDIT ME: 
EOF
	awk -v oldver="${OLDVER}" -v newver="${NEWVER}" \
	    -v disturl="${DISTURL}" -v newsurl="${NEWSURL}" \
	    '
		BEGIN {
			bullet = "  * ";
			indent = "    ";
			blankline = 0;
			goodsection = 0;
			havesentence = 0;
			print "Import tzdata"newver" from "disturl;
			#print "and NEWS file from "newsurl;
		}
		/^Release/ {
			# "Release <version> - <date>"
			ver = $2;
			date = gensub(".* - ", "", 1, $0);
			print "";
			print "Summary of changes in tzdata"ver \
				" ("date"):";
		}
		/^$/ { blankline = 1; havesentence = 0; }
		/^  Changes affecting/ { goodsection = 0; }
		/^  Changes affecting.*time/ { goodsection = 1; }
		/^  Changes affecting.*data/ { goodsection = 1; }
		/^  Changes affecting.*documentation/ || \
		/^  Changes affecting.*commentary/ {
			t = gensub("^ *", "", 1, $0);
			t = gensub("\\.*$", ".", 1, t);
			print bullet t;
			goodsection = 0;
		}
		/^    .*/ && goodsection {
			# In a paragraph in a "good" section.
			# Ignore leading spaces, and ignore anything
			# after the first sentence.
			# First line of paragraph gets a bullet.
			t = gensub("^ *", "", 1, $0);
			t = gensub("\\. .*", ".", 1, t);
			if (blankline) print bullet t;
			else if (! havesentence) print indent t;
			havesentence = (havesentence || (t ~ "\\.$"));
		}
		/./ { blankline = 0; }
		' \
		<"${NEWSTRIMFILE}"
	} >"${IMPORTMSGFILE}"
}

editimportmsg()
{
	if [ -s "${IMPORTMSGFILE}" ] \
	&& ! grep -q '^EDIT' "${IMPORTMSGFILE}"
	then
		return 0 # file has already been edited
	fi
	# Pass both IMPORTMSGFILE and NEWSFILE to the editor, so that the
	# user can easily consult NEWSFILE while editing IMPORTMSGFILE.
	${EDITOR} "${IMPORTMSGFILE}" "${NEWSFILE}"
}

cvsimport()
{
	if [ -e "${IMPORTDONEFILE}" ]; then
		cat >&2 <<EOF
The CVS import has already been performed.
EOF
		return 0
	fi
	if ! [ -s "${IMPORTMSGFILE}" ] \
	|| grep -q '^EDIT' "${IMPORTMSGFILE}"
	then
		cat >&2 <<EOF
The message file ${IMPORTMSGFILE}
has not been properly edited.
Not performing cvs import.
EOF
		return 1
	fi
	( cd "${EXTRACTDIR}" &&
	  DOIT cvs -d "${CVSROOT}" import -m "$(cat "${IMPORTMSGFILE}")" \
		"${REPODIR}" "${CVSBRANCHTAG}" "${CVSNEWTAG}"
	) && touch "${IMPORTDONEFILE}"
}

cvsmerge()
{

	cd "${TZDISTDIR}" || exit 1
	if [ -e "${MERGEDONEFILE}" ]; then
		cat >&2 <<EOF
The CVS merge has already been performed.
EOF
		return 0
	fi
	DOIT cvs -d "${CVSROOT}" update -j"${CVSOLDTAG}" -j"${CVSNEWTAG}" \
	&& touch "${MERGEDONEFILE}"
}

resolveconflicts()
{
	cd "${TZDISTDIR}" || exit 1
	if grep -l '^[<=>][<=>][<=>]' *
	then
		cat <<EOF
There appear to be conflicts in the files listed above.
Resolve conflicts, then re-run this script.
EOF
		return 1
	fi
}

cvscommitmerge()
{
	cd "${TZDISTDIR}" || exit 1
	if grep -l '^[<=>][<=>][<=>]' *
	then
		cat >&2 <<EOF
There still appear to be conflicts in the files listed above.
Not performing cvs commit.
EOF
		return 1
	fi
	if [ -e "${COMMITMERGEDONEFILE}" ]; then
		cat >&2 <<EOF
The CVS commmit (of the merge result) has already been performed.
EOF
		return 0
	fi
	DOIT cvs -d "${CVSROOT}" commit -m "Merge tzdata${NEWVER}" \
	&& touch "${COMMITMERGEDONEFILE}"
}

extra()
{
	cat <<EOF
Also do the following:
 * Edit src/doc/3RDPARTY
 * Edit src/doc/CHANGES
 * Edit src/distrib/sets/lists/base/mi if the set of installed files altered.
 * Submit pullup requests for all active release branches.
 * rm -rf ${WORKDIR}
EOF
}

main()
{
	set -e
	findcvsroot
	mkworkdir
	fetch
	checksig
	extract
	addnews
	trimnews
	mkimportmsg
	editimportmsg
	cvsimport
	cvsmerge
	resolveconflicts
	cvscommitmerge
	extra
}

main "$@"