1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#!/bin/sh
# dist-tools/git-commit-po-updates.sh
# A helper script to commit translation updates into Git.
# Assumes translation updates are visible to git,
# and one directory above.
#
# © Copyright 2019 - 2020 by Matthias Andree.
# Licensed under the GNU General Public License V2 or,
# at your choice, any later version.
#
# Supported modes:
# -n: dry-run, only print commands, but do not run them.
# -c: commit, print commands and run them.
# Exit codes:
# 0: success, no new po/*.po files.
# 1: error
# 2: usage was printed, nothing was done
# 3: new po/*.po files detected
set -eu
unset IFS
cd "$(realpath $(dirname $0))/.."
# see if Perl has Carp::Always available,
# and implicitly fail (set -e) if it hasn't.
perl -MCarp::Always -e ''
usage() {
printf 'Usage: %s {-n|-c}\n-n: dry-run; -c: commit\n' "$0"
exit $1
}
# print and potentially run a shell command
run() {
cmd="$1 '$2'"
printf '+ %s\n' "$cmd"
$dryrun_pfx eval "$cmd"
return $?
}
# try to parse features of a po file and build a git command
handle_po() {
pofile="$1"
logmsg1="$2" # "Update", or "Add new"
logmsg2="$3" # "to", or "for"
export logmsg1 logmsg2
if ! cmd="$(perl -WT - "$pofile" <<'_EOF'
use Encode::Locale;
use Encode;
use strict;
use Carp::Always ();
use warnings FATAL => 'uninitialized';
my ($ver, $dat, $translator, $lang, $lcod, $cset, $found);
while(<>)
{
if (/^"Project-Id-Version: (.+)\\n"/) { $ver=$1; };
if (/^"PO-Revision-Date: (.+)\\n"/) { $dat=$1; };
if (/^"Last-Translator: (.+)\\n"/) { $translator=$1; };
if (/^"Language-Team: ([^<]+?)\s+<.*>\\n"/)
{ $lang=$1; };
if (/^"Language: (.+)\\n"/) { $lcod=$1; };
if (/^"Content-Type: text\/plain; charset=(.+)\\n"/)
{ $cset = $1; };
if ($ver and $dat and $translator and $lang and $lcod and $cset) {
$found = 1;
last;
}
}
$translator = Encode::decode($cset, $translator);
if ($found) {
print Encode::encode(locale => "git commit --author '$translator' --date '$dat' -m '$ENV{logmsg1} <$lcod> $lang translation $ENV{logmsg2} $ver'", Encode::FB_CROAK);
} else {
exit(1);
}
_EOF
)"
then
echo >&2 "Parsing $pofile failed, skipping."
return 23
fi
run "$cmd" "$pofile"
return $?
}
dryrun_pfx=
docommit=
while getopts 'nc' opt ; do
case $opt in
n) dryrun_pfx=: ;;
c) docommit=y ;;
?)
usage 2 ;
esac
done
rc=0
if [ -z "$dryrun_pfx" -a -z "$docommit" ] ; then usage 2 ; fi
new_po_files=$(git status --porcelain=v1 po/*.po | grep -E '^(\?|.\?|A)' | cut -c4-)
for nfile in $new_po_files ; do
run "git add" "$nfile"
r=$?
handle_po "$nfile" "Add new" "for"
if [ $r -ne 0 -o $? -ne 0 ] ; then
echo "There were errors adding $nfile" >&2 ; rc=1
fi
done
git diff -G '^"(Project-Id-Version|PO-Revision-Date):' --name-only po/*.po \
| while read pofile ; do
if ! handle_po "$pofile" "Update" "to" ; then
echo "There were errors updating $pofile" >&2 ; rc=1
fi
done
if [ -n "$new_po_files" ] ; then
printf "Remember to add these codes to po/LINGUAS:"
for i in $new_po_files ; do
j=${i%.po}
j=${j#po/}
printf " %s" "$j"
done
printf '\n'
if [ $rc -eq 0 ] ; then rc=3 ; fi
fi
exit $rc
|