#!/bin/sh usage="\ Copies PO files from a PG messages repository structure to a PostgreSQL source tree. Usage: cp-po [OPTION...] SOURCEDIR DESTDIR Options: -d delete files from DESTDIR based on qualified list (-L) -f copy a PO file even if it has warnings or errors -g Git mode; combination of -u and make a commit in DESTDIR -k don't adjust CVS key words of target files; obsolete -L FILE qualified list; determines which files to copy; together with -d, all files not listed are deleted from DESTDIR -n dry run -u update target tree: adjust nls.mk and perform deletes Typical use for preparing a release: cp-po -L qualified-list-X.Y-branch.txt -g messages postgresql # (add -d before a major release) cd postgresql && git push Typical use in babel web site scripts: cp-po -f -k messages postgresql " # Written by Peter Eisentraut # Public domain set -e me=$(basename $0) if [ "$1" = '--help' ]; then echo "$usage" exit 0 fi adjustcvskeywords=true force=false run=true delete=false update_target_tree=false git_mode=false TEMP=$(getopt dfgkL:nu "$@") eval set -- "$TEMP" while true; do case $1 in -d) delete=true; shift;; -f) force=true; shift;; -g) git_mode=true; update_target_tree=true; shift;; -k) adjustcvskeywords=false; shift;; -L) qualfile=$2; test -e "$qualfile"; shift; shift;; -n) run=false; shift;; -u) update_target_tree=true; shift;; --) shift; break;; esac done srcdir=$1 if [ -z "$srcdir" ]; then echo "$me: no source directory specified" 1>&2 exit 1 fi destdir=$2 if [ -z "$destdir" ]; then echo "$me: no destination directory specified" 1>&2 exit 1 fi if $git_mode; then cd "$srcdir" remote=$(git config branch.$(git rev-parse --abbrev-ref HEAD).remote) remote_url=$(git config remote."$remote".url) git_hash=$(git rev-parse HEAD) cd - GIT_WORK_TREE=$(cd "$destdir" && pwd) export GIT_WORK_TREE GIT_DIR=$GIT_WORK_TREE/.git export GIT_DIR fi nls_mks=$(find -H "$destdir" -name nls.mk) for srcfile in $(find -H "$srcdir" -name '*.po'); do base=$(echo X"$srcfile" | sed "s,^X$srcdir/*,,") lang=$(expr $base : '\([a-z][a-zA-Z_]*\)') srccat=$(expr $base : '.*/\([^/]*\)\.po$') if [ -n "$qualfile" ] && ! grep -q -F "$srccat/$lang" "$qualfile"; then continue fi if ! msgfmt -o /dev/null -c -v $srcfile 2>/dev/null; then echo "$me: $srcfile has errors" 1>&2 msgfmt -o /dev/null -c -v $srcfile || : if $force; then echo "$me: copying anyway, as requested" 1>&2 else continue fi fi if msgfmt -o /dev/null -c -v $srcfile 2>&1 | grep -q "warning"; then echo "$me: $srcfile has warnings" 1>&2 msgfmt -o /dev/null -c -v $srcfile || : if $force; then echo "$me: copying anyway, as requested" 1>&2 else continue fi fi if grep -q -IU ' ' $srcfile; then # DOS line endings break Solaris msgfmt echo "$me: $srcfile contains DOS line endings" 1>&2 grep -n -m5 -IU ' ' $srcfile 1>&2 || : if $force; then echo "$me: copying anyway, as requested" 1>&2 else continue fi fi if msgcat $srcfile 2>&1 >/dev/null | grep -q '.'; then # checks for things like bogus escapes in msgid or msgstr echo "$me: $srcfile has potential issues" 1>&2 msgcat $srcfile >/dev/null if $force; then echo "$me: copying anyway, as requested" 1>&2 else continue fi fi if grep -E -q '#~\|' $srcfile; then echo "$me: $srcfile will fail with old gettext versions" 1>&2 grep -E -Hn '#~\|' $srcfile 1>&2 || : if $force; then echo "$me: copying anyway, as requested" 1>&2 else continue fi fi for y in $nls_mks; do destcat=$(cat $y | sed -n 's/CATALOG_NAME.*:*= *\([^ ]*\)$/\1/p') if [ -z "$destcat" ]; then echo "$me: could not determine catalog name from $y; skipped" 1>&2 continue fi if [ "$srccat" = "$destcat" ]; then targetdir=$(echo $y | sed 's,nls\.mk$,po,') targetfile=$targetdir/$lang.po if [ ! -e $targetfile ]; then if ! $update_target_tree; then if [ -e "$targetdir/LINGUAS" ]; then y2="$targetdir/LINGUAS" else y2=$y fi echo "NEW: $targetfile --- file will be copied, but do \"git add\" and fix $y2 by hand" 1>&2 fi fi if [ ! -e $targetfile ] \ || { ! $adjustcvskeywords && ! diff $srcfile $targetfile >/dev/null; } \ || ! diff -I '\(\$Header\|pgtranslation Id\|\$Id\|\$PostgreSQL\).*\$' $srcfile $targetfile >/dev/null; then echo " $srcfile --> $targetfile" mkdir -p $(dirname $targetfile) if $run; then if $adjustcvskeywords; then cat $srcfile | sed 's/^\(# *\)$Id/\1pgtranslation Id/' >$targetfile else cp $srcfile $targetfile fi chmod 644 $targetfile if $git_mode; then git add $(echo "$targetfile" | sed "s,^$destdir/,,") fi fi fi fi done done if $delete && [ -n "$qualfile" ]; then for y in $nls_mks; do destcat=$(cat $y | sed -n 's/CATALOG_NAME.*:*= *\([^ ]*\)$/\1/p') if [ -z "$destcat" ]; then echo "$me: could not determine catalog name from $y; skipped" 1>&2 continue fi destlang=$(cat $y | sed -n 's/AVAIL_LANGUAGES.*:*= *\(.*\)$/\1/p') targetdir=$(echo $y | sed 's,nls\.mk$,po,') for lang in $destlang; do if ! grep -q -F "$destcat/$lang" "$qualfile"; then if $run && $update_target_tree; then if $git_mode; then (cd $targetdir && git rm -q --ignore-unmatch $lang.po) else rm -f $targetdir/$lang.po fi else echo "should DELETE unqualified: $targetdir/$lang.po" 1>&2 fi fi done done fi if $update_target_tree; then for y in $nls_mks; do targetdir=$(echo $y | sed 's,nls\.mk$,po,') langs=$(echo $(cd $targetdir && ls *.po | sed 's/\.po$//')) if [ -e "$targetdir/LINGUAS" ]; then echo "$langs" >"$targetdir/LINGUAS" else sed -e 's/\(AVAIL_LANGUAGES.*:*=\).*$/\1 '"$langs/" $y >$y.new mv $y.new $y fi if $git_mode; then if [ -e "$targetdir/LINGUAS" ]; then git add $(echo "$targetdir/LINGUAS" | sed "s,^$destdir/,,") else git add $(echo "$y" | sed "s,^$destdir/,,") fi fi done fi if $git_mode; then git --no-pager diff --cached --check git commit -m "Translation updates Source-Git-URL: $remote_url Source-Git-Hash: $git_hash" fi