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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
#!/bin/bash
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# git-tp-sync - downloads the latest PO files from translationproject.org
# and commits changes to your GIT repository.
#
# Copyright (C) 2007-2025 Karel Zak <kzak@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
declare -A TP_PROJECTS
# Define local directories and project names on TP.org
#
# TP_PROJECTS[<dirname>]=<project>
#
TP_PROJECTS["po"]="util-linux"
TP_PROJECTS["po-man"]="util-linux-man"
URL="rsync://translationproject.org/tp/latest"
DRYRUN="false"
LANGS=()
DIRS=()
while [[ $# -gt 0 ]]; do
case $1 in
--dry-run)
DRYRUN="true"
shift
;;
--dir)
DIRS+=("$2")
shift
shift
;;
--usage | --help)
echo "$(basename "$0") [--dir <dir>] [--dry-run] [<lang> ...]"
exit 0
;;
*)
LANGS+=("$1")
shift;
;;
esac
done
git rev-parse --is-inside-work-tree &> /dev/null
if [ "$?" -ne 0 ]; then
echo "Must be called within a Git working tree."
exit 1
fi
# default to all dirs defined by TP_PROJECTS
if [ ${#DIRS[@]} -eq 0 ]; then
DIRS=( ${!TP_PROJECTS[@]} )
fi
function get_author {
echo $(gawk 'BEGIN { FS=": " } /Last-Translator/ { sub("\\\\n\"", ""); print $2 }' "$1")
}
function get_revision {
echo $(gawk 'BEGIN { FS=": " } /PO-Revision-Date/ { sub("\\\\n\"", ""); print $2 }' "$1" \
| date '+%s' -f -)
}
function get_revision_orig {
echo $(git show HEAD:"$1" \
| gawk 'BEGIN { FS=": " } /PO-Revision-Date/ { sub("\\\\n\"", ""); print $2 }' \
| date '+%s' -f -)
}
function git_commit {
local POFILE="$1"
local MSG="$2"
local AUTHOR=$(get_author "$POFILE")
git commit --author "$AUTHOR" -m "$MSG" "$POFILE"
}
function save_modified_files {
local POFILENAME="$1"
local PODIR="$2"
local POFILE="${PODIR}/${POFILENAME}"
printf " %s : %10s : " $PODIR $POFILENAME
new_rev=$(get_revision "$POFILE")
old_rev=$(get_revision_orig "$POFILE")
if [ $new_rev -gt $old_rev ]; then
if [ "$DRYRUN" = "true" ]; then
echo " updated (ingore, dry-run)"
else
echo " updated"
git_commit $POFILE "$PODIR: update $POFILENAME (from translationproject.org)"
fi
else
echo " ok"
fi
}
function git_files {
local MODE="$1"
local PODIR="$2"
echo $(git ls-files $MODE "${PODIR}/*.po" \
| gawk '/[[:alpha:]_\-]*\.po/ { sub(".*/", ""); print $0; }' \
| sort)
}
function download_files {
local PROJECT="$1"
local PODIR="$2"
echo -n " Dowloding from ${URL}/${PROJECT} ..."
if [ ${#LANGS[@]} -eq 0 ]; then
rsync -Lrtz "$URL"/"$PROJECT"/ "$PODIR"
else
for l in "${LANGS[@]}"; do
rsync -Lrtz "$URL"/"$PROJECT"/"$l".po "$PODIR"
done
fi
echo " done"
}
function update_project {
local PROJECT="$1"
local PODIR="$2"
echo
echo "== Syncing $PROJECT to $PODIR/ ==="
download_files $PROJECT $PODIR
PO_NEW=$(git_files -o $PODIR)
PO_MOD=$(git_files -m $PODIR)
for f in $PO_MOD; do
save_modified_files $f $PODIR
done
for f in $PO_NEW; do
git add "$PODIR/$f"
git_commit "$PODIR/$f" "$PODIR: add $f (from translationproject.org)"
done
if [ -f "${PODIR}/LINGUAS" ]; then
LINGUAS=$(find $PODIR"/" -name '*.po' -type f -printf '%P\n' | sed 's/\.po//g' | sort)
echo "$LINGUAS" > "${PODIR}/LINGUAS"
if [ "$(git ls-files -m "${PODIR}/LINGUAS")" = "${PODIR}/LINGUAS" ]; then
if [ "$DRYRUN" = "true" ]; then
echo ""${PODIR}/LINGUAS" needs update"
else
git commit -m "$PODIR: update LINGUAS list" "${PODIR}/LINGUAS"
fi
fi
fi
# cleanup
git checkout -f "$PODIR"/ &> /dev/null
}
function regenerate_po_files {
local PODIR="$1"
if [ "$PODIR" = "po" ]; then
if [ "${PODIR}/Makefile" ]; then
return;
else
echo "== Updating $PODIR (be patient) =="
make -C $PODIR update-po &> /dev/null
fi
elif [ "$PODIR" = "po-man" ]; then
echo "== Updating $PODIR (be patient) =="
make gen-poman-dist
else
echo "Unsupported $PODIR directory (skip update)"
return;
fi
# ignore files where is only modified one line ("POT-Creation-Date")
PO_IGNORE=$(git diff --numstat $PODIR/*.po | gawk -v ORS=" " '/1[[:blank:]]1[[:blank:]]/ { print $3 }')
if [ -n "$PO_IGNORE" ]; then
git checkout -f $PO_IGNORE &> /dev/null
fi
if [ $(git ls-files -m "$PODIR" | wc -l) -gt 0 ]; then
if [ "$DRYRUN" = "true" ]; then
echo "${PODIR}: needs merge changes"
else
git commit -m "$PODIR: merge changes" $PODIR
fi
fi
git checkout -f "$PODIR" &> /dev/null
}
for d in "${DIRS[@]}"; do
update_project "${TP_PROJECTS[$d]}" "$d"
regenerate_po_files "$d"
done
|