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
|
#!/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.
set -eu
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 | egrep '^\?|^.\?' | cut -c4-)
printf "%s" "$new_po_files" \
| while read nfile ; 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 $nfile" >&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'
fi
exit $rc
|