#!/bin/bash # # This script pulls all the latest data from CLDR and IANA databases, builds the TZCompile project and updates the DB # Requires a UNIX-like system with FreePascal installed. # # Enjoy! # REPO=`dirname "$0"` echo "Running in '$REPO' path." TZDB_PAS=$REPO/src/TZDBPK/TZDB.pas INPUT_VER=`cat $TZDB_PAS | sed -n "s/.*CComponentVersion\ *=\ *'\(.*\)';.*/\1/p"` CUSTOM_VER=0 CI=0 if [ "$1" == "ci" ]; then CI=1 if ! command -v git &> /dev/null; then echo "[ERR] CI mode only supported when git is installed!" exit 1 fi elif [ "$1" != "" ]; then INPUT_VER=$1 CUSTOM_VER=1 fi IFS='.'; DOT_ARR=($INPUT_VER); unset IFS; VER_0=${DOT_ARR[0]} VER_1=${DOT_ARR[1]} VER_2=${DOT_ARR[2]} VER_3=${DOT_ARR[3]} if [[ $VER_0 =~ ^[0-9]+$ ]] && [[ $VER_1 =~ ^[0-9]+$ ]] && [[ $VER_2 =~ ^[0-9]+$ ]] && [[ $VER_3 =~ ^[0-9]+$ ]]; then if [ $CUSTOM_VER -eq 0 ]; then # Increment the build number ((VER_3++)) fi echo "Will bump the version of the project to $VER_0.$VER_1.$VER_2.$VER_3." else echo "[ERR] Invalid version info provided: $INPUT_VER. Expected 'n.n.n.n' format." exit 1 fi if [ ! -d "$REPO/tz_database_latest" ] || [ ! -e "$REPO/cldr/converter.xsl" ] || [ ! -d "$REPO/src/TZDBPK" ] || [ ! -e "$REPO/src/TZCompile/TZCompile.dpr" ]; then echo "[ERR] Script located in '$REPO' but cannot find required sub-directories. Make sure you have full repo downloaded." exit 1 fi echo "Pulling the latest CLDR data from GitHub..." CLDR_XML=$REPO/cldr/windowsZones.xml wget https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml -q -O $CLDR_XML.tmp if [ "$?" -ne 0 ]; then echo "[WARN] Failed pulling down updated CLDR Windows zone information from GitHub." rm $CLDR_XML.tmp else rm $CLDR_XML mv $CLDR_XML.tmp $CLDR_XML fi echo "Converting the latest CLDR xml file to inc..." CLDR_INC=$REPO/src/TZCompile/WindowsTZ.inc cat $CLDR_XML | sed -n 's//GlobalCache.AddAlias("\1", "\2");/p' | sed "s/\"/'/g" > $CLDR_INC.tmp if [ "$?" -ne 0 ]; then echo "[ERR] Failed to convert CLDR xml file to inc." exit 1 fi rm $CLDR_INC mv $CLDR_INC.tmp $CLDR_INC ALIASES=`wc -l $CLDR_INC | sed 's/\([0-9]\) .*/\1/g'` echo "Created $ALIASES aliases." FPC_MAJOR=`fpc -iV | sed 's/\([0-9]*\)\.[0-9]*\.[0-9]*/\1/g' || 0` if [ $FPC_MAJOR -eq 0 ]; then echo "[ERR] FreePascal compiler not installed." exit 1 fi if [ $FPC_MAJOR -lt 3 ]; then echo "[ERR] Expected at least FreePascal version 3." exit 1 fi echo "Found FreePascal version `fpc -iV` installed." rm -fr $REPO/bin 2> /dev/null mkdir $REPO/bin fpc $REPO/src/TZCompile/TZCompile.dpr -FEbin -FUbin if [ "$?" -ne 0 ]; then echo "[ERR] Failed to compile the TZCompile program." exit 1 fi echo "Pulling the latest TZDB database from IANA ..." rm -rf $REPO/iana_temp 2> /dev/null wget -q https://www.iana.org/time-zones -O $REPO/time-zones.html IANA_GZ_URL=$( cat $REPO/time-zones.html | sed -nr 's/.*href="(.*tzdata.*\.tar\.gz)".*/\1/p' ) rm $REPO/time-zones.html wget -q "$IANA_GZ_URL" mv $REPO/tzdata*.tar.gz $REPO/tzdata-latest.tar.gz mkdir $REPO/iana_temp tar -xf tzdata-latest.tar.gz -C $REPO/iana_temp if [ "$?" -ne 0 ]; then echo "[ERR] Failed to pull the latest TZDB tar ball." exit 1; fi rm tzdata-latest.tar.gz IANAV=`cat $REPO/iana_temp/version` echo "Current TZDB database version is v$IANAV." FILES=( africa antarctica asia australasia backward backzone etcetera europe factory northamerica southamerica ) for fn in "${FILES[@]}"; do echo "Replacing file $fn ..." cp $REPO/iana_temp/$fn $REPO/tz_database_latest/$fn done rm -rf $REPO/iana_temp if [ "$?" -ne 0 ]; then echo "[ERR] Failed to replace required TZ files from the IANA archive." exit 1 fi # CI mode checks if [ $CI -eq 1 ]; then CHK=`git status -s $REPO/cldr $REPO/tz_database_latest` if [ "$CHK" == "" ]; then echo "Nothing has been updated. Finishing the rest of the process." exit 0 fi git add $REPO/cldr $REPO/tz_database_latest git commit -m "chore: update to the latest tzdb/cldr" fi # Compile the IANA DB TZDB_INC=$REPO/src/TZDBPK/TZDB.inc $REPO/bin/TZCompile $REPO/tz_database_latest $TZDB_INC.temp $IANAV if [ "$?" -ne 0 ]; then echo "[ERR] Failed to process latest TZDB data." exit 1 fi rm $TZDB_INC mv $TZDB_INC.temp $TZDB_INC if [ "$?" -ne 0 ]; then echo "[ERR] Failed to finalize the process." exit 1 fi # Run tests fpc $REPO/src/TZTest/TZTest.dpr -Fu$REPO/src/TZDBPK -Fu$REPO/src/TZDBLIB -FEbin -FUbin if [ "$?" -ne 0 ]; then echo "[ERR] Failed to compile the TZTest program." exit 1 fi $REPO/bin/TZTest --format=plain --all --progress --sparse if [ "$?" -ne 0 ]; then echo "[ERR] Tests failed! Please correct the errors before continuing." exit 1 fi # Update the README echo "Updating README with the new version '$IANAV'..." README=$REPO/README.md cat $README | sed "s/\(.*\*\*\)[0-9]*[a-z]*\(\*\*.*\)/\1$IANAV\2/g" > $README.tmp if [ "$?" -ne 0 ]; then echo "[ERR] Failed to update README.md file with the IANA DB version." exit 1 fi rm $README mv $README.tmp $README if [ "$?" -ne 0 ]; then echo "[ERR] Failed to finalize the update of README." exit 1 fi # Bump the version replace_tokens () { cat $1 | sed "s/$2/\1$3\2/g" > $1.tmp if [ "$?" -ne 0 ]; then exit 1 fi rm $1 mv $1.tmp $1 if [ "$?" -ne 0 ]; then exit 1 fi } VER_MAJ="$VER_0.$VER_1" VER_FULL="$VER_0.$VER_1.$VER_2.$VER_3" DPROJ_FILES=`find $REPO -type f | grep .dproj` for DPROJ in $DPROJ_FILES; do echo "Bumping the version of file '$DPROJ' to '$VER_FULL'..." cp $DPROJ $DPROJ.1 replace_tokens $DPROJ.1 '\(.*FileVersion=\)[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\(.*<\/VerInfo_Keys>\)' $VER_FULL replace_tokens $DPROJ.1 '\(.*ProductVersion=\)[0-9]*\.[0-9]*\(.*<\/VerInfo_Keys>\)' $VER_MAJ replace_tokens $DPROJ.1 '\(.*\)[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\(<\/VersionInfoKeys>\)' $VER_FULL replace_tokens $DPROJ.1 '\(.*\)[0-9]*\.[0-9]*\(<\/VersionInfoKeys>\)' $VER_MAJ replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VersionInfo>\)' $VER_0 replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VersionInfo>\)' $VER_1 replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VersionInfo>\)' $VER_2 replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VersionInfo>\)' $VER_3 replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VerInfo_MajorVer>\)' $VER_0 replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VerInfo_MinorVer>\)' $VER_1 replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VerInfo_Release>\)' $VER_2 replace_tokens $DPROJ.1 '\(.*\)[0-9]*\(<\/VerInfo_Build>\)' $VER_3 if [ "$?" -ne 0 ]; then echo "[ERR] Failed to bump versions in file '$DPROJ'!" exit 1 fi rm $DPROJ mv $DPROJ.1 $DPROJ if [ "$?" -ne 0 ]; then echo "[ERR] Failed to bump versions in file '$DPROJ'!" exit 1 fi done # update the version in the .pas module as well cat $TZDB_PAS | sed "s/\(.*CComponentVersion\ *=\ *'\).*\(';.*\)/\1$VER_FULL\2/g" > $TZDB_PAS.tmp if [ "$?" -ne 0 ]; then echo "[ERR] Failed to update TZDB.pas file with the bumped version." exit 1 fi rm $TZDB_PAS mv $TZDB_PAS.tmp $TZDB_PAS # Merge the files into one DIST=$REPO/dist if [ ! -d "$DIST" ]; then echo "[WARN] Unable to locate the distribution dorectory. Skipping the last step." echo "DONE!" exit 0 fi echo "Merging the TZDB components into one source file..." TZDB_PAS_DIST=$DIST/TZDB.pas rm $TZDB_PAS_DIST 2> /dev/null cp $REPO/media/logo-64x64.ico $DIST/TZDB.ico cat $REPO/src/TZDBPK/TZDBPK.dpk | sed 's/TZDBPK/TZDB/g' > $DIST/TZDB.dpk cleanup () { rm -fr $REPO/xx00 2> /dev/null rm -fr $REPO/xx01 2> /dev/null rm -fr $REPO/xx02 2> /dev/null } # Split the file into pieces based in includes . csplit -s $TZDB_PAS '/{\$INCLUDE.*}/' {1} 2> /dev/null if [ "$?" -ne 0 ] || [ ! -e "$REPO/xx00" ] || [ ! -e "$REPO/xx00" ] || [ ! -e "$REPO/xx00" ]; then cleanup echo "[ERR] Failed to split the TZDB unit file into chunks." exit 1 fi # We have three chunks in here. Assemble them into final file. cat $REPO/src/TZDBPK/Version.inc > $TZDB_PAS_DIST cat $REPO/xx01 | sed "s/{\$INCLUDE.*}//g" >> $TZDB_PAS_DIST cat $REPO/src/TZDBPK/TZDB.inc >> $TZDB_PAS_DIST cat $REPO/xx02 | sed "s/{\$INCLUDE.*}//g" >> $TZDB_PAS_DIST if [ "$?" -ne 0 ]; then echo "[ERR] Failed to build a packaged unit file." exit 1 fi cleanup echo "Downloading the API documentation..." wget https://raw.githubusercontent.com/wiki/pavkam/tzdb/API-Documentation.md -q -O $DIST/API.md if [ "$?" -ne 0 ]; then echo "[ERR] Failed to download the API documentation." exit 1 fi # Finish up in CI mode. if [ $CI -eq 1 ]; then TAG="$VER_0.$VER_1.$VER_2.$IANAV" git add . && git commit -m "chore: bump version" && git tag $TAG && git push origin $TAG && git push fi echo "DONE!"