From 0724c41ce83a076ca8165bd3fe9f9348b4b6ee073e876e05031e02bf1c36255c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Schr=C3=B6ter?= Date: Sat, 4 May 2024 01:30:25 +0200 Subject: [PATCH] Sync from SUSE:SLFO:Main translation-update-upstream revision ccedc12c4e71a320c3a82012fa8ac7f2 --- .gitattributes | 23 + check-translation-completeness.sh | 170 ++++ create-tlst-step1-list-all-po-projects.sh | 32 + create-tlst-step2-create-gnome_gtp.sh | 157 +++ create-tlst.conf | 11 + freedesktop_org.tlst | 6 + github.tlst | 6 + lcn-sle.tlst | 5 + misc.tlst | 12 + msgheadermerge | 59 ++ msgheadermerge-compose | 27 + msgheadermerge-empty.pot | 17 + msgheadermerge-parse | 21 + opensuse.tlst | 6 + static.tlst | 5 + translation-update-mandatory-20200601.tar.bz2 | 3 + translation-update-static.tar.bz2 | 3 + translation-update-upstream-20200601.tar.bz2 | 3 + translation-update-upstream-AUTHORS | 1 + translation-update-upstream-COPYING | 339 +++++++ translation-update-upstream-HOWTO | 109 ++ translation-update-upstream-README | 5 + translation-update-upstream-embedded-README | 17 + translation-update-upstream-embedded.patch | 19 + ...n-update-upstream-to-translation-update.sh | 276 +++++ translation-update-upstream.changes | 348 +++++++ translation-update-upstream.in | 276 +++++ translation-update-upstream.spec | 157 +++ upstream-collect-template.hook | 20 + upstream-collect.conf | 20 + upstream-collect.sh | 955 ++++++++++++++++++ upstream-gnome_gtp-not-on-media.tlst | 6 + upstream-gnome_gtp.hook | 19 + upstream-gnome_gtp.tlst | 214 ++++ 34 files changed, 3347 insertions(+) create mode 100644 .gitattributes create mode 100644 check-translation-completeness.sh create mode 100644 create-tlst-step1-list-all-po-projects.sh create mode 100644 create-tlst-step2-create-gnome_gtp.sh create mode 100644 create-tlst.conf create mode 100644 freedesktop_org.tlst create mode 100644 github.tlst create mode 100644 lcn-sle.tlst create mode 100644 misc.tlst create mode 100644 msgheadermerge create mode 100644 msgheadermerge-compose create mode 100644 msgheadermerge-empty.pot create mode 100644 msgheadermerge-parse create mode 100644 opensuse.tlst create mode 100644 static.tlst create mode 100644 translation-update-mandatory-20200601.tar.bz2 create mode 100644 translation-update-static.tar.bz2 create mode 100644 translation-update-upstream-20200601.tar.bz2 create mode 100644 translation-update-upstream-AUTHORS create mode 100644 translation-update-upstream-COPYING create mode 100644 translation-update-upstream-HOWTO create mode 100644 translation-update-upstream-README create mode 100644 translation-update-upstream-embedded-README create mode 100644 translation-update-upstream-embedded.patch create mode 100644 translation-update-upstream-to-translation-update.sh create mode 100644 translation-update-upstream.changes create mode 100644 translation-update-upstream.in create mode 100644 translation-update-upstream.spec create mode 100644 upstream-collect-template.hook create mode 100644 upstream-collect.conf create mode 100644 upstream-collect.sh create mode 100644 upstream-gnome_gtp-not-on-media.tlst create mode 100644 upstream-gnome_gtp.hook create mode 100644 upstream-gnome_gtp.tlst diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/check-translation-completeness.sh b/check-translation-completeness.sh new file mode 100644 index 0000000..349e7cc --- /dev/null +++ b/check-translation-completeness.sh @@ -0,0 +1,170 @@ +#!/bin/bash + +set -o errexit +# We need stable text format +export LANG=C + +if ! test -d po-full ; then + echo >&2 "$0: You need \"po-full\" directory. Call this script only after ./upstream-collect.sh" + exit 1 +fi + +cd po-full +ALL_LNG="$( + for PO in */*.po ; do + LNG=${PO%.po} + LNG=${LNG##*/} + echo "$LNG" + done | + sort -u | + tr '\n' ' ' +)" +#echo >&2 "$0 DBG: ALL_LNG=\"$ALL_LNG\"" + +for DOMAIN in * ; do + for LNG in $ALL_LNG ; do + # Sanitize to not contain "," or ".": + LNG_SN=${LNG//,/__COMMA__} + LNG_SN=${LNG_SN//./__PERIOD__} + DOMAIN_SN=${DOMAIN//,/__COMMA__} + DOMAIN_SN=${DOMAIN_SN//./__PERIOD__} + echo -n "$LNG_SN,$DOMAIN_SN," + PO=$DOMAIN/$LNG.po + if test -f "$PO" ; then + msgfmt --statistics -o /dev/null $PO 2>&1 + else + msgfmt --statistics -o /dev/null ../pot/$DOMAIN.pot 2>&1 + fi + done +done | +#tee ../check-translation-completeness-DBG1.log | +( +# "F1 translated messages, F2 fuzzy translations, F3 untranslated messages." Some fields can be missing + IFS=,. + while read LNG DOMAIN F1 F2 F3 F4 ; do + LNG=${LNG//__COMMA__/,} + LNG=${LNG//__PERIOD__/.} + DOMAIN=${DOMAIN//__COMMA__/,} + DOMAIN=${DOMAIN//__PERIOD__/.} + TRANSLATED=0 + UNTRANSLATED=0 + FUZZY=0 + if test -n "$F4" ; then + echo >&2 "$0: Too long output of \"msgfmt --statistics -o /dev/null po-full/$DOMAIN/$LNG.po\": \"$F4\"" + exit 1 + fi + for STRING in "$F1" "$F2" "$F3" "$F4" ; do + STRING=${STRING# } + case "$STRING" in + *" translated message" ) + TRANSLATED=${STRING% translated message} + ;; + *" translated messages" ) + TRANSLATED=${STRING% translated messages} + ;; + *" fuzzy translation" ) + FUZZY=${STRING% fuzzy translation} + ;; + *" fuzzy translations" ) + FUZZY=${STRING% fuzzy translations} + ;; + *" untranslated message" ) + UNTRANSLATED=${STRING% untranslated message} + ;; + *" untranslated messages" ) + UNTRANSLATED=${STRING% untranslated messages} + ;; + "" ) + ;; + * ) + echo >&2 "$0: Unknown format of \"msgfmt --statistics -o /dev/null po-full/$DOMAIN/$LNG.po\": \"$STRING\"" + exit 1 + ;; + esac + done + #echo >&2 -n "$0 DBG: LNG=$LNG DOMAIN=$DOMAIN F1=\"$F1\" F2=\"$F2\" F3=\"$F3\" F4=\"$F4\" TRANSLATED=$TRANSLATED UNTRANSLATED=$UNTRANSLATED FUZZY=$FUZZY" + let UNTRANSLATED+=FUZZY || : + let ALL=TRANSLATED+UNTRANSLATED || : + #echo >&2 " DBG: ALL=$ALL all_UNTRANSLATED=$UNTRANSLATED" + let PERCENTAGE=100"*"TRANSLATED/ALL || : + echo "\"$LNG\",\"$DOMAIN\",$PERCENTAGE,$UNTRANSLATED,$ALL" + done +) | +#tee ../check-translation-completeness-DBG2.log | +( + echo >../check-translation-completeness-by-domain.csv "\"Language\",\"Domain\",\"Translated %\",\"Untranslated #\",\"All #\"" + tee -a ../check-translation-completeness-by-domain.csv +) | +sort | +( + echo >../check-translation-completeness-by-language.csv "\"Language\",\"Domain\",\"Translated %\",\"Untranslated #\",\"All #\"" + tee -a ../check-translation-completeness-by-language.csv +) | +( + IFS="," + while read LNG DOMAIN PERCENTAGE UNTRANSLATED ALL ; do + LNG=${LNG//\"} + case $LNG in + ar ) + LNG_NAME="Arabic" + ;; + pt_BR ) + LNG_NAME="Brazilian Portuguese" + ;; + zh_CN ) + LNG_NAME="Chinese Simplified" + ;; + zh_TW ) + LNG_NAME="Chinese Traditional" + ;; + cs ) + LNG_NAME="Czech" + ;; + nl ) + LNG_NAME="Dutch" + ;; + fr ) + LNG_NAME="French" + ;; + de ) + LNG_NAME="German" + ;; + hu ) + LNG_NAME="Hungarian" + ;; + it ) + LNG_NAME="Italian" + ;; + ja ) + LNG_NAME="Japanese" + ;; + ko ) + LNG_NAME="Korean" + ;; + pl ) + LNG_NAME="Polish" + ;; + ru ) + LNG_NAME="Russian" + ;; + es ) + LNG_NAME="Spanish" + ;; + sv ) + LNG_NAME="Swedish" + ;; + * ) + continue + ;; + esac + echo "\"$LNG_NAME\",$DOMAIN,$PERCENTAGE,$UNTRANSLATED,$ALL" + done +) | +sort | +( + echo >../check-translation-completeness-supported.csv "\"Language\",\"Domain\",\"Translated %\",\"Untranslated #\",\"All #\"" + cat >../check-translation-completeness-supported.csv +) + +cd .. +zip check-translation-completeness.zip check-translation-completeness*.csv diff --git a/create-tlst-step1-list-all-po-projects.sh b/create-tlst-step1-list-all-po-projects.sh new file mode 100644 index 0000000..17def4a --- /dev/null +++ b/create-tlst-step1-list-all-po-projects.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# This program searches for all active translations in the distro and +# does dumb guesses of project - domain relations. +# +# It needs access to distro RPMs. +# +set -o errexit + +source ${0%create-tlst-step1-list-all-po-projects.sh}create-tlst.conf + +for i in $BINARY_REPO/{$BINARY_ARCH,noarch}/*.rpm ; do rpm -q --queryformat=%{name} -p $i ; echo : ; rpm -qlp $i | grep LC_MESSAGES || : ; done | + sed "s~^$BINARY_REPO/($BINARY_ARCH|noarch)~~" >create-tlst-temp-all-po-files.lst + +cat create-tlst-temp-all-po-files.lst | +sed ' +/:$/ { + h + d +} +/LC_MESSAGES$/d +s:.*/LC_MESSAGES/:: +/.*/ { + G + s/\(.*\)\.mo\n\(.*\):/\2 \1/ +} +/kde3-i18n/d +' | +uniq | +LC_COLLATE=C LC_ALL= sort -u >create-tlst-temp-all-po-projects.lst + +rm create-tlst-temp-all-po-files.lst diff --git a/create-tlst-step2-create-gnome_gtp.sh b/create-tlst-step2-create-gnome_gtp.sh new file mode 100644 index 0000000..b53d4f4 --- /dev/null +++ b/create-tlst-step2-create-gnome_gtp.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +# This program creates makes dumb guesses about relation of upstream +# projects and openSUSE packages and creates initial configuration file. +# +# It needs osc and net access. +# +# It tries to assign packages to GNOME GTP projects and adds other known packages. +# + +set -o errexit + +source ${0%create-tlst-step2-create-gnome_gtp.sh}upstream-collect.conf + +for REPOSITORY in ${OSC_REPOSITORIES[@]} ; do + osc ${OSC_APIURL:+--apiurl=$OSC_APIURL} list $REPOSITORY +done | sort -u >create-tlst-temp-osc-projects.lst + +# branches tried for all apps: +KNOWN_BRANCHES="gnome-3-34|gnome-3-36" +# branches tried apps with the same name base: +# Do not forget hardcoded strings in the code below! +APP_BRANCHES="|gimp-2-8|gimp-2-10|gtk-3-22|gtk-3-24|gtk-2-24|glib-2.62|glib-2.64" +# FIXME: support for libgda:release-3-0-branch gnome-background:gnome-2-22 + +echo "# This file was generated $(LANG=C LC_ALL=C date) by create-tlst-step2-create-gnome_gtp.sh." >upstream-gnome_gtp.tlst +echo "# package domain method repository dir branch" >>upstream-gnome_gtp.tlst + +SPACES=' ' + +# listing of all GNOME GTP projects +curl https://l10n.gnome.org/POT/ | sed -n 's:^.*href="\([^"]*\)/".*$:\1:p' | sed '/^$/d' | + ( + while read ; do + BRANCH=${REPLY##*.} + REPLY=${REPLY%.*} + ( + grep -i ^$REPLY'\( \|\[0-9]\|-[0-9]\|-lang\)' create-tlst-temp-all-po-projects.lst || : + # For network-manager*, try to match with NetworkManager + if test "${REPLY#network-manager}" != "$REPLY" ; then + grep -i ^${REPLY/network-manager/NetworkManager}'\( \|\[0-9]\|-[0-9]\|-lang\)' create-tlst-temp-all-po-projects.lst + fi + + ) | + while read PACKAGE DOMAIN ; do + if test "${PACKAGE%-lang}/$DOMAIN" = "NetworkManager/nm-applet" ; then + continue + fi + echo $REPLY ${PACKAGE%-lang} $DOMAIN $BRANCH + done + done + # Packages known to have special name in GTP: + for LBRANCH in $KNOWN_BRANCHES master ; do + echo gconf gconf2 GConf2 $LBRANCH + done + echo glib glib2 glib20 glib-2-62 + echo glib glib2 glib20 glib-2-64 + echo glib glib2 glib20 master + echo gtk+ gtk2 gtk20 gtk-2-24 + echo gtk+ gtk2 gtk20 master + echo gtk+ gtk2 gtk20-properties gtk-2-24 + echo gtk+ gtk2 gtk20-properties master + echo gtk+ gtk3 gtk30 gtk-3-24 + echo gtk+ gtk3 gtk30 master + echo gtk+ gtk3 gtk30-properties gtk-3-24 + echo gtk+ gtk3 gtk30-properties master + echo gnome-phone-manager phonemgr gnome-phone-manager gnome-3-34 + echo gnome-phone-manager phonemgr gnome-phone-manager gnome-3-36 + echo gnome-phone-manager phonemgr gnome-phone-manager master + echo network-manager-applet NetworkManager-gnome nm-applet master + echo udisks udisks2 udisks2 master +# For other versions than sles10: +# echo network-manager-applet NetworkManager nm-applet + ) | + while read PROJECT PACKAGE DOMAIN BRANCH ; do + if test -z "$PACKAGE" ; then + continue + fi + # Test, whether package name is also the source name: + if ! grep -q "^$PACKAGE\$" create-tlst-temp-osc-projects.lst ; then + continue + fi + + # Projects known to use special directories: + case $DOMAIN in + gimp20-libgimp ) + PO_DIR=po-libgimp + ;; + gimp20-script-fu ) + PO_DIR=po-script-fu + ;; + gimp20-python ) + PO_DIR=po-python + ;; + gimp20-std-plug-ins ) + PO_DIR=po-plug-ins + ;; + gimp20-tags ) + PO_DIR=po-tags + ;; + gimp20-tips ) + PO_DIR=po-tips + ;; + gtk20-properties ) + PO_DIR=po-properties + ;; + gnumeric-functions ) + PO_DIR=po-functions + ;; + # FIXME: Only some teams use GTP for gstreamer. Run 'find -name "*-fixes.po"' on processed downstream to find possible regressions. + gst-plugins-base-1.0 ) + PROJECT=gst-plugins-base + ;; + gst-plugins-good-1.0 ) + PROJECT=gst-plugins-good + ;; + gst-plugins-bad-1.0 ) + PROJECT=gst-plugins-bad + ;; + gst-plugins-ugly-1.0 ) + PROJECT=gst-plugins-ugly + ;; + libgweather-locations ) + PO_DIR=po-locations + ;; + * ) + PO_DIR=po + ;; + esac + USE_IT=false + eval "case \"\$BRANCH\" in + $KNOWN_BRANCHES$APP_BRANCHES|master) + USE_IT=true + ;; + esac" + if $USE_IT ; then + BRANCH=${BRANCH/master/zzzz_master} + echo "$PACKAGE${SPACES:0:28-${#PACKAGE}}$DOMAIN${SPACES:0:47-${#DOMAIN}}gtp l10n.gnome.org/POT $PROJECT/$PO_DIR${SPACES:0:26-${#PROJECT}-${#PO_DIR}}$BRANCH" + fi + +# Disabled for now. Final merge will happen in spec file. +# # We want to include LCN only for projects, which need merge with GNOME GTP. +# if test -d translation-update-lcn/$DOMAIN ; then +# echo "$PACKAGE${SPACES:0:28-${#PACKAGE}}$DOMAIN${SPACES:0:27-${#DOMAIN}}zzzz_lcn" +# fi + + done | +tee upstream-gnome_gtp_raw.lst | +LC_COLLATE=C LC_ALL= sort | +sed ' +s/ *zzzz_master// +s/zzzz_lcn/lcn/ +' >>upstream-gnome_gtp.tlst + +# Remove temporary progress file: +rm upstream-gnome_gtp_raw.lst +rm create-tlst-temp-* diff --git a/create-tlst.conf b/create-tlst.conf new file mode 100644 index 0000000..b53c300 --- /dev/null +++ b/create-tlst.conf @@ -0,0 +1,11 @@ +# create-tlst.conf: Configuration for creating of translation-update-upstream.lst. +# +# Binary repository file system path you want to scan. It may be a local +# copy of a complete openSUSE repository or a remote repository mounted +# to a local file system. Note that DVD contents may be insufficient. + +BINARY_REPO=/mnt + +# Binary arch for. Directories suse/$BINARY_ARCH and suse/noarch will be +# searched. +BINARY_ARCH=x86_64 diff --git a/freedesktop_org.tlst b/freedesktop_org.tlst new file mode 100644 index 0000000..d66a80d --- /dev/null +++ b/freedesktop_org.tlst @@ -0,0 +1,6 @@ +# package domain method repository dir branch +gstreamer gstreamer-1.0 cgit git://anongit.freedesktop.org/gstreamer/gstreamer gstreamer/po +gstreamer-plugins-base gst-plugins-base-1.0 cgit git://anongit.freedesktop.org/gstreamer/gst-plugins-base gst-plugins-base/po +gstreamer-plugins-good gst-plugins-good-1.0 cgit git://anongit.freedesktop.org/gstreamer/gst-plugins-good gst-plugins-good/po +pulseaudio pulseaudio cgit git://anongit.freedesktop.org/pulseaudio/pulseaudio pulseaudio/po +shared-mime-info shared-mime-info cgit git://anongit.freedesktop.org/xdg/shared-mime-info po diff --git a/github.tlst b/github.tlst new file mode 100644 index 0000000..c66a408 --- /dev/null +++ b/github.tlst @@ -0,0 +1,6 @@ +# Note: Single file download using GitHub web is not yet implemented. Use full git snapshot instead. +# package domain method repository dir branch +ibus ibus10 git https://github.com/ibus/ibus.git ibus/po +eiciel eiciel git https://github.com/rofirrim/eiciel.git eiciel/po +libgnomesu libgnomesu-1.0 git https://github.com/openSUSE/libgnomesu.git libgnomesu/po +#UNSUPPORTED-POT: virt-manager virt-manager git https://github.com/virt-manager/virt-manager.git virt-manager/po diff --git a/lcn-sle.tlst b/lcn-sle.tlst new file mode 100644 index 0000000..b91cc87 --- /dev/null +++ b/lcn-sle.tlst @@ -0,0 +1,5 @@ +# package domain method repository dir branch option +#NOT-IN-SLE: NetworkManager-vpnc NetworkManager-vpnc lcn - NetworkManager-vpnc/po SLE12-SP4 +#NOT-IN-SLE: krb5-ticket-watcher krb5-ticket-watcher lcn - krb5-ticket-watcher/po SLE12-SP4 +libgnomesu libgnomesu-1.0 lcn - libgnomesu/po SLE12-SP4 +#LOST-I18N-SUPPORT: linuxrc linuxrc lcn - linuxrc/po SLE12-SP4 diff --git a/misc.tlst b/misc.tlst new file mode 100644 index 0000000..2b2c355 --- /dev/null +++ b/misc.tlst @@ -0,0 +1,12 @@ +# package domain method repository dir branch +# Already latest version: +#pidgin pidgin tbz http://downloads.sourceforge.net/pidgin/pidgin-2.13.0.tar.bz2 pidgin-2.13.0/po +pam Linux-PAM git https://github.com/linux-pam/linux-pam.git linux-pam/po +#BROKEN: firewalld firewalld git https://github.com/firewalld/firewalld.git firewalld/po +#DUP: virt-manager virt-manager git https://github.com/virt-manager/virt-manager.git virt-manager/po +#DUP: eiciel eiciel git https://github.com/rofirrim/eiciel.git eiciel/po +# package domain method repository dir branch +pam Linux-PAM cvs pam.cvs.sourceforge.net:/cvsroot/pam Linux-PAM/po +# Already latest version, and will probably never update: +#gtkspell gtkspell tgz http://downloads.sourceforge.net/gtkspell/gtkspell-2.0.16.tar.gz gtkspell-2.0.16/po +gtkspell3 gtkspell3 txz http://downloads.sourceforge.net/gtkspell/gtkspell3-3.0.10.tar.xz gtkspell3-3.0.10/po diff --git a/msgheadermerge b/msgheadermerge new file mode 100644 index 0000000..4bff38c --- /dev/null +++ b/msgheadermerge @@ -0,0 +1,59 @@ +#!/bin/bash + +# msgheadermerge expected_older.po expected_newer.po dest-header.po [--mergemode|--newdate|] + +# This tool merges headers of two .po files and never loses extra info (e. g. plurals). + +rm -rf {${1%.po},${2%.po}}-msgheadermerge-temp.{merge-dir,order} +trap "rm -rf {${1%.po},${2%.po}}-msgheadermerge-temp.{merge-dir,order} ${2%.po}-msgheadermerge-tempheader{,1}.po" 0 + +RC=0 + +# Broken pipe is an expected behavior. Redirect stderr to /dev/null. +msggrep --force-po $1 | msgexec $0-parse ${1%.po}-msgheadermerge-temp 2>/dev/null +msggrep --force-po $2 | msgexec $0-parse ${2%.po}-msgheadermerge-temp 2>/dev/null + +# If --swap-plural-forms was used, use plural definition from the other header. +if test "$6" = --old-plural-forms ; then + if test -f ${1%.po}-msgheadermerge-temp.merge-dir/Plural-Forms ; then + if test -f ${2%.po}-msgheadermerge-temp.merge-dir/Plural-Forms ; then + rm ${2%.po}-msgheadermerge-temp.merge-dir/POT-Creation-Date + fi + fi +fi + +# Keep original POT date with --mergemode and fail for outdated PO: +if test "$4" = --mergemode ; then + rm ${2%.po}-msgheadermerge-temp.merge-dir/POT-Creation-Date + if test ${2%.po}-msgheadermerge-temp.merge-dir/PO-Revision-Date -ot ${1%.po}-msgheadermerge-temp.merge-dir/PO-Revision-Date ; then + if test "$5" = --continue ; then + RC=1 + else + exit 1 + fi + fi +else + if test "$4" = --newdate ; then + rm ${1%.po}-msgheadermerge-temp.merge-dir/PO-Revision-Date + rm ${1%.po}-msgheadermerge-temp.merge-dir/POT-Creation-Date + else + if test ${2%.po}-msgheadermerge-temp.merge-dir/POT-Creation-Date -ot ${1%.po}-msgheadermerge-temp.merge-dir/POT-Creation-Date ; then + rm ${2%.po}-msgheadermerge-temp.merge-dir/POT-Creation-Date + fi + if test ${2%.po}-msgheadermerge-temp.merge-dir/PO-Revision-Date -ot ${1%.po}-msgheadermerge-temp.merge-dir/PO-Revision-Date ; then + rm ${2%.po}-msgheadermerge-temp.merge-dir/PO-Revision-Date + fi + fi +fi + +# Old project version is the correct one: +rm -f ${2%.po}-msgheadermerge-temp.merge-dir/Project-Id-Version + +mv ${2%.po}-msgheadermerge-temp.merge-dir/* ${1%.po}-msgheadermerge-temp.merge-dir/ +cat ${1%.po}-msgheadermerge-temp.order >>${2%.po}-msgheadermerge-temp.order + +msgmerge --quiet --force-po $2 $0-empty.pot -o ${2%.po}-msgheadermerge-tempheader.po +msgattrib --no-obsolete --force-po ${2%.po}-msgheadermerge-tempheader.po -o ${2%.po}-msgheadermerge-tempheader1.po +msgfilter --force-po -i ${2%.po}-msgheadermerge-tempheader1.po -o $3 $0-compose ${1%.po}-msgheadermerge-temp.merge-dir ${2%.po}-msgheadermerge-temp.order + +exit $RC diff --git a/msgheadermerge-compose b/msgheadermerge-compose new file mode 100644 index 0000000..2b5d7ee --- /dev/null +++ b/msgheadermerge-compose @@ -0,0 +1,27 @@ +#!/bin/bash +# helper script for msgheadermerge +PO_HEADER_DIR=$1 +PO_HEADER_ORDER=$2 +if test -d $1 ; then + cat >/dev/null + cat $PO_HEADER_ORDER | + while read ; do + if test "${REPLY}" != "${REPLY/ }" ; then + echo "ERROR: Malformed header line $PO_HEADER_DIR/$REPLY. Ignoring." >&2 + else + if test -f $PO_HEADER_DIR/$REPLY ; then + TAG=${REPLY//__SLASH__//} # safety check counterpart + echo -n "$TAG: " + cat "$PO_HEADER_DIR/$REPLY" + fi + fi + rm -f "$PO_HEADER_DIR/$REPLY" + done + if ! rmdir $PO_HEADER_DIR ; then + echo "WARNING: These items of $PO_HEADER_DIR were not processed:" >&2 + ls -1 $PO_HEADER_DIR >&2 + echo "This can happen if the file lacks one of mandatory header items." >&2 + fi +else + exit 1 +fi diff --git a/msgheadermerge-empty.pot b/msgheadermerge-empty.pot new file mode 100644 index 0000000..c671ff3 --- /dev/null +++ b/msgheadermerge-empty.pot @@ -0,0 +1,17 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2009-10-13 13:43+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" diff --git a/msgheadermerge-parse b/msgheadermerge-parse new file mode 100644 index 0000000..cc23d47 --- /dev/null +++ b/msgheadermerge-parse @@ -0,0 +1,21 @@ +#!/bin/bash +# helper script for msgheadermerge +PO_HEADER_DIR=$1 +if mkdir 2>/dev/null $PO_HEADER_DIR.merge-dir ; then + while read ; do + TAG=${REPLY%%:*} + if test "$TAG" = "$REPLY" -o -z "$TAG" ; then + echo "ERROR: Malformed header line $PO_HEADER_DIR/$TAG. Ignoring." >&2 + else + TAG=${TAG//\//__SLASH__} # safety check + VALUE=${REPLY#*:} + VALUE=${VALUE# } + echo >"$PO_HEADER_DIR.merge-dir/$TAG" "$VALUE" + echo >>$PO_HEADER_DIR.order "$TAG" + fi + done + touch -d "$(<$PO_HEADER_DIR.merge-dir/POT-Creation-Date)" $PO_HEADER_DIR.merge-dir/POT-Creation-Date + touch -d "$(<$PO_HEADER_DIR.merge-dir/PO-Revision-Date)" $PO_HEADER_DIR.merge-dir/PO-Revision-Date +else + exit 1 +fi diff --git a/opensuse.tlst b/opensuse.tlst new file mode 100644 index 0000000..f6e1962 --- /dev/null +++ b/opensuse.tlst @@ -0,0 +1,6 @@ +# package domain method repository dir branch option +cracklib cracklib lcn - cracklib/po +gnome-packagekit gnome-packagekit lcn - gnome-packagekit/po +#LOST-I18N-SUPPORT: linuxrc linuxrc lcn - linuxrc/po +pam-config pam-config lcn - pam-config/po +pam_krb5 pam_krb5 lcn - pam_krb5/po diff --git a/static.tlst b/static.tlst new file mode 100644 index 0000000..8a7e211 --- /dev/null +++ b/static.tlst @@ -0,0 +1,5 @@ +# package domain method repo dir branch option +# +# Updates from git.gnome.org, where upstream git does not exist any more +pan pan static - pan/po +libgnomecanvas libgnomecanvas-2.0 static - libgnomecanvas/po diff --git a/translation-update-mandatory-20200601.tar.bz2 b/translation-update-mandatory-20200601.tar.bz2 new file mode 100644 index 0000000..7cec957 --- /dev/null +++ b/translation-update-mandatory-20200601.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d196b4fbc03f6fb31f64b5f5c1236ac99f3291f81688ab94386a82ce02e34f5 +size 256 diff --git a/translation-update-static.tar.bz2 b/translation-update-static.tar.bz2 new file mode 100644 index 0000000..1852de8 --- /dev/null +++ b/translation-update-static.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:edc617fb9a896369da0993b8af1df00ef097f2ae1c4b99c224557aa35d1c5c0b +size 293428 diff --git a/translation-update-upstream-20200601.tar.bz2 b/translation-update-upstream-20200601.tar.bz2 new file mode 100644 index 0000000..0f3774a --- /dev/null +++ b/translation-update-upstream-20200601.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ec7e324f1097ea4c21b318704e7f17beafac7848271b6daf797ea5cf7f646d8 +size 6359 diff --git a/translation-update-upstream-AUTHORS b/translation-update-upstream-AUTHORS new file mode 100644 index 0000000..e8fcf84 --- /dev/null +++ b/translation-update-upstream-AUTHORS @@ -0,0 +1 @@ +Stanislav Brabec diff --git a/translation-update-upstream-COPYING b/translation-update-upstream-COPYING new file mode 100644 index 0000000..88de850 --- /dev/null +++ b/translation-update-upstream-COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/translation-update-upstream-HOWTO b/translation-update-upstream-HOWTO new file mode 100644 index 0000000..8863dc9 --- /dev/null +++ b/translation-update-upstream-HOWTO @@ -0,0 +1,109 @@ +If you want to add translation-update-upstream support to a package +=================================================================== + +1) Add to preamble: + + BuildRequires: translation-update-upstream + +2) Immediately after %setup (and before possible +gnome-patch-translation-prepare) add command: + + translation-update-upstream + +3) Add configuration for this package to translation-update-upstream and +update translations. + + +If you want to update or add single translation +=============================================== + +Add a line to a proper configuration file (or create a new one - +anything with nale *.tlst is sourced automatically). + +See upstream-collect.sh for implemented methods. + +If your project uses a non-standard directory in the upstream directory +hierrarchy, you may need a code into a *.hook file. + +Then run following command in unpacked sources directory: + +./upstream-collect.sh {package_name} + +where {package_name} is the name of the package you need to update. + +Then you have to edit spec file to include new tarball, rebuild it and +rebuild the package using the new version of translation-update-upstream. + +Note that the shapshot date of the package will not be updated, but +instead of it, a sub-version will be used. + +You need osc, network connection, commands for all used download methods +(cvs, svn, git, wget) all commands needed to run %prep of packages +(e. g. patch or gnome-patch-translation) and network connection. + +You need a lot of time. A complete run on ./upstream-collect.sh may +require 12 hours and several gigabytes of data downloaded. + + +If you want to update translations (short process: update translations only) +============================================================================ + +Run following command in unpacked sources directory: + +bash ./upstream-collect.sh + +It creates a tarball with translations updated by upstream using all +existing *.tlst filůes (configuration of packages) and +upstream-collect.conf (configuration of tool itself). + +Then you have to edit spec file to include new tarball, rebuild it and +rebuild all packages using new version of translation-update-upstream. + +You need osc, network connection, commands for all used download methods +(cvs, svn, git, wget) all commands needed to run %prep of packages +(e. g. patch or gnome-patch-translation) and network connection. + +Note that ./upstream-collect.sh has a smart error recovery. If any of +actions fail, you can restart ./upstream-collect.sh without loss of +already collected data. Just an actual package is restarted. + + +If you want to update translations (long process: update configuration) +============================================================================ + +Just now the file upstream-collect.lst is automatically generated by +lower mentioned tools. + +You need a complete binary RPM repository available on a filesystem and +refer to it in create-config.conf + +Then you can run following command in unpacked sources directory: + +# collect possible po domains from rpm packages +bash ./create-tlst-step1-list-all-po-projects.sh +# scan upstream branches +bash ./create-tlst-step2-create-gnome_gtp.sh + +Then continue as above. + + +To extract relevant strings from translation-update-upstream to translation-update +================================================================================== + +If you need to extract relevant strings from compile time merged +translation-update-upstream to post installation update +translation-update, you can use +translation-update-upstream-to-translation-update.sh. This tool requires +some outputs of the upstream-collect.sh run, especially po-full +directory that contains the best full translations available. + +You need this command: + +# extract strings from translation-update-upstream that will not be updated +./translation-update-upstream-to-translation-update.sh + +The command uses first item in OSC_REPOSITORIES array in +upstream-collect.conf as your target distro. Any package that is not +present there will be considered for post installation update. + +Add the generated tarball to translation-update package after the run. diff --git a/translation-update-upstream-README b/translation-update-upstream-README new file mode 100644 index 0000000..9a9b61b --- /dev/null +++ b/translation-update-upstream-README @@ -0,0 +1,5 @@ +This is a source of translation update files intended for use during +compilation of packages. After unpacking, before starting to patch and +build the package, simply call translation-update-upstream. + +See HOWTO for more. diff --git a/translation-update-upstream-embedded-README b/translation-update-upstream-embedded-README new file mode 100644 index 0000000..823d0a5 --- /dev/null +++ b/translation-update-upstream-embedded-README @@ -0,0 +1,17 @@ +translation-update-upstream-embedded.sh is a script that can be used +without translation-update-upstream package. + +How to use it: + +1. Create .tlst and .hook files and run ./upstream-collect.sh as you do +with translation-update-upstream. + +2. Create an archive that contains: + - directory translation-update-upstream with: + - translation-update-upstream-embedded.sh + - msgheadermerge* + - directory po that contains contents of the archive created in step 1. + +3. Instead of call of translation-update-upstream in the spec file use +translation-update-upstream/translation-update-upstream-embedded.sh. +Arguments and style of use are the same. diff --git a/translation-update-upstream-embedded.patch b/translation-update-upstream-embedded.patch new file mode 100644 index 0000000..15a224f --- /dev/null +++ b/translation-update-upstream-embedded.patch @@ -0,0 +1,19 @@ +--- translation-update-upstream-embedded.sh 2020-01-22 22:19:22.911348880 +0100 ++++ translation-update-upstream-embedded.sh 2020-01-22 22:39:26.134577525 +0100 +@@ -85,6 +85,7 @@ + USE_INTLTOOL=true + fi + fi ++BASE_DIR=$PWD + DIR=${1:-po} + + if test -z "$3" ; then +@@ -259,7 +260,7 @@ + echo "WARNING: Missing $DOMAIN in translation-update-upstream configuration! No updates available." + fi + else +- echo "ERROR: Package translation-update-upstream is not installed. Please update your BuildRequires!" ++ echo "ERROR: Incorrect use of translation-update-upstream-embedded!" + exit 1 + fi + fi diff --git a/translation-update-upstream-to-translation-update.sh b/translation-update-upstream-to-translation-update.sh new file mode 100644 index 0000000..9e11117 --- /dev/null +++ b/translation-update-upstream-to-translation-update.sh @@ -0,0 +1,276 @@ +#!/bin/bash + +# This program searches for packages that are not updated and extracts +# their translation updates to a separate tarball that can be used by +# translation-update package. + +WORK_DIR=$PWD + +set -o errexit +shopt -s nullglob + +if ! test -f upstream-collect.domain-map ; then + echo "Missing generated files. Please make a full run of ./upstream-collect.sh first." + exit 1 +fi + +if ! test -d gnome-patch-translation ; then + echo "Please provide directory gnome-patch-translation with contents of" + echo "/usr/share/gnome-patch-translation from gnome-patch-translation RPM" + echo "on the target system." + exit 1 +fi + +source ${0%translation-update-upstream-to-translation-update.sh}upstream-collect.conf + +mkdir\ + TRANSLATION_UPDATE TRANSLATION_UPDATE/translation-update TRANSLATION_UPDATE/TUU\ + TRANSLATION_UPDATE/NOT_UPDATED \ + TRANSLATION_UPDATE/UPDATED \ + TRANSLATION_UPDATE/complete TRANSLATION_UPDATE/rebuilt \ + TRANSLATION_UPDATE/complete/translation-update TRANSLATION_UPDATE/rebuilt/translation-update + +# more tarballs are available => use the latest one +# FIXME: Fix 20090213.10 < 20090213.9 +# (but it should not happen for people who update and submit) +for ARCHIVE in translation-update-upstream-*.tar.bz2 ; do + : +done +tar -jtf $ARCHIVE >${0%.sh}-updates.lst +SNAPSHOT=${ARCHIVE%.tar.bz2} +SNAPSHOT=${SNAPSHOT#translation-update-upstream-} +for ARCHIVE in translation-update-mandatory-*.tar.bz2 ; do + : +done +MSNAPSHOT=${ARCHIVE%.tar.bz2} +MSNAPSHOT=${MSNAPSHOT#translation-update-mandatory-} +if [[ "$MSNAPSHOT" > "$SNAPSHOT" ]] ; then + SNAPSHOT=$MSNAPSHOT +fi + +# FIXME: It should list all gnome-patch-translation references, not only the first on the line. +# But there is a bug in the gnome-patch-translation: Only first reference contain domain. +# Hopefully, the output is complete even with it. +sed -n 's%^#: \([^/]*\).*$%\1%p' gnome-patch-translation/gnome-patch-translation.pot | sort -u >${0%.sh}-gpt.lst + +# Process translations to get complete sets of strings. +cd po-full +for DOMAIN in * ; do + if grep -q "^$DOMAIN\$" ../${0%.sh}-gpt.lst ; then + SUPPORTS_GPT=true + else + SUPPORTS_GPT=false + fi + for PO in $DOMAIN/*.po ; do + LNG=${PO##*/} + LNG=${LNG%.po} + mkdir -p "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG" + + if test -f "../po-mandatory-full/$PO" ; then + if $SUPPORTS_GPT && test -f "../gnome-patch-translation/$LNG.po" ; then + # mandatory strings take precedence over gnome-patch-translation, but gnome-patch-translation takes precedence over upstream. + msgcat --use-first "../po-mandatory-full/$PO" "../gnome-patch-translation/$LNG.po" "$PO" -o "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG/$LNG.po.p1" + # There are mandatory strings. We must update. + mkdir -p "../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN" + echo "po-mandatory-full/$PO" >"../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN/$LNG" + else + msgcat --use-first "../po-mandatory-full/$PO" "$PO" -o "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG/$LNG.po" + # There are mandatory strings. We must update. + mkdir -p "../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN" + touch "../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN/$LNG" + fi + else + if $SUPPORTS_GPT && test -f "../gnome-patch-translation/$LNG.po" ; then + msgcat --use-first "../gnome-patch-translation/$LNG.po" "$PO" -o "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG/$LNG.po.p1" + # We don't know, whether strings from gnome-patch-translation were updated. There is no check yet. We must update. + mkdir -p "../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN" + echo "po-full/$PO" >"../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN/$LNG" + else + ln "$PO" "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG/$LNG.po" + fi + fi + done +done + +cd ../po-mandatory-full +for DOMAIN in * ; do + if grep -q "^$DOMAIN\$" ../${0%.sh}-gpt.lst ; then + SUPPORTS_GPT=true + else + SUPPORTS_GPT=false + fi + for PO in $DOMAIN/*.po ; do + LNG=${PO##*/} + LNG=${LNG%.po} + # There are mandatory strings. We must update. + mkdir -p "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG" + # Handle only po files not processed above. + if ! test -f "../po-full/$PO" ; then + mkdir -p "../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN" + if $SUPPORTS_GPT -a -f "../gnome-patch-translation/$LNG.po" ; then + # mandatory strings take precedence over gnome-patch-translation, but gnome-patch-translation takes precedence over upstream. + msgcat --use-first "$PO" "../gnome-patch-translation/$LNG.po" -o "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG/$LNG.po.p1" + echo "po-mandatory-full/$PO" >"../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN/$LNG" + else + ln "$PO" "../TRANSLATION_UPDATE/complete/translation-update/$DOMAIN/$LNG/$LNG.po" + touch "../TRANSLATION_UPDATE/complete/stamp-force/$DOMAIN/$LNG" + fi + fi + done +done + +# Finish processing of po files that included strings from gnome-patch-translation. +cd ../TRANSLATION_UPDATE/complete/translation-update +for POP1 in */*/*.po.p1 ; do + PO=${POP1%.p1} + DOMAIN=${PO%%/*} + LNG=${PO%/*} + LNG=${LNG#*/} + + # Include only gnome-patch-translation strings from particular domain. + msgmerge --no-fuzzy-matching "$POP1" ../../../pot/$DOMAIN.pot -o "$PO.p2" + msgattrib --no-obsolete "$PO.p2" -o "$PO.p3" + + # Put header from the most important source stored into stamp-force. + # Extract header. Broken pipe is an expected behavior. Redirect stderr to /dev/null. + msgmerge --quiet --force-po ../../../$(<"../stamp-force/$DOMAIN/$LNG") ../../../msgheadermerge-empty.pot -o "$PO.p4" + msgattrib --no-obsolete --force-po "$PO.p4" -o "$PO.p5" + msgcat --use-first --force-po "$PO.p5" "$PO.p3" -o "$PO" + + rm "$PO.p"* +done + +cd ../.. + +# Now create a copy of all files to TUU (they will be moved later to particular directories). +cp -al complete/translation-update/* TUU/ + +cd .. + +osc ${OSC_APIURL:+--apiurl=$OSC_APIURL} ls "${OSC_REPOSITORIES[OSC_MAIN_INDEX]}" >${0%.sh}-rebuilt.lst +if test -n "$OSC_PROPOSED_INDEX" ; then + osc ${OSC_APIURL:+--apiurl=$OSC_APIURL} ls "${OSC_REPOSITORIES[OSC_PROPOSED_INDEX]}" >${0%.sh}-outdated.lst +else + echo -n '' >${0%.sh}-outdated.lst +fi + +for TLST in *.tlst ; do + exec <$WORK_DIR/$TLST + + while read PACKAGE DOMAIN METHOD REPO DIR BRANCH MANDATORY ; do + + # Continue for empty lines and comments + if test "${PACKAGE###}" != "$PACKAGE" ; then + continue + fi + if test -z "$PACKAGE" ; then + continue + fi + + echo "$(tput setf 3)Processing: package=$PACKAGE domain=$DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:-(default)} mandatory=$MANDATORY$(tput init)" + PACKAGE_REBUILT_UP_TO_DATE=false + if grep -q "^$PACKAGE\$" ${0%.sh}-rebuilt.lst ; then + if grep -q "^$PACKAGE\$" ${0%.sh}-outdated.lst ; then + echo " is rebuilt in the distro, but has pending translation related update, adding" + else + PACKAGE_REBUILT_UP_TO_DATE=true + echo " is rebuilt in the distro, not adding" + fi + else + echo " not rebuilt in the distro, adding" + fi + + if $PACKAGE_REBUILT_UP_TO_DATE ; then + cat ${0%translation-update-upstream-to-translation-update.sh}upstream-collect.domain-map | + while read PACKAGE_ REAL_DOMAIN STATUS ; do + if test "$PACKAGE" = "$PACKAGE_" ; then + case $STATUS in + OK*) + echo " domain $REAL_DOMAIN is correctly updated, OK" + if test -d TRANSLATION_UPDATE/TUU/$REAL_DOMAIN ; then + mv TRANSLATION_UPDATE/TUU/$REAL_DOMAIN TRANSLATION_UPDATE/UPDATED/ + fi + ;; + *) + echo " domain $REAL_DOMAIN is not correctly updated, needs to be added" + if test -d TRANSLATION_UPDATE/TUU/$REAL_DOMAIN ; then + mv TRANSLATION_UPDATE/TUU/$REAL_DOMAIN TRANSLATION_UPDATE/NOT_UPDATED/ + fi + ;; + esac + fi + done + else + cat ${0%translation-update-upstream-to-translation-update.sh}upstream-collect.domain-map | + while read PACKAGE_ REAL_DOMAIN STATUS ; do + if test "$PACKAGE" = "$PACKAGE_" ; then + if test -d TRANSLATION_UPDATE/TUU/$REAL_DOMAIN ; then + mv TRANSLATION_UPDATE/TUU/$REAL_DOMAIN TRANSLATION_UPDATE/NOT_UPDATED/ + fi + fi + done + fi + echo + done +done + +# If files remain in TUU, there is something wrong. Move them to NOT_UPDATED and hope that domain is correct. +# It can happen when domain mapping process failed. +cd TRANSLATION_UPDATE/TUU +for DIR in * ; do + echo "$(tput setf 4)Something went wrong, domain=${DIR#*/} was not listed and processed$(tput init)" + echo " assuming that it was not updated" + mv $DIR ../NOT_UPDATED/$DIR +done + +cd ../NOT_UPDATED +for PO in */*/*.po ; do + DOMAIN=${PO%%/*} + LNG=${PO%/*} + LNG=${LNG#*/} + + # Standard update: Pick only files with changes. + if grep -q "^po/$DOMAIN/$LNG.po\$" ../../${0%.sh}-updates.lst ; then + mkdir -p "../translation-update/$DOMAIN/$LNG" + ln "../complete/translation-update/$PO" "../translation-update/$PO" + fi + # Mandatory update: Pick all files. + if test -f "../complete/stamp-force/$DOMAIN/$LNG" ; then + mkdir -p "../translation-update/$DOMAIN/$LNG" + ln -f "../complete/translation-update/$PO" "../translation-update/$PO" + fi +done +cd ../UPDATED +for PO in */*/*.po ; do + DOMAIN=${PO%%/*} + LNG=${PO%/*} + LNG=${LNG#*/} + + # Standard update: Pick only files with changes. + if grep -q "^po/$DOMAIN/$LNG.po\$" ../../${0%.sh}-updates.lst ; then + mkdir -p "../rebuilt/translation-update/$DOMAIN/$LNG" + ln "../complete/translation-update/$PO" "../rebuilt/translation-update/$PO" + fi + # Mandatory update: Pick all files. + if test -f "../complete/stamp-force/$DOMAIN/$LNG" ; then + mkdir -p "../rebuilt/translation-update/$DOMAIN/$LNG" + ln -f "../complete/translation-update/$PO" "../rebuilt/translation-update/$PO" + fi +done + +cd .. +tar -jcf ../translation-update-from-translation-update-upstream-$SNAPSHOT.tar.bz2 translation-update +echo "Generated translation-update-from-translation-update-upstream-$SNAPSHOT.tar.bz2 +Please add it to the package translation-update" +cd rebuilt +tar -jcf ../../translation-update-from-translation-update-upstream-rebuilt-$SNAPSHOT.tar.bz2 translation-update +echo "Generated translation-update-from-translation-update-upstream-rebuilt-$SNAPSHOT.tar.bz2 +It contains translations that that should be provided in build time by translation-update-upstream, +but if translation-update-upstream was not updated to the latest version, then you may want to include +these translations to translation-update as well." +cd ../complete +tar -jcf ../../translation-update-from-translation-update-upstream-complete-$SNAPSHOT.tar.bz2 translation-update +echo "Generated translation-update-from-translation-update-upstream-complete-$SNAPSHOT.tar.bz2 +This file includes all avaliable translations." +cd ../.. +rm -r TRANSLATION_UPDATE diff --git a/translation-update-upstream.changes b/translation-update-upstream.changes new file mode 100644 index 0000000..293de62 --- /dev/null +++ b/translation-update-upstream.changes @@ -0,0 +1,348 @@ +------------------------------------------------------------------- +Tue Mar 10 14:37:34 CET 2020 - sbrabec@suse.com + +- Reset outdated translations and turn translate-update-upstream + into dummy (bsc#1172337, boo#1172367). +- Drop SLE / Leap discrimination code. +- translation-update-upstream.in: + * Disable msgmerge. Never cause translation regression, even at + cost of superfluous strings (bsc#1160114). + * Implement new heuristic: use xgettext. Make it the default + (bsc#1160114). + * translation-update-upstream-embedded.patch: Update. +- upstream-collect.sh supplementary script: Port + translation-update-upstream.in changes. + +------------------------------------------------------------------- +Tue Nov 5 18:49:52 CET 2019 - sbrabec@suse.com + +- upstream-collect.sh supplementary script: Port meson support to + the fallback pot extractor (bsc#1095368#c9). +- upstream-collect.sh, upstream-collect.conf supplementary script: + Evaluate %is_opensuse for target system instead of host + (bsc#1095368#c8). + +------------------------------------------------------------------- +Wed Oct 2 02:48:55 CEST 2019 - sbrabec@suse.com + +- Update to version 20191002 (bsc#1095361, bsc#1095364, + bsc#1095368, bsc#1095371, bsc#1095377, bsc#1095379): + * Update configuration to be SLE15 SP1 Update compatible. + * Add new upstream branches to tlst files. + * Update create-tlst-step2-create-gnome_gtp.sh to cover new + upstream branches. + * Update all strings from upstream and LCN. +- upstream-collect.sh supplementary script: Make paths compatible + with Tumbleweed. + +------------------------------------------------------------------- +Fri Mar 29 00:41:19 CET 2019 - sbrabec@suse.com + +- Update to version 20190328: + * Translation updates. + +------------------------------------------------------------------- +Mon Dec 10 22:58:25 CET 2018 - sbrabec@suse.com + +- translation-update-upstream.in: Restore time stamp to prevent + triggering of aclocal (boo#1118603). + * Refresh translation-update-upstream-embedded.patch. +- Add a check that prevents build of SLE version for openSUSE. + +------------------------------------------------------------------- +Wed Nov 28 23:31:49 CET 2018 - sbrabec@suse.com + +- Update to Factory specific version 20181128 that contains only + abandoned packages in static.tlst (bsc#1100398). + *.tlst: Port from SLE15 SP1: +- Comment upstream-collect.conf. +- upstream-collect.sh supplementary script: + * Make paths compatible with Tumbleweed. + * Add support for .tar.xz files. +- Improved create-tlst scripts to work with standard DVD medium + (create-tlst-step1-list-all-po-projects.sh, + create-tlst-step2-create-gnome_gtp.sh, create-tlst.conf), + add upstream-gnome_gtp-not-on-media.tlst. +- Move libgnomecanvas dropped in upstream to + translation-update-static.tar.bz2. +- Add github.tlst. + +------------------------------------------------------------------- +Wed May 2 19:50:06 CEST 2018 - sbrabec@suse.com + +- Improve meson/ninja domain detection (boo#1091307). + +------------------------------------------------------------------- +Fri Apr 27 15:06:30 CEST 2018 - sbrabec@suse.com + +- Implement support for meson/ninja build system (fixes missing + translations in nautilus, bsc#1087076, upstream-collect.sh, + translation-update-upstream.in, + translation-update-upstream-embedded.patch). +- Update to version 20180426: + * Update for translation-update-upstream fixes (bsc#1087076). + * Correct files from meson/ninja based builds. + +------------------------------------------------------------------- +Tue Apr 10 18:31:45 CEST 2018 - sbrabec@suse.com + +- Update to version 20180410: + * Reflect latest package updates (e. g. gtk3, bsc#1087126). + * Update for translation-update-upstream fixes (bsc#1086036#c13). + * Package is now SLE 15 specific. Update *.tlst to exclude + openSUSE-only packages. +- Configure upstream-collect.conf to SLE 15. + +------------------------------------------------------------------- +Mon Apr 9 18:04:00 CEST 2018 - sbrabec@suse.com + +- Update to version 20180313.2: + * Add upstream eiciel to misc.tlst, remove merged downstream from + lcn-sle.tlst. + * Update eiciel (bsc#1087321). + +------------------------------------------------------------------- +Wed Mar 28 22:55:39 CEST 2018 - sbrabec@suse.com + +- Refresh gdm after dropping of gdm-nb-translations.patch + (bump version to 20180313.1, boo#1087338). + +------------------------------------------------------------------- +Tue Mar 13 18:54:11 CET 2018 - sbrabec@suse.com + +- Updated strings from the latest upstream translations and for the + latest Factory snapshot (version 20180313). +- create-tlst-step2-create-gnome_gtp.sh: + * Use latest branches. + * Add code matching NetworkManager plugins (bsc#989505). +- create-tlst.conf: Switch to x86_64. +- misc.tlst: + * Add firewalld (bsc#1082309, bsc#1081815, bsc#1081623, + bsc#1081625, bsc#1081823). + * Add virt-manager (bsc#1081541). +- lcn-sle.tlst: Remove dropped packages. +- upstream-collect.sh: Remove more macros in rpmprep. + +------------------------------------------------------------------- +Fri Aug 21 16:23:02 CEST 2015 - sbrabec@suse.com + +- upstream-collect.sh supplementary script: Prevent plural form + clash in case of additions only (bsc#894913). + +------------------------------------------------------------------- +Thu Sep 4 17:32:24 CEST 2014 - sbrabec@suse.cz + +- upstream-collect.sh supplementary script: Fixed inverted po file + age check (bnc#889513). +- create-tlst-step2-create-gnome_gtp.sh: Add support for udisks. +- Reset translation tarballs: use only packaged translations. + +------------------------------------------------------------------- +Tue May 6 23:37:37 CEST 2014 - sbrabec@suse.cz + +- New supplementary script: check-translation-completeness.sh + that creates statistics of translation completeness. +- Merge latest upstream-collect.sh fixes from SLE11 SP3: + * Re-add all strings lost after removal from upstream + (bnc#807817#c15). + * Do incremental update by default to prevent loss of strings + removed from upstream (bnc#807817#c15). + * Fix errors in debug mode. +- Merge latest translation-update-upstream-to-translation-update.sh + fixes from SLE11 SP3: + * rewrote to include strings from gnome-patch-translation + (bnc#807817, bnc#811265). + +------------------------------------------------------------------- +Fri Apr 25 09:58:27 UTC 2014 - schwab@linux-m68k.org + +- Only process PO header in msgheadermerge + +------------------------------------------------------------------- +Wed Apr 23 09:22:19 UTC 2014 - dmueller@suse.com + +- speed up msgheadermerge by factor 20-25 + +------------------------------------------------------------------- +Wed Mar 13 20:29:06 CET 2013 - sbrabec@suse.cz + +- Supplementary scripts update: + * GTP: Update to the new GTP web engine. + +------------------------------------------------------------------- +Fri Mar 8 22:02:53 CET 2013 - sbrabec@suse.cz + +- Remove glib.glib-2-30.gu.po file that comes from GTP + (bnc#808436). + +------------------------------------------------------------------- +Thu Feb 14 20:30:28 CET 2013 - sbrabec@suse.cz + +- Improve supplementary script + translation-update-upstream-to-translation-update.sh to fit well + for SLE, openSUSE and SLE service packs. + +------------------------------------------------------------------- +Thu Feb 14 16:51:59 CET 2013 - sbrabec@suse.cz + +- Updated strings from the latest upstream translations and for the + latest 12.3 snapshot. + +------------------------------------------------------------------- +Thu Jan 24 20:29:07 CET 2013 - sbrabec@suse.cz + +- Updated strings from the latest upstream translations and for the + latest Factory snapshot. +- Supplementary scripts improvements: + * Validate all imported po files before merge. + * Try harder to make plural forms consistent. + * Collect full translations of all projects. + * Create a domain map. + * Added a script that makes possible to prepare translations for + post-install translation-update package. + * Support for pending translation fixes. + * "static" method for update from attached tarball + (needed if upstream disappeared) + +------------------------------------------------------------------- +Mon Aug 6 19:58:07 CEST 2012 - sbrabec@suse.cz + +- Updated strings from the latest upstream translations and for the + latest 12.2 snapshot. +- Reflect migration of LCN from Berlios to svn.opensuse.org. +- Supplementary scripts fix: + * Fixed name of archive. + * Integrate strings from SLE11 SP2. + +------------------------------------------------------------------- +Mon Feb 13 10:57:09 UTC 2012 - coolo@suse.com + +- patch license to follow spdx.org standard + +------------------------------------------------------------------- +Tue Oct 18 19:07:52 CEST 2011 - sbrabec@suse.cz + +- Supplementary scripts improvement: + * Fixed partial mandatory update. + +------------------------------------------------------------------- +Fri Oct 14 01:58:46 CEST 2011 - sbrabec@suse.cz + +- Updated strings from the latest upstream translations and for the + latest Factory. +- Supplementary scripts improvement: + * Keep pot file in place, so "true" can be used as a pot generator. + +------------------------------------------------------------------- +Wed Sep 7 14:44:21 CEST 2011 - sbrabec@suse.cz + +- Supplementary scripts improvements: + * Support for pot-only run (COLLECT_UPSTREAM=false). + * Implemented check for possible strings in patches. + * Support for import of strings from different gettext domain. + * Allow to skip time consuming update by setting SKIP_TUU=true. + +------------------------------------------------------------------- +Thu Jul 7 20:57:26 CEST 2011 - sbrabec@suse.cz + +- Don't process .reduced.po files from GTP (bnc#703739). + +------------------------------------------------------------------- +Fri Jun 24 19:03:18 CEST 2011 - sbrabec@suse.cz + +- Updated strings from the latest upstream translations and for the + latest Factory. +- COPYING file update. + +------------------------------------------------------------------- +Tue May 24 13:52:12 UTC 2011 - coolo@novell.com + +- fake %find_lang as if the translations are provided by the packages + +------------------------------------------------------------------- +Wed Feb 23 17:11:45 CET 2011 - sbrabec@suse.cz + +- Added translations for more packages (bnc#673924). +- Supplementary scripts improvements: + * Improved support for partial translations update. + * Added support for parallel processing of po files. + * Do not generate empty new translations. + * Use gettext-tools instead of sed hacks. + +------------------------------------------------------------------- +Mon Feb 14 15:12:54 CET 2011 - sbrabec@suse.cz + +- Updated strings from the latest upstream translations and for the + latest Factory. + +------------------------------------------------------------------- +Tue Dec 14 18:10:56 CET 2010 - sbrabec@suse.cz + +- Validate locales and remove invalid ones (bnc#658999). + +------------------------------------------------------------------- +Mon Jun 14 20:22:26 CEST 2010 - sbrabec@suse.cz + +- Fixes of build failures: + * Edit configure* only if po/LINGUAS does not exist. + * Support LINGUAS list in a single line. +- Added the latest upstream and LCN strings. + +------------------------------------------------------------------- +Fri Jun 4 12:47:12 CEST 2010 - sbrabec@suse.cz + +- Added the latest upstream and LCN strings. +- Ported fixes from SLE11-SP1: + * Added support for custom pot generator. + * Implemented suppport for LCN as a translation source. + * Implemented mandatory sources with absolute precedence. + * Symlinks to the new name: translation-update-tool. + * Updated translation sources. + +------------------------------------------------------------------- +Tue Feb 2 18:35:28 CET 2010 - sbrabec@suse.cz + +- Use dummy tarball before version freeze. +- Migration of servers from Novell Forge to Berlios. +- Supports newer version of cgit. +- Support for multiple osc sources. +- Support for extracting new and changed strings for review. +- Never overwrite strings by po file with older time stamp. + +------------------------------------------------------------------- +Tue Oct 27 16:21:20 CET 2009 - sbrabec@suse.cz + +- Added several more packages. +- Fixed errors if one package has updates on more servers. +- Do not interfere with gnome-patch-translation (bnc#517629#c17). +- Added translation-update-upstream-embedded script (src rpm only). + +------------------------------------------------------------------- +Fri Oct 9 17:01:19 CEST 2009 - sbrabec@suse.cz + +- Updated for the latest Factory and collected fresh translations. +- Fixed bugs in merge that caused lost strings (bnc#517629#c12). +- Implemented git, git web and GNOME Translation Project support. +- GNOME SVN is obsolete, migrate to GNOME Translation Project. +- Fixed for new RPM. +- Support for multiple domains in a single package. +- Generate non-volatile POT time stamps (bnc#489139). +- Ignore update if it is older than the package. + +------------------------------------------------------------------- +Thu Mar 26 14:34:21 CET 2009 - sbrabec@suse.cz + +- Reset mostly outdated translations until next freeze. + +------------------------------------------------------------------- +Wed Feb 11 15:32:59 CET 2009 - sbrabec@suse.cz + +- Modularization of package lists. +- Make possible update of a single translation. +- Added pidgin. + +------------------------------------------------------------------- +Fri Feb 6 16:32:55 CET 2009 - sbrabec@suse.cz + +- New SuSE package (FATE#301344). + diff --git a/translation-update-upstream.in b/translation-update-upstream.in new file mode 100644 index 0000000..693cb11 --- /dev/null +++ b/translation-update-upstream.in @@ -0,0 +1,276 @@ +#! /bin/bash + +echo "No translation-update-upstream data available. Keeping existing translation." +exit 0 + +set -o errexit +shopt -s nullglob + +if test "$1" = "--help" ; then + echo "Upstream translation update tool works in top directory of unpacked source code." + echo "Usage: $0 [translation_directory] [translation_domain] [command to create pot file]" +fi + +# Update all known mechanisms to add language: +function linguas_update { + if test -f LINGUAS -o -f ../po/LINGUAS ; then + if test -f LINGUAS ; then + touch -r LINGUAS translation-update-upstream-tmp-stamp + if sed '/^#/d' >LINGUAS + fi + touch -r translation-update-upstream-tmp-stamp LINGUAS + rm translation-update-upstream-tmp-stamp + else + echo "Not adding $LNG to LINGUAS - secondary domain, global LINGUAS." + fi + else + if test -f $OLDPWD/configure.ac ; then + if grep -q 'ALL_LINGUAS=' $OLDPWD/configure.ac ; then + echo "Adding $LNG to configure.ac." + touch -r $OLDPWD/configure.ac translation-update-upstream-tmp-stamp + sed -i 's/ALL_LINGUAS="/&'$LNG' /;s/\(ALL_LINGUAS=\)\([^"]\|$\)/\1"'$LNG' "\2/' $OLDPWD/configure.ac + touch -r translation-update-upstream-tmp-stamp $OLDPWD/configure.ac + rm translation-update-upstream-tmp-stamp + fi + fi + if test -f $OLDPWD/configure.in ; then + if grep -q 'ALL_LINGUAS=' $OLDPWD/configure.in ; then + echo "Adding $LNG to configure.in." + touch -r $OLDPWD/configure.in translation-update-upstream-tmp-stamp + sed -i 's/ALL_LINGUAS="/&'$LNG' /;s/\(ALL_LINGUAS=\)\([^"]\|$\)/\1"'$LNG' "\2/' $OLDPWD/configure.in + touch -r translation-update-upstream-tmp-stamp $OLDPWD/configure.in + rm translation-update-upstream-tmp-stamp + fi + fi + if test -f $OLDPWD/configure ; then + if grep -q 'ALL_LINGUAS=' $OLDPWD/configure ; then + echo "Adding $LNG to configure." + touch -r $OLDPWD/configure translation-update-upstream-tmp-stamp + sed -i 's/ALL_LINGUAS="/&'$LNG' /;s/\(ALL_LINGUAS=\)\([^"]\|$\)/\1"'$LNG' "\2/' $OLDPWD/configure + touch -r translation-update-upstream-tmp-stamp $OLDPWD/configure + rm translation-update-upstream-tmp-stamp + fi + fi + fi +} + +DOMAIN=$2 +USE_MESON=false +if test -f meson.build -a ! \( -f ${1:-po}/Makefile.in.in -o -f ${1:-po}/Makefile.in -o -f ${1:-po}/Makefile \) ; then + echo "Switching to meson style pot file extraction." >&2 + USE_MESON=true + if test -z "$DOMAIN" ; then + MESON_PROJECT="$(sed -n "/^project(/,+1{1{h;d};2{x;G}};s/^project[[:space:]]*([[:space:]]*'\([^']*\)'.*/\1/p" &2 + exit 1 + fi + fi + fi +fi +USE_INTLTOOL=false +if test -f configure.ac ; then + if grep PROG_INTLTOOL configure.ac ; then + USE_INTLTOOL=true + fi +fi +if test -f configure.in ; then + if grep PROG_INTLTOOL configure.in ; then + USE_INTLTOOL=true + fi +fi +DIR=${1:-po} + +if test -z "$3" ; then + if $USE_MESON ; then + if test -f POTFILES ; then + POTFILES="$PWD/${1:-po}/POTFILES" + else + POTFILES="$PWD/${1:-po}/POTFILES.in" + fi + xgettext --package-name="$DOMAIN"\ + -p "$PWD" -f "$POTFILES" -D "$PWD"\ + -k_ -o "$PWD/${1:-po}/$DOMAIN.pot"\ + --keyword=NC_:1c,2\ + --flag=g_strdup_printf:1:c-format\ + --flag=g_set_error:4:c-format\ + --flag=g_dngettext:2:pass-c-format\ + --flag=g_string_printf:2:c-format\ + --add-comments\ + --from-code=UTF-8\ + --keyword=C_:1c,2\ + --flag=N_:1:pass-c-format\ + --flag=g_string_append_printf:2:c-format\ + --flag=C_:2:pass-c-format\ + --keyword=N_\ + --flag=g_error_new:3:c-format\ + --flag=NC_:2:pass-c-format\ + --keyword=g_dngettext:2,3\ + --keyword=g_dpgettext2:2c,3\ + --keyword=_\ + --keyword=g_dcgettext:2 + cd $DIR + else + cd $DIR + if $USE_INTLTOOL ; then + if test -z "$DOMAIN" ; then + intltool-update --pot + else + intltool-update --gettext-package=$DOMAIN --pot + fi + else + # Fallback: use xgettext with default options except those that we + # cannot guess (it can stil fail, as options can be customized). + if test -z "$DOMAIN" ; then + ## Ugly hack! intltool could return invalid po, but its + ## FindPackageName() can guess domain. Call it to get it. + intltool-update --pot + for POT in *.pot ; do + DOMAIN=${POT%.pot} + done + fi + xgettext --default-domain="$DOMAIN" --directory="$OLDPWD" \ + --add-comments=TRANSLATORS: --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments \ + --files-from=./POTFILES.in + mv "$DOMAIN.po" "$DOMAIN.pot" + fi + fi +else + eval $3 +fi + +POT_NOT_UNIQUE=false +NO_POT=true +for POT in *.pot ; do + MISSING=true + if $POT_NOT_UNIQUE ; then + echo "ERROR: Directory $DIR contains more than one .pot file." + exit 1 + fi + POT_NOT_UNIQUE=true + DOMAIN=${POT%.pot} + + # STRING_COLLECT_MODE is a special mode used during string + # collection. STRING_COLLECT_DIR must be set as well. + if test "$STRING_COLLECT_MODE" = 1 ; then + mkdir $STRING_COLLECT_DIR/$DOMAIN + cp -a $POT $STRING_COLLECT_DIR/$DOMAIN + cp -a *.po $STRING_COLLECT_DIR/$DOMAIN + else + if test -d @DATADIR@/translation-update-upstream ; then + if test -d @DATADIR@/translation-update-upstream/po/$DOMAIN ; then + for PO_PATH in @DATADIR@/translation-update-upstream/po/$DOMAIN/*.po ; do + PO=${PO_PATH##*/} + LNG=${PO%.po} + if test -f $PO ; then + if test "$SKIP_TUU" = true ; then + echo "SKIP_TUU is set. Skipping update of $PO." + continue + fi + echo "Updating $PO using translation-update-upstream." + echo "(You can skip update by setting environment variable SKIP_TUU=true.)" + # PO_PATH is first: Update any string, even if it was already translated. + # Swap $PO_PATH and $PO to disable this behavior. + msgcat --use-first $PO_PATH $PO -o $PO.new + # Return .po file notes that are not present in the update file. + ## In theory, we should call msgmerge here, as the + ## imported file might be outdated. But we have to live + ## with the fact that the pot file heuristic above + ## might be incorrect, and the generated pot file is + ## incomplete. Never make things worse, and skip + ## msgmerge. Superfluous strings are better than + ## deleted strings. + ## In time of writing the priginal code, --compendium + ## worked around the fact that msgcat prefers empty + ## string from the first file over translated string + ## from the second file. Now msgcat behaves logically, + ## so this step is not needed. + #msgmerge --no-fuzzy-matching --compendium=$PO_PATH -o $PO.new2 $PO.new $POT + # And finally, synthesize header that not change every time. + #if @LIBEXECDIR@/translation-update-upstream/msgheadermerge $PO $PO.new2 $PO.header --mergemode ; then + if @LIBEXECDIR@/translation-update-upstream/msgheadermerge $PO $PO.new $PO.header --mergemode ; then + #msgcat --use-first $PO.header $PO.new2 -o $PO + msgcat --use-first $PO.header -o $PO + #rm $PO.new $PO.new2 $PO.header + rm $PO.new $PO.header + else + #rm $PO.new $PO.new2 + rm $PO.new + echo "WARNING: Update of $PO for $DOMAIN is older than data in package. Skipping." + fi + else + echo "Adding $PO from translation-update-upstream." + cp -a $PO_PATH $PO + linguas_update + fi + done + MISSING=false + fi + if test -d @DATADIR@/translation-update-upstream/po-mandatory/$DOMAIN ; then + for PO_PATH in @DATADIR@/translation-update-upstream/po-mandatory/$DOMAIN/*.po ; do + PO=${PO_PATH##*/} + LNG=${PO%.po} + if test -f $PO ; then + if test "$SKIP_TUU" = true ; then + echo "SKIP_TUU is set. Skipping update of $PO." + continue + fi + echo "Updating $PO using translation-update-upstream mandatory source." + echo "(You can skip update by setting environment variable SKIP_TUU=true.)" + # PO_PATH is first: Update any string, even if it was already translated. + # Swap $PO_PATH and $PO to disable this behavior. + msgcat --use-first $PO_PATH $PO -o $PO.new + # Return .po file notes that are not present in the update file. + ## In theory, we should call msgmerge here, as the + ## imported file might be outdated. But we have to live + ## with the fact that the pot file heuristic above + ## might be incorrect, and the generated pot file is + ## incomplete. Never make things worse, and skip + ## msgmerge. Superfluous strings are better than + ## deleted strings. + ## In time of writing the priginal code, --compendium + ## worked around the fact that msgcat prefers empty + ## string from the first file over translated string + ## from the second file. Now msgcat behaves logically, + ## so this step is not needed. + #msgmerge --no-fuzzy-matching --compendium=$PO_PATH -o $PO.new2 $PO.new $POT + # And finally, synthesize header that not change every time. + #if ! @LIBEXECDIR@/translation-update-upstream/msgheadermerge $PO $PO.new2 $PO.header --mergemode --continue ; then + if ! @LIBEXECDIR@/translation-update-upstream/msgheadermerge $PO $PO.new $PO.header --mergemode --continue ; then + echo "WARNING: Mandatory update of $PO for $DOMAIN is older than data in package or upstream snapshot. Using anyway!" + fi + #msgcat --use-first $PO.header $PO.new2 -o $PO + msgcat --use-first $PO.header $PO.new -o $PO + #rm $PO.new $PO.new2 $PO.header + rm $PO.new $PO.header + else + echo "Adding $PO from translation-update-upstream mandatory source." + cp -a $PO_PATH $PO + linguas_update + fi + done + MISSING=false + fi + if $MISSING ; then + echo "WARNING: Missing $DOMAIN in translation-update-upstream configuration! No updates available." + fi + else + echo "ERROR: Package translation-update-upstream is not installed. Please update your BuildRequires!" + exit 1 + fi + fi + NO_POT=false +done +if $NO_POT ; then + echo "ERROR: Pot file was not created. Please fix or set command line arguments properly!" + exit 1 +fi diff --git a/translation-update-upstream.spec b/translation-update-upstream.spec new file mode 100644 index 0000000..2e4f1f0 --- /dev/null +++ b/translation-update-upstream.spec @@ -0,0 +1,157 @@ +# +# spec file for package translation-update-upstream +# +# Copyright (c) 2020 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +Name: translation-update-upstream +Version: 20200601 +Release: 0 +Summary: Tool for Translation Update from Upstream +# Ignore cracklib, as it causes build loop cracklib <-> translation-update-upstream +#!BuildIgnore: cracklib libcrack2 +License: GPL-2.0-or-later +Group: System/Localization +Provides: translation-update-tool +Source: %{name}-%{version}.tar.bz2 +Source1: %{name}.in +Source2: %{name}-AUTHORS +Source3: %{name}-COPYING +Source4: %{name}-README +Source5: %{name}-HOWTO +Source6: msgheadermerge +Source7: msgheadermerge-compose +Source8: msgheadermerge-parse +Source9: msgheadermerge-empty.pot +Source10: %{name}-embedded-README +Source11: translation-update-mandatory-%{version}.tar.bz2 +Patch: %{name}-embedded.patch +# Files below are package maintainer tools, not used for package build: +Source50: upstream-collect.sh +Source51: upstream-collect.conf +Source52: upstream-collect-template.hook +Source53: create-tlst-step1-list-all-po-projects.sh +Source54: create-tlst-step2-create-gnome_gtp.sh +Source55: create-tlst.conf +Source56: translation-update-upstream-to-translation-update.sh +Source57: translation-update-static.tar.bz2 +Source58: check-translation-completeness.sh +# Configuration files for package maintainer tools: +Source60: upstream-gnome_gtp.tlst +Source61: upstream-gnome_gtp.hook +Source62: freedesktop_org.tlst +Source63: lcn-sle.tlst +Source65: misc.tlst +Source66: opensuse.tlst +Source67: static.tlst +Source69: github.tlst +Source70: upstream-gnome_gtp-not-on-media.tlst +BuildRoot: %{_tmppath}/%{name}-%{version}-build +Requires: coreutils +Requires: gettext-tools +Requires: grep +Requires: intltool +Requires: sed +BuildArch: noarch + +%description +This is a tool providing update of translations using available +upstream resources. + +The tool tool is intended for use during package compilation as a first +command after unpacking of source code. + +For more see README and HOWTO. + +This package also includes translation update data files. + +%prep + +%setup -q -T -a0 -a11 -c %{name}-%{version} +cp -a %{S:1} translation-update-upstream.in +cp -a %{S:2} AUTHORS +cp -a %{S:3} COPYING +cp -a %{S:4} README +cp -a %{S:5} HOWTO +cp -a %{S:6} %{S:7} %{S:8} %{S:9} . +cp -a %{S:10} translation-update-upstream-embedded.README +sed 's:@DATADIR@:%{_datadir}:g;s:@LIBEXECDIR@:%{_prefix}/lib:g' translation-update-upstream +sed 's/@LIBEXECDIR@/\$BASE_DIR/g;s:@DATADIR@/translation-update-upstream:\$BASE_DIR/translation-update-upstream/po:g;s/translation-update-upstream\./translation-update-upstream-embedded./g' translation-update-upstream-embedded.sh +%patch +chmod +x translation-update-upstream-embedded.sh + +%build +. %{_sourcedir}/upstream-collect.conf + +%install +mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name} $RPM_BUILD_ROOT%{_prefix}/lib/translation-update-upstream +cp -a po po-mandatory $RPM_BUILD_ROOT%{_datadir}/%{name} +install -d $RPM_BUILD_ROOT%{_bindir} +install translation-update-upstream $RPM_BUILD_ROOT%{_bindir}/ +install -m0755 msgheadermerge msgheadermerge-compose msgheadermerge-parse $RPM_BUILD_ROOT%{_prefix}/lib/translation-update-upstream/ +install -m0644 msgheadermerge-empty.pot $RPM_BUILD_ROOT%{_prefix}/lib/translation-update-upstream/ +ln -s translation-update-upstream $RPM_BUILD_ROOT%{_bindir}/translation-update-tool +# +# +# obsolete or bad locales +# +# gnome-i18n says nds_NFE is wrong, remove until upstream clearified that +rm -fv $RPM_BUILD_ROOT%{_datadir}/%{name}/po/*/nds?NFE.po +# +# invalid locales +# +# should be @latin +rm -fv $RPM_BUILD_ROOT%{_datadir}/%{name}/po/*/*@Latn.po +# should be nb +rm -fv $RPM_BUILD_ROOT%{_datadir}/%{name}/po/*/no.po +# should be nb +rm -fv $RPM_BUILD_ROOT%{_datadir}/%{name}/po/*/no_nb.po +# should be ar +rm -fv $RPM_BUILD_ROOT%{_datadir}/%{name}/po/*/ara.po +# testing locale, should not appear in packages +rm -fv $RPM_BUILD_ROOT%{_datadir}/%{name}/po/*/en_IGID.po +# short form of these locales should be used +rm -fv $RPM_BUILD_ROOT%{_datadir}/%{name}/po/*/my_MM.po +# these are nonsenses +#rm -v $RPM_BUILD_ROOT%{_datadir}/%{name}/po/glib-networking/master.po +#rm -v $RPM_BUILD_ROOT%{_datadir}/%{name}/po/glib20/glib.glib-2-30.gu.po +# +# go through valid locales and fail in invalid ones +# +set +x +cd $RPM_BUILD_ROOT%{_datadir} ; +echo translation*/*/*.po | sed 's:.*/::;s:\.po$::' | sort -u +for LOCALE in $(set +x ; cd $RPM_BUILD_ROOT%{_datadir} ; ls -1 translation*/*/*/*.po | sed 's:.*/::;s:\.po$::' | sort -u) ; do + if ! test -d /usr/share/locale/$LOCALE ; then + for file in $RPM_BUILD_ROOT%{_datadir}/translation*/*/*/$LOCALE.po; do + # fake it so it looks like removed from %%find_lang + package=$(echo $file | sed -e 's,.*translation[^/]*/po/,,; s,/[^/]*.po,,') + echo -n "removing translation /usr/share/locale/$LOCALE/LC_MESSAGES/$package.mo: " + msgfmt -o - $file | msgunfmt -o - -| msgfmt --statistics -o /dev/null - + done + fi +done + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr (-,root,root) +%doc AUTHORS COPYING README HOWTO +%{_bindir}/* +%{_datadir}/%{name} +%{_prefix}/lib/translation-update-upstream + +%changelog diff --git a/upstream-collect-template.hook b/upstream-collect-template.hook new file mode 100644 index 0000000..b183372 --- /dev/null +++ b/upstream-collect-template.hook @@ -0,0 +1,20 @@ +#!/bin/bash +if test -z "$PACKAGE" ; then + echo "This is a hook file for upstream-collect.sh. It cannot be called separately." + exit 255 +fi + +# This is just a template of a hook file. If you need a hook, give it +# a name foo.hook, where foo.tlst is a name of your .tlst file. Hook +# is called for each line of the .tlst file after evaluation of +# $RPMPKGDIR, but before each further processing. + +echo "Here are variables from the tlst file: $PACKAGE $DOMAIN $METHOD $REPO $DIR $BRANCH (read only)" +echo "Working directory: $WORK_DIR (read only)" +echo "Directory, where your package source will be placed: $RPMPKGDIR (read only)" + +# directory in the remote repostory: +REPODIR=$DIR + +# directory with the the RPM po files +RPMPODIR$(echo $RPMPKGDIR/BUILD/*/${DIR#*/}) diff --git a/upstream-collect.conf b/upstream-collect.conf new file mode 100644 index 0000000..5a9f376 --- /dev/null +++ b/upstream-collect.conf @@ -0,0 +1,20 @@ +# upstream-collect.conf: Configuration for updating of translation-update-upstream package. +# + +# osc repositories with packages (space separated list in parentheses, first takes precedence) +# It typically consists of an array of following repositories (in this order): +# - proposed-translation-fixes repository with yet unreleased changes (if exists; such repo allows us to create a tarball update for translation-update package without rebuild) +# - latest patchlevel packages sources (if exists) +# - the original gold master (GA) package sources +OSC_REPOSITORIES=( openSUSE:Leap:15.2 openSUSE:Leap:15.1:Update openSUSE:Leap:15.1 openSUSE:Leap:15.0:Update openSUSE:Leap:15.0 ) + +# OSC_REPOSITORIES array index of the main (fully rebuilt with current translation-update-upstream) repository (starts with 0). +# It is typically 0 for Factory based products, 1 for products where 0 is a proposed-translation-fixes repo, 2 for products which are not fully rebuilt before release where 1 represents patchlevel repository. +OSC_MAIN_INDEX=4 + +# OSC_REPOSITORIES array index of the repository with proposed translation updates that don't appear in the main product (starts with 0). Keep empty if there is no such repository. +# It is typically empty for Factory based products, otherwise it points to an unreleased proposed-translation-fixes repository with index 0. +OSC_PROPOSED_INDEX= + +# osc server, empty for using of the osc default +OSC_APIURL=https://api.opensuse.org/ diff --git a/upstream-collect.sh b/upstream-collect.sh new file mode 100644 index 0000000..359c0be --- /dev/null +++ b/upstream-collect.sh @@ -0,0 +1,955 @@ +#!/bin/bash + +# This program collects all upstream translations defined in +# configuration and merges them together. + +# If you want to use po files for completing of translations, you can remove --no-fuzzy-matching. +# It will run much slower, but you could start with fuzzy matches. + +# Debug mode. Set to true if you want to keep working directories. +DEBUG=false +# Incremental mode. With exception of bootstrapping or resetting the memory, it should be true. +# Non-incremental update cannot process a single package. +# FIXME: The incremental mode does not drop obsolete packages. You +# need to delete them manually afterwards using time stamp. +INCREMENTAL=true +# Set to false to generate only pot files, true to collect po files. +COLLECT_UPSTREAM=true +# Number of CPUs. When > 1, then parallel processing of more po files is possible. +CPUS=$(cat /proc/cpuinfo | grep processor | wc -l) +WORK_DIR=$PWD + +set -o errexit +shopt -s nullglob + +rpm -q obs-service-tar >/dev/null +rpm -q obs-service-recompress >/dev/null + +source ${0%.sh}.conf + +function get_pot_name { + POT= + for POT in *.pot ; do + : + done +} + +function validate_po_with_plural_check { + local LOG=$HOME/.validate${1##*/}.log$$ + trap "rm -f $LOG" 0 + if LC_ALL=C LANG=C msgfmt -c -o /dev/null "$1" 2>$LOG ; then + RC=0 + else + RC=1 + fi + PLURAL_FAILURE=false + if grep -q 'plural form' $LOG ; then + PLURAL_FAILURE=true + fi + rm $LOG + trap - 0 + return $RC +} + +function validate_po { + LC_ALL=C LANG=C msgfmt -c -o /dev/null "$1" +} + +function rpmprep { + RPMDIR=$HOME/.var.rpmpatch$$ + rm -rf BUILD $HOME/.var.rpmpatch$$ + trap "rm -rf $RPMDIR" 0 + mkdir -p BUILD $RPMDIR + # Add "%BUILD_ORIG 1" to support original source translation: + cat >$RPMDIR/macros < tag from Release and delete shell escape comments. + /^Release:/s/[<>]//g + # Remove bash shell escape comments (gstreamer, calls autoreconf that can fail). + /#%(bash/d + # Remove negative expressions in BuildRequires. + :1 + s/^\(BuildRequires:.*[[:space:]]\)-[^[:space:]]*/\1/ + t1 + /^BuildRequires:[[:space:]]*$/d + # Modify some requirements to work without relevant packages installed. + s/%{xulrunner_version}/dummy/g + s/%{mozilla_ver}/dummy/g + s/%{glib2_gsettings_schema_requires}/Requires: dummy/g + s/%glib2_gsettings_schema_requires/Requires: dummy/g + s/%{gtk2_immodule_requires}/Requires: dummy/g + s/%{gtk3_immodule_requires}/Requires: dummy/g + s/%{py_requires}/Requires: dummy/g + s/%py_requires/Requires: dummy/g + s/%kde4_runtime_requires/Requires: dummy/g + s/%systemd_requires/Requires: dummy/g + s/%gconf_schemas_prereq/Requires: dummy/g + s/%{gconf_schemas_prereq}/Requires: dummy/g + s/%glib2_gio_module_requires/Requires: dummy/g + s/%{glib2_gio_module_requires}/Requires: dummy/g + s/%{_bluezVersion}/0/g + ' *.spec + eval rpmbuild --macros=/usr/lib/rpm/macros:/usr/lib/rpm/suse_macros:/usr/lib/rpm/suse/macros:/usr/lib/rpm/macros.d/macros.systemd:/usr/lib/rpm/platform/$(uname -i)-linux/macros:/etc/rpm/\\\*:$RPMDIR/macros --nodeps -bp ${*:-*.spec} + rm -rf $RPMDIR + trap - 0 +} + +ONLY_PACKAGES=() +FULL_PROCESS=true +SNAPSHOT=$(LC_ALL=C LANG=C date +%Y%m%d) +MSNAPSHOT=$SNAPSHOT +case $1 in + --help ) + # "only_new" is tricky: Processing new is the default. "only_new" has no match => only_new. + echo "Usage: $0 [ package | only_new ]" + exit + ;; + # no arguments: process everything + "" ) + ;; + * ) + ONLY_PACKAGES=("$@") + FULL_PROCESS=false + ;; +esac + +rm -rf UPSTREAM +mkdir UPSTREAM +if ! test -d STAMPS ; then + mkdir -p pot pot-tuu pot-diff + mkdir OSC PACKAGES UPDATE STAMPS + rm -f upstream-collect.log + rm -f upstream-collect.domain-map.tmp +fi + +# wd may contain ":" in the name, use ~/ instead: +mkdir -p ~/.upstream-collect.tmp +cat >~/.upstream-collect.tmp/translation-update-upstream <&2 + USE_MESON=true + if test -z "\$DOMAIN" ; then + MESON_PROJECT="\$(sed -n "/^project(/,+1{1{h;d};2{x;G}};s/^project[[:space:]]*([[:space:]]*'\([^']*\)'.*/\1/p" &2 + exit 1 + fi + fi + fi +fi +USE_INTLTOOL=false +if test -f configure.ac ; then + if grep PROG_INTLTOOL configure.ac ; then + USE_INTLTOOL=true + fi +fi +if test -f configure.in ; then + if grep PROG_INTLTOOL configure.in ; then + USE_INTLTOOL=true + fi +fi +DIR=\${1:-po} + +if test -z "\$3" ; then + if \$USE_MESON ; then + if test -f POTFILES ; then + POTFILES="\$PWD/\${1:-po}/POTFILES" + else + POTFILES="\$PWD/\${1:-po}/POTFILES.in" + fi + echo "cd \\"\$PWD\\" +xgettext --package-name=\\"\$DOMAIN\\"\\\\ + -p \\"\$PWD\\"\\\\ + -f \\"\$POTFILES\\"\\\\ + -D \\"\$PWD\\"\\\\ + -k_ -o \\"\$PWD/\${1:-po}/\$DOMAIN.pot\\"\\\\ + --keyword=NC_:1c,2\\\\ + --flag=g_strdup_printf:1:c-format\\\\ + --flag=g_set_error:4:c-format\\\\ + --flag=g_dngettext:2:pass-c-format\\\\ + --flag=g_string_printf:2:c-format\\\\ + --add-comments\\\\ + --from-code=UTF-8\\\\ + --keyword=C_:1c,2\\\\ + --flag=N_:1:pass-c-format\\\\ + --flag=g_string_append_printf:2:c-format\\\\ + --flag=C_:2:pass-c-format\\\\ + --keyword=N_\\\\ + --flag=g_error_new:3:c-format\\\\ + --flag=NC_:2:pass-c-format\\\\ + --keyword=g_dngettext:2,3\\\\ + --keyword=g_dpgettext2:2c,3\\\\ + --keyword=_\\\\ + --keyword=g_dcgettext:2" >\${1:-po}/.translation-update-upstream-implemented + else + if \$USE_INTLTOOL ; then + if test -z "\$DOMAIN" ; then + echo "intltool-update --pot" >\${1:-po}/.translation-update-upstream-implemented + else + intltool-update --gettext-package=\$DOMAIN --pot + echo "intltool-update --gettext-package=\$DOMAIN --pot" >\${1:-po}/.translation-update-upstream-implemented + fi + else + # Fallback: use xgettext with default options except those that we + # cannot guess (it can stil fail, as options can be customized). + echo "cd \\"\$DIR\\" + if test -z \\"\$DOMAIN\\" ; then + ## Ugly hack! intltool could return invalid po, but its + ## FindPackageName() can guess domain. Call it to get it. + intltool-update --pot + for POT in *.pot ; do + DOMAIN=\\\${POT%.pot} + done + fi + xgettext --default-domain=\\"\$DOMAIN\\" --directory=\\"\$OLDPWD\\" \\\\ + --add-comments=TRANSLATORS: --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments \\\\ + --files-from=./POTFILES.in + mv \\"\\\$DOMAIN.po\\" \\"\\\$DOMAIN.pot\\"" >\${1:-po}/.translation-update-upstream-implemented + fi + fi +else + echo \$3 >\${1:-po}/.translation-update-upstream-implemented +fi +cd \${1:-po} +# Generate and save a copy of the pot file now and compare later. +bash ./.translation-update-upstream-implemented +mkdir -p tuu +for POT in *.pot ; do + cp -a \$POT tuu/ +done +EOF +chmod +x ~/.upstream-collect.tmp/translation-update-upstream + +# executable flag does not survive some build systems +chmod +x msgheadermerge msgheadermerge-compose msgheadermerge-parse upstream-collect.sh create-tlst-step*.sh translation-update-upstream-to-translation-update.sh + +# Strings in installed instance of gnome-patch-translation may interfere +# with upstream-collect.sh. Use of dummies allows to import upstream +# strings, that are part of openSUSE patches. +for FILE in gnome-patch-translation-prepare gnome-patch-translation-update ; do + cat >~/.upstream-collect.tmp/$FILE < use the latest one + # FIXME: Fix 20090213.10 < 20090213.9 + # (but it should not happen for people who update and submit) + for ARCHIVE_ in translation-update-upstream-*.tar.bz2 ; do + ARCHIVE=$ARCHIVE_ + done + if ! test -f STAMPS/UPDATE_old_tarball ; then + cd UPDATE + echo "$(tput setf 3)Unpacking: $ARCHIVE$(tput init)" + tar -jxf ../$ARCHIVE + # If it is not a full process, increment only release + # SNAPSHOT 20090213 -> 20090213.1, 20090213.1 -> 20090213.2 + cd .. + touch STAMPS/UPDATE_old_tarball + fi + SNAPSHOT_RELEASE=${ARCHIVE#translation-update-upstream-} + SNAPSHOT_RELEASE=${SNAPSHOT_RELEASE%.tar.bz2} + SNAPSHOT_RELEASE_PART1=${SNAPSHOT_RELEASE%.*} + SNAPSHOT_RELEASE_PART2=${SNAPSHOT_RELEASE#*.} + if test "$SNAPSHOT_RELEASE_PART1" = "$SNAPSHOT_RELEASE" ; then + SNAPSHOT_RELEASE_PART2=1 + else + let SNAPSHOT_RELEASE_PART2++ + fi + SNAPSHOT_RELEASE=$SNAPSHOT_RELEASE_PART1.$SNAPSHOT_RELEASE_PART2 + + for ARCHIVE_ in translation-update-mandatory-*.tar.bz2 ; do + ARCHIVE=$ARCHIVE_ + done + if ! test -f STAMPS/UPDATE_old_mtarball ; then + cd UPDATE + echo "$(tput setf 3)Unpacking: $ARCHIVE$(tput init)" + tar -jxf ../$ARCHIVE + # If it is not a full process, increment only release + # SNAPSHOT 20090213 -> 20090213.1, 20090213.1 -> 20090213.2 + cd .. + touch STAMPS/UPDATE_old_mtarball + fi + MSNAPSHOT_RELEASE=${ARCHIVE#translation-update-mandatory-} + MSNAPSHOT_RELEASE=${MSNAPSHOT_RELEASE%.tar.bz2} + SNAPSHOT_RELEASE_PART1=${MSNAPSHOT_RELEASE%.*} + SNAPSHOT_RELEASE_PART2=${MSNAPSHOT_RELEASE#*.} + if test "$SNAPSHOT_RELEASE_PART1" = "$MSNAPSHOT_RELEASE" ; then + SNAPSHOT_RELEASE_PART2=1 + else + let SNAPSHOT_RELEASE_PART2++ + fi + MSNAPSHOT_RELEASE=$SNAPSHOT_RELEASE_PART1.$SNAPSHOT_RELEASE_PART2 +fi +if ! $FULL_PROCESS ; then + SNAPSHOT=$SNAPSHOT_RELEASE + MSNAPSHOT=$MSNAPSHOT_RELEASE +fi + +SERIAL=0 +for TLST in *.tlst ; do + exec <$WORK_DIR/$TLST + + while read PACKAGE DOMAIN METHOD REPO DIR BRANCH MANDATORY ; do + + # Continue for empty lines and comments + if test "${PACKAGE###}" != "$PACKAGE" ; then + continue + fi + if test -z "$PACKAGE" ; then + continue + fi + if test "$MANDATORY" = "mandatory" ; then + MANDATORY=true + else + MANDATORY=false + fi + + echo + echo "$(tput setf 3)Processing: package=$PACKAGE domain=$DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:-(default)} mandatory=$MANDATORY$(tput init)" + + STATUS=OK + # NOTE: Force a limitation: tlst rules for one package must be placed on contiguous line sequence + if ! $DEBUG ; then + if test "$OLD_PACKAGE" != "$PACKAGE" ; then + if test -n "$RPMPKGDIR" ; then + rm -rf $RPMPKGDIR $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok + fi + fi + OLD_PACKAGE=$PACKAGE + fi + + if test -d $WORK_DIR/STAMPS/$PACKAGE/$DOMAIN/$METHOD/${REPO//[\/:.]/_}/$DIR/${BRANCH:-__HEAD__} ; then + echo " Already successfully processed. Skipping..." + continue + fi + + if test "${#ONLY_PACKAGES}" -gt 0 ; then + SKIP_PACKAGE=true + for ONLY_PACKAGE in "${ONLY_PACKAGES[@]}" ; do + if test "$ONLY_PACKAGE" = "$PACKAGE" ; then + SKIP_PACKAGE=false + break + fi + done + if $SKIP_PACKAGE ; then + echo " Not scheduled to process. Recycling old update..." +#FIXME mkdir -p $WORK_DIR/STAMPS/$PACKAGE/$DOMAIN/$METHOD/${REPO//[\/:.]/_}/$DIR/${BRANCH:-__HEAD__} +# touch $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok + continue + fi + fi + + cd $WORK_DIR/OSC + + RPMPKGDIR=$WORK_DIR/PACKAGES/$PACKAGE + + if ! test -f $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok ; then + if ! test -d "$RPMPKGDIR" ; then + for OSC_REPOSITORY in "${OSC_REPOSITORIES[@]}" ; do + echo "Trying to check-out PACKAGES $PACKAGE from $OSC_REPOSITORY..." + # FIXME: When obs-service-download_url appears in Factory, use --source-service-files + if osc ${OSC_APIURL:+--apiurl=$OSC_APIURL} checkout --server-side-source-service-files --expand-link $OSC_REPOSITORY $PACKAGE >gnome-patch-translation-collect-tmp.log 2>&1 ; then + cd $OSC_REPOSITORY/$PACKAGE + if test -f _service ; then + for FILE in *.obscpio ; do + cpio -d -i <$FILE + done + sed -i '//,/<\/service>/d;//d;s/mode="buildtime"//' _service + osc service runall + fi + cd "$OLDPWD" + mv $OSC_REPOSITORY/$PACKAGE $WORK_DIR/PACKAGES/ + for FILE in $WORK_DIR/PACKAGES/$PACKAGE/_service\:download_url\:* ; do + mv "$FILE" "${FILE/_service:download_url:/}" + done + break + fi + if ! grep -q "HTTP Error 404" gnome-patch-translation-collect-tmp.log ; then + cat gnome-patch-translation-collect-tmp.log + rm gnome-patch-translation-collect-tmp.log + echo "ERROR: Checkout failed!" + exit 1 + fi + done + rm gnome-patch-translation-collect-tmp.log + else + rm -rf "$RPMPKGDIR" $WORK_DIR/STAMPS/$PACKAGE + echo "$(tput setf 4)Removed possibly incorrect temporary files from previous runs. Please re-run $0 now.$(tput init)" + exit 1 + fi + cd $RPMPKGDIR + rpmprep $PACKAGE.spec + else + # During processing, builddir may contain incomplete po files: + rm $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok + fi + REPODIR=$DIR + RPMPODIR=$(echo $RPMPKGDIR/BUILD/*/${DIR#*/}) + + if test -f $WORK_DIR/${TLST%.tlst}.hook ; then + source $WORK_DIR/${TLST%.tlst}.hook + fi + + cd $RPMPODIR + get_pot_name + REAL_DOMAIN=${POT%.pot} + if test -f .gnome-patch-translation-implemented ; then + echo $PACKAGE >>$WORK_DIR/gnome-patch-translation.lst + fi + if test -f .translation-update-upstream-implemented ; then + if bash ./.translation-update-upstream-implemented ; then + get_pot_name + REAL_DOMAIN=${POT%.pot} + cp -a $REAL_DOMAIN.pot $WORK_DIR/pot/ + # pot-tuu DOMAIN is the external domain - LCN may use different domain + cp -a tuu/$REAL_DOMAIN.pot $WORK_DIR/pot-tuu/$DOMAIN.pot + # Verify that patches don't introduce new strings. + msgcomm --uniq $REAL_DOMAIN.pot tuu/$REAL_DOMAIN.pot -o $WORK_DIR/pot-diff/$DOMAIN.pot + if ! test -f .gnome-patch-translation-implemented ; then + if test -f $WORK_DIR/pot-diff/$DOMAIN.pot ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)}: new pot file contains unique strings, please check gnome-patch-translation" + STATUS=OK_INCOMPLETE + fi + fi + else + # translation-update-upstream is implemented but fails: + get_pot_name + REAL_DOMAIN=${POT%.pot} + if test -f $REAL_DOMAIN.pot ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)}: pot file update error, continuing with original $DOMAIN.pot" + STATUS=OK_OUTDATED + cp -a $DOMAIN.pot $WORK_DIR/pot/ + else + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)}: pot file update error, no way to update" + STATUS=POT_ERROR + mkdir -p $WORK_DIR/STAMPS/$PACKAGE/$DOMAIN/$METHOD/${REPO//[\/:.]/_}/$REPODIR/${BRANCH:-__HEAD__} + # However we cannot do anything, build dir is successfully processed. + touch $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok + continue + fi + fi + else + echo "$RPMPODIR: Missing or incorrect translation-update-upstream in the spec file." + # translation-update-upstream is implemented, try the default with the upstream domain: + cd .. + RC=0 + if test -f meson.build -a ! \( -f po/Makefile.in.in -o -f po/Makefile.in -o -f po/Makefile \); then + echo "Switching to meson style pot file extraction." + MESON_PROJECT="$(sed -n "/^project(/,+1{1{h;d};2{x;G}};s/^project[[:space:]]*([[:space:]]*'\([^']*\)'.*/\1/p" >$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)}: packaging error, package does not call translation-update-upstream properly and intltool-update fails, no way to update" + STATUS=TUU_BROKEN + mkdir -p $WORK_DIR/STAMPS/$PACKAGE/$DOMAIN/$METHOD/${REPO//[\/:.]/_}/$REPODIR/${BRANCH:-__HEAD__} + # However we cannot do anything, build dir is successfully processed. + touch $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok + continue + fi + for POT in *.pot ; do + DOMAIN=${POT%.pot} + done + fi + xgettext --default-domain="$DOMAIN" --directory="$OLDPWD" \ + --add-comments=TRANSLATORS: --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments \ + --files-from=./POTFILES.in + mv "$DOMAIN.po" "$DOMAIN.pot" + fi + get_pot_name + REAL_DOMAIN=${POT%.pot} + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)}: packaging error, package does not call translation-update-upstream properly" + STATUS=TUU_NOT_CALLED + cp -a $DOMAIN.pot $WORK_DIR/pot/ + fi + fi + + echo $PACKAGE $REAL_DOMAIN $STATUS >>$WORK_DIR/upstream-collect.domain-map.tmp + + if $COLLECT_UPSTREAM ; then + cd $WORK_DIR/UPSTREAM + let SERIAL++ || : + mkdir $SERIAL + cd $SERIAL + echo >.info "package=$PACKAGE domain=$DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)}" + + case "$METHOD" in + cvs ) + cvs -z3 -d:pserver:anoncvs@$REPO co $REPODIR $BRANCH + cd $REPODIR + ;; + svn ) + if test -z "$BRANCH" ; then + svn co $REPO/${REPODIR%%/*}/trunk/${REPODIR#*/} + else + svn co $REPO/${REPODIR%%/*}/branches/$BRANCH/${REPODIR#*/} + fi + cd ${REPODIR##*/} + ;; + git ) + if ! test -d $WORK_DIR/GIT/${REPO//[\/:.]/_} ; then + mkdir -p $WORK_DIR/GIT/${REPO//[\/:.]/_} + cd $WORK_DIR/GIT/${REPO//[\/:.]/_} + git clone $REPO + cd $OLDPWD + fi + cp -a $WORK_DIR/GIT/${REPO//[\/:.]/_}/* . + if test -n "$BRANCH" ; then + cd * + git checkout remotes/origin/$BRANCH + cd $OLDPWD + fi + cd $REPODIR + ;; + # Web-based Git repository viewer makes possible to download particular file. + cgit ) + # Some tricks to be able to recycle git:// URI + CGIT_URI=$REPO + CGIT_URI=${CGIT_URI/git:\/\/anongit./https://cgit.} + CGIT_URI=${CGIT_URI/git:\/\//https://} + CGIT_BRANCH=${BRANCH:+?id=$BRANCH} + CGIT_SERVER=${CGIT_URI#https://} + CGIT_SERVER=${CGIT_SERVER%%/*} + curl $CGIT_URI/tree/${REPODIR#*/}$CGIT_BRANCH | sed -n 's:^.*class='\''ls-blob[^'\'']*'\'' href='\''\([^'\'']*\)'\''.*$:\1:p' | + while read ; do + wget -N http://$CGIT_SERVER${REPLY/\/tree\///plain/} + done + ;; + # standard http directory with po files (BRANCH is not supported) + http ) + wget -N -r --no-parent --level=1 http://$REPO/$REPODIR/$DIR + cd $REPO/$REPODIR/$DIR + ;; + # GNOME Translation project l10n directory + gtp ) + GTP_NAME_BASE=${REPODIR%%/*} + # Projects with multiple domains have custom handling in GTP. + case $DOMAIN in + gimp20-libgimp ) GTP_NAME_BASE=gimp-libgimp ;; + gimp20-python ) GTP_NAME_BASE=gimp-python ;; + gimp20-script-fu ) GTP_NAME_BASE=gimp-script-fu ;; + gimp20-std-plug-ins ) GTP_NAME_BASE=gimp-plug-ins ;; + gimp20-tags ) GTP_NAME_BASE=gimp-tags ;; + gimp20-tips ) GTP_NAME_BASE=gimp-tips ;; + gnumeric-functions ) GTP_NAME_BASE=gnumeric-functions ;; + gtk20-properties ) GTP_NAME_BASE=gtk+-properties ;; + libgweather-locations ) GTP_NAME_BASE=locations ;; + esac + curl https://$REPO/${REPODIR%%/*}.${BRANCH:-master}/ | sed -n 's:^.*href="\([^"]*\.po\)".*$:\1:p' | + while read ; do + case $REPLY in + *.reduced.po ) + ;; + $GTP_NAME_BASE.${BRANCH:-master}.*) + wget -N https://$REPO/${REPODIR%%/*}.${BRANCH:-master}/$REPLY + mv $REPLY ${REPLY#$GTP_NAME_BASE.${BRANCH:-master}.} + ;; + esac + done + ;; + tbz ) + wget -N $REPO + tar -jxf ${REPO##*/} + cd $REPODIR + ;; + tgz ) + wget -N $REPO + tar -zxf ${REPO##*/} + cd $REPODIR + ;; + txz ) + wget -N $REPO + tar -Jxf ${REPO##*/} + cd $REPODIR + ;; + static ) + if ! test -d $WORK_DIR/translation-update-static ; then + cd $WORK_DIR + tar -jxf translation-update-static.tar.bz2 + cd - + fi + cp -a $WORK_DIR/translation-update-static/$DOMAIN . + cd $DOMAIN + ;; + lcn ) + if ! test -d $WORK_DIR/LCN-${BRANCH:-trunk} ; then + mkdir $WORK_DIR/LCN-${BRANCH:-trunk} + cd $WORK_DIR/LCN-${BRANCH:-trunk} + if test "${BRANCH:-trunk}" = "trunk" ; then + BRANCH_PATH="${BRANCH:-trunk}" + else + BRANCH_PATH="branches/$BRANCH" + fi + svn co https://svn.opensuse.org/svn/opensuse-i18n/$BRANCH_PATH/lcn + for PO in lcn/*/po/*.po ; do + LCN_LANG=${PO%/*} + LCN_LANG=${LCN_LANG#lcn/} + LCN_LANG=${LCN_LANG%%/*} + LCN_DOMAIN=${PO##*/} + LCN_DOMAIN=${LCN_DOMAIN%.$LCN_LANG.po} + mkdir -p data/$LCN_DOMAIN + ln $PO data/$LCN_DOMAIN/$LCN_LANG.po + done + cd - + fi + cp -a $WORK_DIR/LCN-${BRANCH:-trunk}/data/${REPODIR%/po} . + cd ${REPODIR%/po} + ;; + * ) + echo "$PACKAGE: Unknown update method $METHOD" + exit 1 + ;; + esac + +# +# Files created in this section: +# +# upstream dir: +# foo-backport.po: raw upstream translation backported to the downstream +# foo-uheader.po: header with the upstream date from the branch modified as last +# foo-upstream.po: backport + updates from all upstreams processed before (date from the branch modified as last) +# foo-allfz.po: downstream + joined updates. Strings that were modified create fuzzy multi-match. +# foo-all.po: downstream + joined updates. Strings that were modified use the last processed instance. +# foo-fixes.po: Strings that are different while comparing downstream and joined updates. +# foo-additions.po: Strings that are newly introduced in joined updates while comparing with downstream. +# foo-header.po: header with the lastest date, either upstream date from the branch modified as last or the downstream date +# foo-fixes-clean.po: fixes with a nice header. +# +# downstream dir: +# foo-downstream.po: cleaned and complete downstream po file +# foo-updatesraw.po: fixes + additions in a single file, raw form +# foo-updates.po: fixes + additions in a single file, clean form with an useful header (this file will be copied to UPDATE/) +# + for PO in *.po ; do + ( + if $MANDATORY ; then + if ! validate_po $PO ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)} po=$PO: mandatory validation error!" + exit + fi + # Mandatory sources: copy the whole source to the mandatory po directory. Strings must not be skipped. + mkdir -p $WORK_DIR/UPDATE/po-mandatory/$REAL_DOMAIN + if test -f $WORK_DIR/UPDATE/po-mandatory/$REAL_DOMAIN/$PO ; then + msgcat --use-first $PO $WORK_DIR/UPDATE/po-mandatory/$REAL_DOMAIN/$PO -o $WORK_DIR/UPDATE/po-mandatory/$REAL_DOMAIN/$PO~ + mv $WORK_DIR/UPDATE/po-mandatory/$REAL_DOMAIN/$PO~ $WORK_DIR/UPDATE/po-mandatory/$REAL_DOMAIN/$PO + else + msgcat $PO -o $WORK_DIR/UPDATE/po-mandatory/$REAL_DOMAIN/$PO + fi + mkdir -p $WORK_DIR/po-mandatory-full/$REAL_DOMAIN + if test -f $RPMPODIR/$PO ; then + # FIXME: Downstream po file may be invalid and cause invalid po-full po file. It does not + # create any regression, but it would be nice to try harder to fix brokenness. + if ! msgmerge --no-fuzzy-matching $RPMPODIR/$PO $RPMPODIR/$REAL_DOMAIN.pot -o $RPMPODIR/${PO%.po}-downstream.po ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN repository=$REPO directory=$RPMPODIR branch=${BRANCH:(default)} po=$PO: package msgmerge error" + # Failed initial msgmerge is fatal. There is no way to update. Build may fail. + exit + fi + msgcat --use-first --force-po $PO $RPMPODIR/${PO%.po}-downstream.po -o $RPMPODIR/${PO%.po}-merged.po + msgattrib --no-obsolete $RPMPODIR/${PO%.po}-merged.po -o $WORK_DIR/po-mandatory-full/$REAL_DOMAIN/$PO + else + msgattrib --no-obsolete $PO -o $WORK_DIR/po-mandatory-full/$REAL_DOMAIN/$PO + fi + else + # step 0: Merge new po file into old project. Removes unused (too new) translations. + if ! msgmerge --no-fuzzy-matching $PO $RPMPODIR/$REAL_DOMAIN.pot -o ${PO%.po}-backport.po~ ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)} po=$PO: msgmerge error" + exit + fi + if ! validate_po ${PO%.po}-backport.po~ ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)} po=$PO: validation error (backported po file)" + exit + fi + if test -f $RPMPODIR/$PO ; then + # step 1: Clean the RPM po file to be safe. + if ! msgmerge --no-fuzzy-matching $RPMPODIR/$PO $RPMPODIR/$REAL_DOMAIN.pot -o $RPMPODIR/${PO%.po}-downstream.po ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN repository=$REPO directory=$RPMPODIR branch=${BRANCH:(default)} po=$PO: package msgmerge error" + # Failed initial msgmerge is fatal. There is no way to update. Build may fail. + exit + fi + # Do the magic: + # step 2: Merge new upstream po and previous upstream updates to RPM po (if any). + OLD_UPDATE=false + PLURAL_FAILURE=false + if test -f $WORK_DIR/UPDATE/po/$REAL_DOMAIN/$PO ; then + if ! $WORK_DIR/msgheadermerge $WORK_DIR/UPDATE/po/$REAL_DOMAIN/$PO $PO ${PO%.po}-uheader.po --mergemode --continue ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN repository=$REPO directory=$RPMPODIR branch=${BRANCH:(default)} po=$PO: old po file, skipping fixes" + OLD_UPDATE=true + fi + msgcat --force-po --use-first ${PO%.po}-uheader.po ${PO%.po}-backport.po~ $WORK_DIR/UPDATE/po/$REAL_DOMAIN/$PO -o ${PO%.po}-upstream.po + if ! validate_po_with_plural_check ${PO%.po}-upstream.po ; then + if $PLURAL_FAILURE ; then + # Try to use downstream plural forms. + $WORK_DIR/msgheadermerge $WORK_DIR/UPDATE/po/$REAL_DOMAIN/$PO $PO ${PO%.po}-uheader_opf.po --mergemode --continue --old-plural-forms + msgcat --force-po --use-first ${PO%.po}-uheader_opf.po ${PO%.po}-backport.po~ $WORK_DIR/UPDATE/po/$REAL_DOMAIN/$PO -o ${PO%.po}-upstream.po + if ! validate_po ${PO%.po}-upstream.po ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN repository=$REPO directory=$RPMPODIR branch=${BRANCH:(default)} po=$PO: validation error (merged translation), possible plural forms clash" + exit + fi + else + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN repository=$REPO directory=$RPMPODIR branch=${BRANCH:(default)} po=$PO: validation error (merged translation)" + exit + fi + fi + else + cp -a ${PO%.po}-backport.po~ ${PO%.po}-upstream.po + fi + # step 3: Join both translations, without --use-first string changes will disappear as fuzzy. + msgcat --force-po ${PO%.po}-upstream.po $RPMPODIR/${PO%.po}-downstream.po -o ${PO%.po}-allfz.po + msgcat --use-first --force-po ${PO%.po}-upstream.po $RPMPODIR/${PO%.po}-downstream.po -o ${PO%.po}-all.po + # step 4: Find string fixes (existed before, now different). + msgcat --force-po --unique ${PO%.po}-all.po ${PO%.po}-allfz.po -o ${PO%.po}-fixes.po~ + # step 5: Find newly translated strings (translation removal is not supported). + msgcat --force-po --unique $RPMPODIR/${PO%.po}-downstream.po ${PO%.po}-all.po -o ${PO%.po}-additions.po~ + # step 6: Join both to collect all known fixes. + if $OLD_UPDATE ; then + # If the update has an old time stamp, don't include fixes. Use just additions. + msgcat ${PO%.po}-additions.po~ -o $RPMPODIR/${PO%.po}-updatesraw.po + # "updatesraw" can have inconsistent plural forms even if "upstream" has them consistent (bsc#894913). + # Other failures are not possible here (superset was already validated). + if ! validate_po_with_plural_check ${PO%.po}-updatesraw.po ; then + # => There is no chance that --old-plural-forms succeeds. Don't try it and fail. + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN repository=$REPO directory=$RPMPODIR branch=${BRANCH:(default)} po=$PO: validation error (merged translation additions), possible plural forms clash" + exit + fi + else + msgcat ${PO%.po}-fixes.po~ ${PO%.po}-additions.po~ -o $RPMPODIR/${PO%.po}-updatesraw.po + fi + # Are there any updates? If no, game over. + if test -f $RPMPODIR/${PO%.po}-updatesraw.po ; then + # step 7: Compose the best po file header. + if $PLURAL_FAILURE ; then + $WORK_DIR/msgheadermerge $RPMPODIR/$PO ${PO%.po}-upstream.po ${PO%.po}-header.po --newdate "" --old-plural-forms + else + $WORK_DIR/msgheadermerge $RPMPODIR/$PO ${PO%.po}-upstream.po ${PO%.po}-header.po --newdate + fi + # step 8: And yet another ugly game to get rid commented out garbage. + msgattrib --no-obsolete --force-po $RPMPODIR/${PO%.po}-updatesraw.po -o $RPMPODIR/${PO%.po}-updates.po~ + # step 9: Merge correct header to the updates file. + msgcat --no-location --use-first ${PO%.po}-header.po $RPMPODIR/${PO%.po}-updates.po~ -o $RPMPODIR/${PO%.po}-updates.po + fi + # Prepare po-full file. + mkdir -p $WORK_DIR/po-full/$REAL_DOMAIN + if $OLD_UPDATE ; then + $WORK_DIR/msgheadermerge ${PO%.po}-upstream.po $RPMPODIR/$PO ${PO%.po}-dheader.po --mergemode --continue + msgcat --use-first --force-po ${PO%.po}-dheader.po $RPMPODIR/${PO%.po}-downstream.po ${PO%.po}-upstream.po -o ${PO%.po}-alldown.po + msgattrib --no-obsolete ${PO%.po}-alldown.po -o $WORK_DIR/po-full/$REAL_DOMAIN/$PO + else + msgattrib --no-obsolete ${PO%.po}-all.po -o $WORK_DIR/po-full/$REAL_DOMAIN/$PO + fi + # step 10: Prepare texts for review. We created them in previous steps, but files need cleanup. + if test -f ${PO%.po}-header.po ; then + if test -f ${PO%.po}-additions.po~ ; then + msgattrib --no-obsolete --force-po ${PO%.po}-additions.po~ -o ${PO%.po}-additions.po + mkdir -p $WORK_DIR/po-review/${PO%.po}/additions + msgcat --use-first ${PO%.po}-header.po ${PO%.po}-additions.po -o $WORK_DIR/po-review/${PO%.po}/additions/$REAL_DOMAIN.po + rmdir --ignore-fail-on-non-empty --parents $WORK_DIR/po-review/${PO%.po}/additions + fi + if test -f ${PO%.po}-fixes.po~ ; then + msgattrib --no-obsolete --force-po ${PO%.po}-fixes.po~ -o ${PO%.po}-fixes.po + msgcat --use-first ${PO%.po}-header.po ${PO%.po}-fixes.po -o ${PO%.po}-fixes-clean.po + fi + if test -f ${PO%.po}-fixes-clean.po ; then + msgmerge ${PO%.po}-allfz.po ${PO%.po}-fixes-clean.po -o ${PO%.po}-fixes-review.po~ + msgattrib --no-obsolete --force-po ${PO%.po}-fixes-review.po~ -o ${PO%.po}-fixes-review.po~~ + msgcat ${PO%.po}-fixes-review.po~~ -o ${PO%.po}-fixes-review.po + if $OLD_UPDATE ; then + mkdir -p $WORK_DIR/po-review/${PO%.po}/excluded-changes/${REPO//[\/:.]/_}/$REPODIR + cp -a ${PO%.po}-fixes-clean.po $WORK_DIR/po-review/${PO%.po}/excluded-changes/${REPO//[\/:.]/_}/$REPODIR/$REAL_DOMAIN.po + cp -a ${PO%.po}-fixes-review.po $WORK_DIR/po-review/${PO%.po}/excluded-changes/${REPO//[\/:.]/_}/$REPODIR/$REAL_DOMAIN-review.po + rmdir --ignore-fail-on-non-empty --parents $WORK_DIR/po-review/${PO%.po}/excluded-changes/${REPO//[\/:.]/_}/$REPODIR + if test -d $WORK_DIR/po-review/${PO%.po}/excluded-changes ; then + echo -e "Excluded changes contains changes introduced by upstream po files with\ntime stamp older than our package." >$WORK_DIR/po-review/${PO%.po}/excluded-changes/README + fi + else + mkdir -p $WORK_DIR/po-review/${PO%.po}/changes + cp -a ${PO%.po}-fixes-clean.po $WORK_DIR/po-review/${PO%.po}/changes/$REAL_DOMAIN.po + cp -a ${PO%.po}-fixes-review.po $WORK_DIR/po-review/${PO%.po}/changes/$REAL_DOMAIN-review.po + rmdir --ignore-fail-on-non-empty --parents $WORK_DIR/po-review/${PO%.po}/changes + fi + fi + fi + else + # Test is not needed in current msgmerge, file is generated even if there is nothing inside. + if test -f ${PO%.po}-backport.po~ ; then + # step 1: Merge new po and previous updates (if any). + msgattrib --no-obsolete --no-fuzzy --translated ${PO%.po}-backport.po~ -o ${PO%.po}-backport.po + if ! test -f ${PO%.po}-backport.po ; then + # backport file does not contain anything useful + exit + fi + if test -f $RPMPODIR/${PO%.po}-updates.po ; then + if ! msgcat --force-po --use-first ${PO%.po}-backport.po $RPMPODIR/${PO%.po}-updates.po -o $RPMPODIR/${PO%.po}-updates.po~ ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)} po=$PO: msgcat error" + exit + fi + mv $RPMPODIR/${PO%.po}-updates.po~ $RPMPODIR/${PO%.po}-updates.po + else + # To get surely a valid po file, use msgcat instead of cp. + if ! msgcat ${PO%.po}-backport.po -o $RPMPODIR/${PO%.po}-updates.po ; then + echo >>$WORK_DIR/upstream-collect.log "package=$PACKAGE domain=$DOMAIN gettext-package=$REAL_DOMAIN method=$METHOD repository=$REPO directory=$DIR branch=${BRANCH:(default)} po=$PO: msgcat error" + exit + fi + fi + # step 2: Prepare texts for review. + mkdir -p $WORK_DIR/po-review/${PO%.po}/new-files + cp -a $RPMPODIR/${PO%.po}-updates.po $WORK_DIR/po-review/${PO%.po}/new-files/$REAL_DOMAIN.po + rmdir --ignore-fail-on-non-empty --parents $WORK_DIR/po-review/${PO%.po}/new-files + mkdir -p $WORK_DIR/po-full/$REAL_DOMAIN + cp -a $RPMPODIR/${PO%.po}-updates.po $WORK_DIR/po-full/$REAL_DOMAIN/$PO + fi + fi + fi + ) & + if test $CPUS -le 1 ; then + wait + else + echo "JOBS: New job launched." + SHOWME=true + while test $(jobs -p | wc -l) -ge $CPUS ; do + if $SHOWME ; then + echo -n "JOBS: $CPUS jobs running. Will check later~" + SHOWME=false + else + echo -n "~" + fi + sleep 3 + done + fi + if ! $SHOWME ; then + echo "JOBS: Releasing." + fi + done + if test $CPUS -gt 1 ; then + echo "JOBS: All tasks launched. Waiting for results." + wait + fi + + mkdir -p $WORK_DIR/UPDATE/po/$REAL_DOMAIN + cd $RPMPODIR + for POX in *-updates.po ; do + PO=${POX/-updates/} + cp -a $POX $WORK_DIR/UPDATE/po/$REAL_DOMAIN/$PO + done + + if ! $DEBUG ; then + rm -rf $WORK_DIR/UPSTREAM/$SERIAL + fi + + fi + + mkdir -p $WORK_DIR/STAMPS/$PACKAGE/$DOMAIN/$METHOD/${REPO//[\/:.]/_}/$DIR/${BRANCH:-__HEAD__} + touch $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok + + done +done + +if ! $DEBUG ; then + if test -n "$RPMPKGDIR" ; then + rm -rf $RPMPKGDIR $WORK_DIR/STAMPS/$PACKAGE/.builddir_ok + fi +fi + +if $COLLECT_UPSTREAM ; then + cd $WORK_DIR/UPDATE + if test -d po ; then + tar -j -c -f $WORK_DIR/translation-update-upstream-$SNAPSHOT.tar.bz2 po + fi + if test -d po-mandatory ; then + tar -j -c -f $WORK_DIR/translation-update-mandatory-$MSNAPSHOT.tar.bz2 po-mandatory + fi +fi + +if $FULL_PROCESS ; then + # FIXME: Partial process should be able to update corresponding parts of domain-map. + echo >$WORK_DIR/upstream-collect.domain-map "# This file was generated $(LANG=C LC_ALL=C date) by upstream-collect.sh." + LC_ALL=C LANG=C sort -u <$WORK_DIR/upstream-collect.domain-map.tmp >>$WORK_DIR/upstream-collect.domain-map + rm $WORK_DIR/upstream-collect.domain-map.tmp +fi + +cd $WORK_DIR +if ! $DEBUG ; then + rm -rf UPSTREAM OSC PACKAGES UPDATE UPDATE_OLD STAMPS BIN translation-update-static +fi +rm -rf ~/.upstream-collect.tmp + +echo "" +echo "$(tput setf 2)Done. Please update version date in the spec file.$(tput init)" diff --git a/upstream-gnome_gtp-not-on-media.tlst b/upstream-gnome_gtp-not-on-media.tlst new file mode 100644 index 0000000..cd8ef59 --- /dev/null +++ b/upstream-gnome_gtp-not-on-media.tlst @@ -0,0 +1,6 @@ +# Resources on GNOME GTP that are not on DVD, and thus not found by create-tlst-step2-create-gnome_gtp.sh. +# package domain method repository dir branch +gnome-themes gnome-themes gtp l10n.gnome.org/POT gnome-themes/po +#NOT-IN-SLE: lasem lasem-0.4 gtp l10n.gnome.org/POT lasem/po +libepc libepc gtp l10n.gnome.org/POT libepc/po +#NOT-IN-SLE: shotwell shotwell-extras gtp l10n.gnome.org/POT shotwell/po diff --git a/upstream-gnome_gtp.hook b/upstream-gnome_gtp.hook new file mode 100644 index 0000000..65c8b73 --- /dev/null +++ b/upstream-gnome_gtp.hook @@ -0,0 +1,19 @@ +#!/bin/bash +if test -z "$PACKAGE" ; then + echo "This is a hook file for upstream-collect.sh. It cannot be called separately." + exit 255 +fi + +# For other versions than sles10: +# Hack for nm-applet, which uses different hierrarchy than upstream: +#if test $DOMAIN = nm-applet ; then +# RPMPODIR=$(echo $RPMPKGDIR/BUILD/*/nm-applet-*/${DIR#*/}) +#fi +# Hack for banshee and beagle, strangely placed to svn +#if test $DOMAIN = banshee-1 ; then +# REPODIR=banshee/banshee/po +#fi +# Hack for gnome-themes, which bundles several projects in SuSE: +if test $DOMAIN = gnome-themes ; then + RPMPODIR=$(echo $RPMPKGDIR/BUILD/gnome-themes-*/${DIR#*/}) +fi diff --git a/upstream-gnome_gtp.tlst b/upstream-gnome_gtp.tlst new file mode 100644 index 0000000..0ff79c0 --- /dev/null +++ b/upstream-gnome_gtp.tlst @@ -0,0 +1,214 @@ +# This file was generated Sun Mar 29 03:21:28 CEST 2020 by create-tlst-step2-create-gnome_gtp.sh. +# package domain method repository dir branch +AppStream appstream gtp l10n.gnome.org/POT appstream/po +ModemManager ModemManager gtp l10n.gnome.org/POT ModemManager/po +NetworkManager NetworkManager gtp l10n.gnome.org/POT NetworkManager/po +NetworkManager-applet nm-applet gtp l10n.gnome.org/POT network-manager-applet/po +NetworkManager-openconnect NetworkManager-openconnect gtp l10n.gnome.org/POT NetworkManager-openconnect/po +NetworkManager-openvpn NetworkManager-openvpn gtp l10n.gnome.org/POT NetworkManager-openvpn/po +NetworkManager-pptp NetworkManager-pptp gtp l10n.gnome.org/POT NetworkManager-pptp/po +PackageKit PackageKit gtp l10n.gnome.org/POT PackageKit/po +PackageKit PackageKit gtp l10n.gnome.org/POT packagekit/po +accountsservice accounts-service gtp l10n.gnome.org/POT accountsservice/po +alacarte alacarte gtp l10n.gnome.org/POT alacarte/po +appstream-glib appstream-glib gtp l10n.gnome.org/POT appstream-glib/po +at-spi2-core at-spi2-core gtp l10n.gnome.org/POT at-spi2-core/po gnome-3-34 +at-spi2-core at-spi2-core gtp l10n.gnome.org/POT at-spi2-core/po +atk atk10 gtp l10n.gnome.org/POT atk/po gnome-3-34 +atk atk10 gtp l10n.gnome.org/POT atk/po +avahi avahi gtp l10n.gnome.org/POT avahi/po +baobab baobab gtp l10n.gnome.org/POT baobab/po gnome-3-34 +baobab baobab gtp l10n.gnome.org/POT baobab/po +brasero brasero gtp l10n.gnome.org/POT brasero/po +caribou caribou gtp l10n.gnome.org/POT caribou/po +cheese cheese gtp l10n.gnome.org/POT cheese/po +clutter clutter-1.0 gtp l10n.gnome.org/POT clutter/po +clutter-gtk cluttergtk-1.0 gtp l10n.gnome.org/POT clutter-gtk/po +cogl cogl gtp l10n.gnome.org/POT cogl/po +colord colord gtp l10n.gnome.org/POT colord/po +cups-pk-helper cups-pk-helper gtp l10n.gnome.org/POT cups-pk-helper/po +dasher dasher gtp l10n.gnome.org/POT dasher/po +dconf-editor dconf-editor gtp l10n.gnome.org/POT dconf-editor/po gnome-3-34 +dconf-editor dconf-editor gtp l10n.gnome.org/POT dconf-editor/po gnome-3-36 +dconf-editor dconf-editor gtp l10n.gnome.org/POT dconf-editor/po +devhelp devhelp gtp l10n.gnome.org/POT devhelp/po gnome-3-34 +devhelp devhelp gtp l10n.gnome.org/POT devhelp/po +dia dia gtp l10n.gnome.org/POT dia/po +ekiga ekiga gtp l10n.gnome.org/POT ekiga/po +eog eog gtp l10n.gnome.org/POT eog/po gnome-3-34 +eog eog gtp l10n.gnome.org/POT eog/po +evince evince gtp l10n.gnome.org/POT evince/po gnome-3-34 +evince evince gtp l10n.gnome.org/POT evince/po +evolution evolution gtp l10n.gnome.org/POT evolution/po gnome-3-34 +evolution evolution gtp l10n.gnome.org/POT evolution/po gnome-3-36 +evolution evolution gtp l10n.gnome.org/POT evolution/po +evolution-data-server evolution-data-server gtp l10n.gnome.org/POT evolution-data-server/po gnome-3-34 +evolution-data-server evolution-data-server gtp l10n.gnome.org/POT evolution-data-server/po gnome-3-36 +evolution-data-server evolution-data-server gtp l10n.gnome.org/POT evolution-data-server/po +evolution-ews evolution-ews gtp l10n.gnome.org/POT evolution-ews/po gnome-3-34 +evolution-ews evolution-ews gtp l10n.gnome.org/POT evolution-ews/po gnome-3-36 +evolution-ews evolution-ews gtp l10n.gnome.org/POT evolution-ews/po +file-roller file-roller gtp l10n.gnome.org/POT file-roller/po +flatpak flatpak gtp l10n.gnome.org/POT flatpak/po +folks folks gtp l10n.gnome.org/POT folks/po +fwupd fwupd gtp l10n.gnome.org/POT fwupd/po +gcab gcab gtp l10n.gnome.org/POT gcab/po +gconf2 GConf2 gtp l10n.gnome.org/POT gconf/po +gcr gcr gtp l10n.gnome.org/POT gcr/po gnome-3-34 +gcr gcr gtp l10n.gnome.org/POT gcr/po gnome-3-36 +gcr gcr gtp l10n.gnome.org/POT gcr/po +gdk-pixbuf gdk-pixbuf gtp l10n.gnome.org/POT gdk-pixbuf/po +gdm gdm gtp l10n.gnome.org/POT gdm/po +gedit gedit gtp l10n.gnome.org/POT gedit/po gnome-3-34 +gedit gedit gtp l10n.gnome.org/POT gedit/po gnome-3-36 +gedit gedit gtp l10n.gnome.org/POT gedit/po +ghex ghex-3.0 gtp l10n.gnome.org/POT ghex/po +gimp gimp20 gtp l10n.gnome.org/POT gimp/po gimp-2-10 +gimp gimp20 gtp l10n.gnome.org/POT gimp/po +gimp gimp20-libgimp gtp l10n.gnome.org/POT gimp/po-libgimp gimp-2-10 +gimp gimp20-libgimp gtp l10n.gnome.org/POT gimp/po-libgimp +gimp gimp20-python gtp l10n.gnome.org/POT gimp/po-python gimp-2-10 +gimp gimp20-python gtp l10n.gnome.org/POT gimp/po-python +gimp gimp20-script-fu gtp l10n.gnome.org/POT gimp/po-script-fu gimp-2-10 +gimp gimp20-script-fu gtp l10n.gnome.org/POT gimp/po-script-fu +gimp gimp20-std-plug-ins gtp l10n.gnome.org/POT gimp/po-plug-ins gimp-2-10 +gimp gimp20-std-plug-ins gtp l10n.gnome.org/POT gimp/po-plug-ins +gimp gimp20-tips gtp l10n.gnome.org/POT gimp/po-tips gimp-2-10 +gimp gimp20-tips gtp l10n.gnome.org/POT gimp/po-tips +glade glade gtp l10n.gnome.org/POT glade/po +glib-networking glib-networking gtp l10n.gnome.org/POT glib-networking/po +glib2 glib20 gtp l10n.gnome.org/POT glib/po +gnome-bluetooth gnome-bluetooth2 gtp l10n.gnome.org/POT gnome-bluetooth/po +gnome-builder gnome-builder gtp l10n.gnome.org/POT gnome-builder/po +gnome-calculator gnome-calculator gtp l10n.gnome.org/POT gnome-calculator/po gnome-3-34 +gnome-calculator gnome-calculator gtp l10n.gnome.org/POT gnome-calculator/po +gnome-characters org.gnome.Characters gtp l10n.gnome.org/POT gnome-characters/po +gnome-clocks gnome-clocks gtp l10n.gnome.org/POT gnome-clocks/po gnome-3-34 +gnome-clocks gnome-clocks gtp l10n.gnome.org/POT gnome-clocks/po gnome-3-36 +gnome-clocks gnome-clocks gtp l10n.gnome.org/POT gnome-clocks/po +gnome-color-manager gnome-color-manager gtp l10n.gnome.org/POT gnome-color-manager/po +gnome-contacts gnome-contacts gtp l10n.gnome.org/POT gnome-contacts/po gnome-3-34 +gnome-contacts gnome-contacts gtp l10n.gnome.org/POT gnome-contacts/po gnome-3-36 +gnome-contacts gnome-contacts gtp l10n.gnome.org/POT gnome-contacts/po +gnome-control-center gnome-control-center-2.0 gtp l10n.gnome.org/POT gnome-control-center/po gnome-3-34 +gnome-control-center gnome-control-center-2.0 gtp l10n.gnome.org/POT gnome-control-center/po gnome-3-36 +gnome-control-center gnome-control-center-2.0 gtp l10n.gnome.org/POT gnome-control-center/po +gnome-control-center gnome-control-center-2.0-timezones gtp l10n.gnome.org/POT gnome-control-center/po gnome-3-34 +gnome-control-center gnome-control-center-2.0-timezones gtp l10n.gnome.org/POT gnome-control-center/po gnome-3-36 +gnome-control-center gnome-control-center-2.0-timezones gtp l10n.gnome.org/POT gnome-control-center/po +gnome-desktop gnome-desktop-3.0 gtp l10n.gnome.org/POT gnome-desktop/po gnome-3-34 +gnome-desktop gnome-desktop-3.0 gtp l10n.gnome.org/POT gnome-desktop/po gnome-3-36 +gnome-desktop gnome-desktop-3.0 gtp l10n.gnome.org/POT gnome-desktop/po +gnome-disk-utility gnome-disk-utility gtp l10n.gnome.org/POT gnome-disk-utility/po gnome-3-34 +gnome-disk-utility gnome-disk-utility gtp l10n.gnome.org/POT gnome-disk-utility/po gnome-3-36 +gnome-disk-utility gnome-disk-utility gtp l10n.gnome.org/POT gnome-disk-utility/po +gnome-documents gnome-documents gtp l10n.gnome.org/POT gnome-documents/po +gnome-initial-setup gnome-initial-setup gtp l10n.gnome.org/POT gnome-initial-setup/po gnome-3-34 +gnome-initial-setup gnome-initial-setup gtp l10n.gnome.org/POT gnome-initial-setup/po gnome-3-36 +gnome-initial-setup gnome-initial-setup gtp l10n.gnome.org/POT gnome-initial-setup/po +gnome-keyring gnome-keyring gtp l10n.gnome.org/POT gnome-keyring/po gnome-3-34 +gnome-keyring gnome-keyring gtp l10n.gnome.org/POT gnome-keyring/po +gnome-logs gnome-logs gtp l10n.gnome.org/POT gnome-logs/po +gnome-menus gnome-menus gtp l10n.gnome.org/POT gnome-menus/po +gnome-music org.gnome.Music gtp l10n.gnome.org/POT gnome-music/po gnome-3-34 +gnome-music org.gnome.Music gtp l10n.gnome.org/POT gnome-music/po gnome-3-36 +gnome-music org.gnome.Music gtp l10n.gnome.org/POT gnome-music/po +gnome-online-accounts gnome-online-accounts gtp l10n.gnome.org/POT gnome-online-accounts/po gnome-3-34 +gnome-online-accounts gnome-online-accounts gtp l10n.gnome.org/POT gnome-online-accounts/po gnome-3-36 +gnome-online-accounts gnome-online-accounts gtp l10n.gnome.org/POT gnome-online-accounts/po +gnome-packagekit gnome-packagekit gtp l10n.gnome.org/POT gnome-packagekit/po +gnome-photos gnome-photos gtp l10n.gnome.org/POT gnome-photos/po gnome-3-34 +gnome-photos gnome-photos gtp l10n.gnome.org/POT gnome-photos/po +gnome-power-manager gnome-power-manager gtp l10n.gnome.org/POT gnome-power-manager/po +gnome-screenshot gnome-screenshot gtp l10n.gnome.org/POT gnome-screenshot/po gnome-3-36 +gnome-screenshot gnome-screenshot gtp l10n.gnome.org/POT gnome-screenshot/po +gnome-session gnome-session-3.0 gtp l10n.gnome.org/POT gnome-session/po gnome-3-34 +gnome-session gnome-session-3.0 gtp l10n.gnome.org/POT gnome-session/po +gnome-settings-daemon gnome-settings-daemon gtp l10n.gnome.org/POT gnome-settings-daemon/po gnome-3-34 +gnome-settings-daemon gnome-settings-daemon gtp l10n.gnome.org/POT gnome-settings-daemon/po +gnome-shell gnome-shell gtp l10n.gnome.org/POT gnome-shell/po gnome-3-34 +gnome-shell gnome-shell gtp l10n.gnome.org/POT gnome-shell/po +gnome-software gnome-software gtp l10n.gnome.org/POT gnome-software/po gnome-3-34 +gnome-software gnome-software gtp l10n.gnome.org/POT gnome-software/po +gnome-system-monitor gnome-system-monitor gtp l10n.gnome.org/POT gnome-system-monitor/po gnome-3-34 +gnome-system-monitor gnome-system-monitor gtp l10n.gnome.org/POT gnome-system-monitor/po +gnome-terminal gnome-terminal gtp l10n.gnome.org/POT gnome-terminal/po gnome-3-34 +gnome-terminal gnome-terminal gtp l10n.gnome.org/POT gnome-terminal/po gnome-3-36 +gnome-terminal gnome-terminal gtp l10n.gnome.org/POT gnome-terminal/po +gnome-weather org.gnome.Weather gtp l10n.gnome.org/POT gnome-weather/po gnome-3-34 +gnome-weather org.gnome.Weather gtp l10n.gnome.org/POT gnome-weather/po +gnote gnote gtp l10n.gnome.org/POT gnote/po gnome-3-34 +gnote gnote gtp l10n.gnome.org/POT gnote/po +grilo grilo gtp l10n.gnome.org/POT grilo/po +grilo-plugins grilo-plugins gtp l10n.gnome.org/POT grilo-plugins/po +gsettings-desktop-schemas gsettings-desktop-schemas gtp l10n.gnome.org/POT gsettings-desktop-schemas/po gnome-3-34 +gsettings-desktop-schemas gsettings-desktop-schemas gtp l10n.gnome.org/POT gsettings-desktop-schemas/po +gspell gspell-1 gtp l10n.gnome.org/POT gspell/po +gstreamer gstreamer-1.0 gtp l10n.gnome.org/POT gstreamer/po +gtk-vnc gtk-vnc gtp l10n.gnome.org/POT gtk-vnc/po +gtk2 gtk20 gtp l10n.gnome.org/POT gtk+/po gtk-2-24 +gtk2 gtk20 gtp l10n.gnome.org/POT gtk+/po +gtk2 gtk20-properties gtp l10n.gnome.org/POT gtk+/po-properties gtk-2-24 +gtk2 gtk20-properties gtp l10n.gnome.org/POT gtk+/po-properties +gtk3 gtk30 gtp l10n.gnome.org/POT gtk+/po gtk-3-24 +gtk3 gtk30 gtp l10n.gnome.org/POT gtk+/po +gtk3 gtk30-properties gtp l10n.gnome.org/POT gtk+/po gtk-3-24 +gtk3 gtk30-properties gtp l10n.gnome.org/POT gtk+/po +gtksourceview gtksourceview-3.0 gtp l10n.gnome.org/POT gtksourceview/po +gvfs gvfs gtp l10n.gnome.org/POT gvfs/po gnome-3-34 +gvfs gvfs gtp l10n.gnome.org/POT gvfs/po +json-glib json-glib-1.0 gtp l10n.gnome.org/POT json-glib/po +libcryptui cryptui gtp l10n.gnome.org/POT libcryptui/po +libgdata gdata gtp l10n.gnome.org/POT libgdata/po +libgnome-keyring libgnome-keyring gtp l10n.gnome.org/POT libgnome-keyring/po +libgnomekbd libgnomekbd gtp l10n.gnome.org/POT libgnomekbd/po +libgsf libgsf gtp l10n.gnome.org/POT libgsf/po +libgtop libgtop gtp l10n.gnome.org/POT libgtop/po +libgweather libgweather-3.0 gtp l10n.gnome.org/POT libgweather/po gnome-3-34 +libgweather libgweather-3.0 gtp l10n.gnome.org/POT libgweather/po gnome-3-36 +libgweather libgweather-3.0 gtp l10n.gnome.org/POT libgweather/po +libgweather libgweather-locations gtp l10n.gnome.org/POT libgweather/po-locations gnome-3-34 +libgweather libgweather-locations gtp l10n.gnome.org/POT libgweather/po-locations gnome-3-36 +libgweather libgweather-locations gtp l10n.gnome.org/POT libgweather/po-locations +libpeas libpeas-1.0 gtp l10n.gnome.org/POT libpeas/po +libsecret libsecret gtp l10n.gnome.org/POT libsecret/po +libsoup libsoup gtp l10n.gnome.org/POT libsoup/po gnome-3-34 +libsoup libsoup gtp l10n.gnome.org/POT libsoup/po +libwnck libwnck-3.0 gtp l10n.gnome.org/POT libwnck/po +meld meld gtp l10n.gnome.org/POT meld/po +mousetweaks mousetweaks gtp l10n.gnome.org/POT mousetweaks/po +mutter mutter gtp l10n.gnome.org/POT mutter/po gnome-3-34 +mutter mutter gtp l10n.gnome.org/POT mutter/po +nautilus nautilus gtp l10n.gnome.org/POT nautilus/po gnome-3-34 +nautilus nautilus gtp l10n.gnome.org/POT nautilus/po gnome-3-36 +nautilus nautilus gtp l10n.gnome.org/POT nautilus/po +orca orca gtp l10n.gnome.org/POT orca/po gnome-3-34 +orca orca gtp l10n.gnome.org/POT orca/po gnome-3-36 +orca orca gtp l10n.gnome.org/POT orca/po +plymouth plymouth gtp l10n.gnome.org/POT plymouth/po +polkit polkit-1 gtp l10n.gnome.org/POT polkit/po +pulseaudio pulseaudio gtp l10n.gnome.org/POT PulseAudio/po +pulseaudio pulseaudio gtp l10n.gnome.org/POT Pulseaudio/po +seahorse seahorse gtp l10n.gnome.org/POT seahorse/po gnome-3-34 +seahorse seahorse gtp l10n.gnome.org/POT seahorse/po gnome-3-36 +seahorse seahorse gtp l10n.gnome.org/POT seahorse/po +shared-mime-info shared-mime-info gtp l10n.gnome.org/POT shared-mime-info/po +simple-scan simple-scan gtp l10n.gnome.org/POT simple-scan/po gnome-3-34 +simple-scan simple-scan gtp l10n.gnome.org/POT simple-scan/po gnome-3-36 +simple-scan simple-scan gtp l10n.gnome.org/POT simple-scan/po +systemd systemd gtp l10n.gnome.org/POT systemd/po +totem totem gtp l10n.gnome.org/POT totem/po gnome-3-34 +totem totem gtp l10n.gnome.org/POT totem/po +totem-pl-parser totem-pl-parser gtp l10n.gnome.org/POT totem-pl-parser/po +tracker tracker gtp l10n.gnome.org/POT tracker/po +tracker-miners tracker-miners gtp l10n.gnome.org/POT tracker-miners/po +udisks2 udisks2 gtp l10n.gnome.org/POT udisks/po +vino vino gtp l10n.gnome.org/POT vino/po +vte vte-2.91 gtp l10n.gnome.org/POT vte/po +xdg-desktop-portal xdg-desktop-portal gtp l10n.gnome.org/POT xdg-desktop-portal/po +xdg-desktop-portal-gtk xdg-desktop-portal-gtk gtp l10n.gnome.org/POT xdg-desktop-portal-gtk/po +xdg-user-dirs xdg-user-dirs gtp l10n.gnome.org/POT xdg-user-dirs/po +xdg-user-dirs-gtk xdg-user-dirs-gtk gtp l10n.gnome.org/POT xdg-user-dirs-gtk/po +xkeyboard-config xkeyboard-config gtp l10n.gnome.org/POT xkeyboard-config/po +yelp yelp gtp l10n.gnome.org/POT yelp/po +zenity zenity gtp l10n.gnome.org/POT zenity/po