The first patch adds a test that will fail if xgettext displays warnings while processing anything in POTFILES. The warnings about undetected language types are fixed in the second patch, and the warnings about unparameterized strings are fixed in the third.
The second patch also fixes our handling of glade files. xgettext sort of supports glade but doesn't very well with glade3, and for that reason we had some makefile rules to use intltool to extract strings. Except we were only looking for glade files in one directory and then never using the generated headers. This fixes that.
I reorganized POTFILES.in a little bit, so the .pot file will look it changed it a lot because all of the anaconda strings are at the bottom now. The filename comments in the .pot should be the same for the files that force a language in Rules-extract (anaconda, data/liveinst/gnome/fedora-welcome), but it will change for the files that switch to intltool generated headers (*.glade, fedora-welcome.desktop.in).
--- tests/Makefile.am | 2 ++ tests/gettext/gettext_warnings.sh | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100755 tests/gettext/gettext_warnings.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am index eb2b98b..3a0fc94 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -41,8 +41,10 @@ dist_check_SCRIPTS = accelerators/check_accelerators.py \ nosetests.sh \ pylint/runpylint.sh \ testenv.sh \ + gettext/gettext_warnings.sh \ $(srcdir)/*_tests/*.py
TESTS = nosetests.sh \ pylint/runpylint.sh \ + gettext/gettext_warnings.sh \ accelerators/run_check_accelerators.sh diff --git a/tests/gettext/gettext_warnings.sh b/tests/gettext/gettext_warnings.sh new file mode 100755 index 0000000..5eaffbe --- /dev/null +++ b/tests/gettext/gettext_warnings.sh @@ -0,0 +1,32 @@ +#!/bin/sh -e + +: "${top_srcdir:=$(dirname "$0")/../..}" +podir="${top_srcdir}/po" + +# Extract XGETTEXT_OPTIONS from po/Makevars +XGETTEXT_OPTIONS="$(sed -n 's/^[[:space:]]*XGETTEXT_OPTIONS[[:space:]]*=[[:space:]]*(.*)/\1/p' \ + "${podir}/Makevars")" + +status=0 +# For each file in POTFILES, run xgettext and look for warnings +while read -r potfile ; do + # Strip the spaces and trailing backslash + potfile="$(echo "$potfile" | sed 's/^[[:space:]]*([^[:space:]]*)[[:space:]]*\?$/\1/')" + + # $potfile is relative to the po/ directory, $test_potfile is + # relative to this script's working directory + test_potfile="${podir}/${potfile}" + + # If the file doesn't exist, try to make it + if [ ! -f "$test_potfile" ]; then + make -C "${podir}" "${potfile}" || exit 1 + fi + + xgettext_output="$(xgettext ${XGETTEXT_OPTIONS} -o /dev/null "$test_potfile" 2>&1)" || status=1 + if echo "$xgettext_output" | fgrep -q 'warning:' ; then + echo "$xgettext_output" + status=1 + fi +done < "${top_srcdir}/po/POTFILES" + +exit "$status"
This combines the Rules-glade and Rules-liveinst into one file and modifies the rules that they work with all of our various glade and liveinst paths. Update POTFILES.in to point to the generated files so that xgettext doesn't try to process the source files directly.
For files that xgettext can handle but can't autodetect the type, manually extract strings into a .po file. xgettext can import .po files into the .pot and knows to leave the file names and line numbers alone. --- .gitignore | 3 +++ configure.ac | 1 + po/POTFILES.in | 68 ++++++++++++++++++++++++++++++------------------------ po/Rules-glade | 11 --------- po/Rules-liveinst | 17 -------------- po/tmpl-extract.in | 54 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 96 insertions(+), 58 deletions(-) delete mode 100644 po/Rules-glade delete mode 100644 po/Rules-liveinst create mode 100644 po/tmpl-extract.in
diff --git a/.gitignore b/.gitignore index c076307..d60c514 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,7 @@ po/Makefile.in.in po/Makevars.template po/POTFILES po/Rules-quot +po/Rules-extract po/boldquot.sed po/en@boldquot.insert-header po/en@boldquot.header @@ -85,3 +86,5 @@ widgets/doc/html widgets/doc/xml widgets/gtk-doc.make widgets/src/gettext.h +anaconda.po +data/liveinst/gnome/fedora-welcome.po diff --git a/configure.ac b/configure.ac index 0da79ad..4237506 100644 --- a/configure.ac +++ b/configure.ac @@ -223,6 +223,7 @@ AC_CONFIG_FILES([Makefile data/icons/hicolor/256x256/apps/Makefile data/systemd/Makefile po/Makefile.in + po/Rules-extract:po/tmpl-extract.in scripts/Makefile pyanaconda/Makefile pyanaconda/isys/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index 4820137..90ce6e4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,7 +2,6 @@ # Copyright (C) 2009 Red Hat, Inc.
# Main anaconda source files -anaconda pyanaconda/bootloader.py pyanaconda/constants.py pyanaconda/image.py @@ -82,32 +81,6 @@ pyanaconda/ui/gui/spokes/lib/refresh.py pyanaconda/ui/gui/spokes/lib/resize.py pyanaconda/ui/gui/spokes/lib/summary.py
-# Interface files. -pyanaconda/ui/gui/spokes/advanced_user.glade -pyanaconda/ui/gui/spokes/datetime_spoke.glade -pyanaconda/ui/gui/spokes/filter.glade -pyanaconda/ui/gui/spokes/network.glade -pyanaconda/ui/gui/spokes/software.glade -pyanaconda/ui/gui/spokes/storage.glade -pyanaconda/ui/gui/spokes/keyboard.glade -pyanaconda/ui/gui/spokes/langsupport.glade -pyanaconda/ui/gui/spokes/password.glade -pyanaconda/ui/gui/spokes/source.glade -pyanaconda/ui/gui/spokes/welcome.glade -pyanaconda/ui/gui/spokes/user.glade -pyanaconda/ui/gui/spokes/custom.glade -pyanaconda/ui/gui/spokes/advstorage/fcoe.glade -pyanaconda/ui/gui/spokes/advstorage/iscsi.glade -pyanaconda/ui/gui/spokes/lib/cart.glade -pyanaconda/ui/gui/spokes/lib/detailederror.glade -pyanaconda/ui/gui/spokes/lib/passphrase.glade -pyanaconda/ui/gui/spokes/lib/refresh.glade -pyanaconda/ui/gui/spokes/lib/resize.glade -pyanaconda/ui/gui/spokes/lib/summary.glade -pyanaconda/ui/gui/main.glade -pyanaconda/ui/gui/hubs/summary.glade -pyanaconda/ui/gui/hubs/progress.glade - # Custom widgets. widgets/src/BaseWindow.c widgets/src/DiskOverview.c @@ -122,10 +95,45 @@ widgets/src/glade-adaptor.c widgets/src/lightbox.c widgets/src/tz.c
-# welcome screen for GNOME Shell -data/liveinst/gnome/fedora-welcome -data/liveinst/gnome/fedora-welcome.desktop.in +# For file types that gettext doesn't understand, list <filename>.h and +# use Rules-extract to extract the strings into a C-style header. + +# Interface files. +# gettext doesn't fully support glade3 +pyanaconda/ui/gui/spokes/advanced_user.glade.h +pyanaconda/ui/gui/spokes/datetime_spoke.glade.h +pyanaconda/ui/gui/spokes/filter.glade.h +pyanaconda/ui/gui/spokes/network.glade.h +pyanaconda/ui/gui/spokes/software.glade.h +pyanaconda/ui/gui/spokes/storage.glade.h +pyanaconda/ui/gui/spokes/keyboard.glade.h +pyanaconda/ui/gui/spokes/langsupport.glade.h +pyanaconda/ui/gui/spokes/password.glade.h +pyanaconda/ui/gui/spokes/source.glade.h +pyanaconda/ui/gui/spokes/welcome.glade.h +pyanaconda/ui/gui/spokes/user.glade.h +pyanaconda/ui/gui/spokes/custom.glade.h +pyanaconda/ui/gui/spokes/advstorage/fcoe.glade.h +pyanaconda/ui/gui/spokes/advstorage/iscsi.glade.h +pyanaconda/ui/gui/spokes/lib/cart.glade.h +pyanaconda/ui/gui/spokes/lib/detailederror.glade.h +pyanaconda/ui/gui/spokes/lib/passphrase.glade.h +pyanaconda/ui/gui/spokes/lib/refresh.glade.h +pyanaconda/ui/gui/spokes/lib/resize.glade.h +pyanaconda/ui/gui/spokes/lib/summary.glade.h +pyanaconda/ui/gui/main.glade.h +pyanaconda/ui/gui/hubs/summary.glade.h +pyanaconda/ui/gui/hubs/progress.glade.h
# liveinst source files data/liveinst/liveinst.desktop.in.h data/liveinst/console.apps/liveinst.h + +# welcome screen for GNOME Shell +data/liveinst/gnome/fedora-welcome.desktop.in.h + +# These are files that gettext does understand, but that lack an extension +# for xgettext to detect the language. Use Rules-extract to generate a .po +# that will be imported into the .pot. +anaconda.po +data/liveinst/gnome/fedora-welcome.po diff --git a/po/Rules-glade b/po/Rules-glade deleted file mode 100644 index e3d7308..0000000 --- a/po/Rules-glade +++ /dev/null @@ -1,11 +0,0 @@ -UI_SRCS = $(wildcard $(top_srcdir)/data/ui/*.glade) -UI_HDRS = $(UI_SRCS:.glade=.glade.h) - -%.glade.h: %.glade - @cd $(top_builddir)/data/ui ; \ - intltool-extract -q --type=gettext/glade -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -mostlyclean-glade: - rm -f $(UI_HDRS) diff --git a/po/Rules-liveinst b/po/Rules-liveinst deleted file mode 100644 index b933c3b..0000000 --- a/po/Rules-liveinst +++ /dev/null @@ -1,17 +0,0 @@ -LIVEINST_SRCS = $(top_srcdir)/data/liveinst/liveinst.desktop.in $(top_srcdir)/data/liveinst/console.apps/liveinst -LIVEINST_HDRS = $(top_builddir)/data/liveinst/liveinst.desktop.in.h $(top_builddir)/data/liveinst/console.apps/liveinst.h - -%.desktop.in.h: %.desktop.in - @cd $(top_builddir)/data/liveinst ; \ - intltool-extract -q --type=gettext/keys -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -%liveinst.h: %liveinst - @cd $(top_builddir)/data/liveinst/console.apps ; \ - intltool-extract -q --type=gettext/quoted -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -mostlyclean-liveinst: - rm -f $(LIVEINST_HDRS) diff --git a/po/tmpl-extract.in b/po/tmpl-extract.in new file mode 100644 index 0000000..97b3b8c --- /dev/null +++ b/po/tmpl-extract.in @@ -0,0 +1,54 @@ +# Handle files that xgettext can't handle automatically + +# Pull in autoconf variables not set by gettext +abs_top_srcdir = @abs_top_srcdir@ +abs_top_builddir = @abs_top_builddir@ + +# The intltool-extract invocation looks kind of weird because intltool-extract +# acts kind of weird. It treats the input file list as relative to what it +# thinks $srcdir is, which is either the current directory or the value of the +# undocumented -s parameter. For the output filename, it has two modes: +# --update, the default, will output files in the same directory as the input +# file. --local will output files in a tmp/ directory relative to the current +# working directory. +# +# The path names look weird because everything is relative to $srcdir/po + +%.glade.h: %.glade + @cd $(abs_top_builddir)/$(subdir)/$$(dirname $<) && \ + intltool-extract -q --type=gettext/glade -l -s $(abs_top_srcdir)/$(subdir)/$$(dirname $<) $$(basename $<) && \ + mv tmp/$$(basename $@) . && \ + ( rmdir tmp || exit 0 ) + +%.desktop.in.h: %.desktop.in + cd $(abs_top_builddir)/$(subdir)/$$(dirname $<) && \ + intltool-extract -q --type=gettext/quoted -l -s $(abs_top_srcdir)/$(subdir)/$$(dirname $<) $$(basename $<) && \ + mv tmp/$$(basename $@) . && \ + ( rmdir tmp || exit 0 ) + +%liveinst.h: %liveinst + cd $(abs_top_builddir)/$(subdir)/$$(dirname $<) && \ + intltool-extract -q --type=gettext/quoted -l -s $(abs_top_srcdir)/$(subdir)/$$(dirname $<) $$(basename $<) && \ + mv tmp/$$(basename $@) . && \ + ( rmdir tmp || exit 0 ) + +# Remove the $top_srcdir prefix from files so that xgettext can search for the file +# relative to $top_srcdir and get the path name right in the .po +%anaconda.po: %anaconda + @input_file="$<" && \ + xgettext $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \ + --language=Python -o $@ $${input_file##$(top_srcdir)/} + +# This file is actually JavaScript, but C is close enough +%fedora-welcome.po: %fedora-welcome + @input_file="$<" && \ + xgettext $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \ + --language=C -o $@ $${input_file##$(top_srcdir)/} + +mostlyclean: mostlyclean-extract +mostlyclean-extract: + rm -f Rules-extract \ + $(top_builddir)/anaconda.po $(top_builddir)/data/liveinst/gnome/fedora-welcome.po \ + $(top_builddir)/data/liveinst/console.apps/liveinst.h + find $(top_builddir) ( -name '*.glade.h' -o -name '*.desktop.in.h' ) \ + -exec rm -f {} ;
On 09/10/2013 12:10 PM, David Shea wrote:
+%.desktop.in.h: %.desktop.in
- cd $(abs_top_builddir)/$(subdir)/$$(dirname $<) && \
- intltool-extract -q --type=gettext/quoted -l -s $(abs_top_srcdir)/$(subdir)/$$(dirname $<) $$(basename $<) && \
- mv tmp/$$(basename $@) . && \
- ( rmdir tmp || exit 0 )
Changed --type by accident. This one needs to be gettext/keys.
On 09/10/2013 12:10 PM, David Shea wrote:
diff --git a/po/tmpl-extract.in b/po/tmpl-extract.in new file mode 100644 index 0000000..97b3b8c --- /dev/null +++ b/po/tmpl-extract.in @@ -0,0 +1,54 @@ +# Handle files that xgettext can't handle automatically
+# Pull in autoconf variables not set by gettext +abs_top_srcdir = @abs_top_srcdir@ +abs_top_builddir = @abs_top_builddir@
+# The intltool-extract invocation looks kind of weird because intltool-extract +# acts kind of weird. It treats the input file list as relative to what it +# thinks $srcdir is, which is either the current directory or the value of the +# undocumented -s parameter. For the output filename, it has two modes: +# --update, the default, will output files in the same directory as the input +# file. --local will output files in a tmp/ directory relative to the current +# working directory. +# +# The path names look weird because everything is relative to $srcdir/po
+%.glade.h: %.glade
- @cd $(abs_top_builddir)/$(subdir)/$$(dirname $<) && \
- intltool-extract -q --type=gettext/glade -l -s $(abs_top_srcdir)/$(subdir)/$$(dirname $<) $$(basename $<) && \
- mv tmp/$$(basename $@) . && \
- ( rmdir tmp || exit 0 )
+%.desktop.in.h: %.desktop.in
- cd $(abs_top_builddir)/$(subdir)/$$(dirname $<) && \
- intltool-extract -q --type=gettext/quoted -l -s $(abs_top_srcdir)/$(subdir)/$$(dirname $<) $$(basename $<) && \
- mv tmp/$$(basename $@) . && \
- ( rmdir tmp || exit 0 )
+%liveinst.h: %liveinst
- cd $(abs_top_builddir)/$(subdir)/$$(dirname $<) && \
- intltool-extract -q --type=gettext/quoted -l -s $(abs_top_srcdir)/$(subdir)/$$(dirname $<) $$(basename $<) && \
- mv tmp/$$(basename $@) . && \
- ( rmdir tmp || exit 0 )
+# Remove the $top_srcdir prefix from files so that xgettext can search for the file +# relative to $top_srcdir and get the path name right in the .po +%anaconda.po: %anaconda
- @input_file="$<" && \
- xgettext $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \
--language=Python -o $@ $${input_file##$(top_srcdir)/}+# This file is actually JavaScript, but C is close enough +%fedora-welcome.po: %fedora-welcome
- @input_file="$<" && \
- xgettext $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \
--language=C -o $@ $${input_file##$(top_srcdir)/}+mostlyclean: mostlyclean-extract +mostlyclean-extract:
- rm -f Rules-extract \
$(top_builddir)/anaconda.po $(top_builddir)/data/liveinst/gnome/fedora-welcome.po \$(top_builddir)/data/liveinst/console.apps/liveinst.h- find $(top_builddir) ( -name '*.glade.h' -o -name '*.desktop.in.h' ) \
-exec rm -f {} \;--
So it turns out that I got too clever with this part. gettext prepends $top_srcdir to each entry in POTFILES.in as it creates POTFILES, so the generated files need to be in $srcdir, not $builddir. gettext also does not support reading Rules-* files out of $builddir, so creating Rules-extract out of AC_CONFIG_FILES won't work. I'll send another patch in a bit.
This combines the Rules-glade and Rules-liveinst into one file and modifies the rules so that they work with all of our various glade and liveinst paths. Update POTFILES.in to point to the generated files so that xgettext doesn't try to process the source files directly.
For files that xgettext can handle but can't autodetect the type, manually extract strings into a .po file. xgettext can import .po files into the .pot and knows to leave the file names and line numbers alone. --- .gitignore | 3 +++ po/POTFILES.in | 68 +++++++++++++++++++++++++++++++------------------------ po/Rules-extract | 43 +++++++++++++++++++++++++++++++++++ po/Rules-glade | 11 --------- po/Rules-liveinst | 17 -------------- 5 files changed, 84 insertions(+), 58 deletions(-) create mode 100644 po/Rules-extract delete mode 100644 po/Rules-glade delete mode 100644 po/Rules-liveinst
diff --git a/.gitignore b/.gitignore index c076307..e888426 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ po/quot.sed po/remove-potcdate.sed po/remove-potcdate.sin po/stamp-po +po/tmp py-compile stamp-h1 tags @@ -85,3 +86,5 @@ widgets/doc/html widgets/doc/xml widgets/gtk-doc.make widgets/src/gettext.h +anaconda.po +data/liveinst/gnome/fedora-welcome.po diff --git a/po/POTFILES.in b/po/POTFILES.in index 4820137..90ce6e4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,7 +2,6 @@ # Copyright (C) 2009 Red Hat, Inc.
# Main anaconda source files -anaconda pyanaconda/bootloader.py pyanaconda/constants.py pyanaconda/image.py @@ -82,32 +81,6 @@ pyanaconda/ui/gui/spokes/lib/refresh.py pyanaconda/ui/gui/spokes/lib/resize.py pyanaconda/ui/gui/spokes/lib/summary.py
-# Interface files. -pyanaconda/ui/gui/spokes/advanced_user.glade -pyanaconda/ui/gui/spokes/datetime_spoke.glade -pyanaconda/ui/gui/spokes/filter.glade -pyanaconda/ui/gui/spokes/network.glade -pyanaconda/ui/gui/spokes/software.glade -pyanaconda/ui/gui/spokes/storage.glade -pyanaconda/ui/gui/spokes/keyboard.glade -pyanaconda/ui/gui/spokes/langsupport.glade -pyanaconda/ui/gui/spokes/password.glade -pyanaconda/ui/gui/spokes/source.glade -pyanaconda/ui/gui/spokes/welcome.glade -pyanaconda/ui/gui/spokes/user.glade -pyanaconda/ui/gui/spokes/custom.glade -pyanaconda/ui/gui/spokes/advstorage/fcoe.glade -pyanaconda/ui/gui/spokes/advstorage/iscsi.glade -pyanaconda/ui/gui/spokes/lib/cart.glade -pyanaconda/ui/gui/spokes/lib/detailederror.glade -pyanaconda/ui/gui/spokes/lib/passphrase.glade -pyanaconda/ui/gui/spokes/lib/refresh.glade -pyanaconda/ui/gui/spokes/lib/resize.glade -pyanaconda/ui/gui/spokes/lib/summary.glade -pyanaconda/ui/gui/main.glade -pyanaconda/ui/gui/hubs/summary.glade -pyanaconda/ui/gui/hubs/progress.glade - # Custom widgets. widgets/src/BaseWindow.c widgets/src/DiskOverview.c @@ -122,10 +95,45 @@ widgets/src/glade-adaptor.c widgets/src/lightbox.c widgets/src/tz.c
-# welcome screen for GNOME Shell -data/liveinst/gnome/fedora-welcome -data/liveinst/gnome/fedora-welcome.desktop.in +# For file types that gettext doesn't understand, list <filename>.h and +# use Rules-extract to extract the strings into a C-style header. + +# Interface files. +# gettext doesn't fully support glade3 +pyanaconda/ui/gui/spokes/advanced_user.glade.h +pyanaconda/ui/gui/spokes/datetime_spoke.glade.h +pyanaconda/ui/gui/spokes/filter.glade.h +pyanaconda/ui/gui/spokes/network.glade.h +pyanaconda/ui/gui/spokes/software.glade.h +pyanaconda/ui/gui/spokes/storage.glade.h +pyanaconda/ui/gui/spokes/keyboard.glade.h +pyanaconda/ui/gui/spokes/langsupport.glade.h +pyanaconda/ui/gui/spokes/password.glade.h +pyanaconda/ui/gui/spokes/source.glade.h +pyanaconda/ui/gui/spokes/welcome.glade.h +pyanaconda/ui/gui/spokes/user.glade.h +pyanaconda/ui/gui/spokes/custom.glade.h +pyanaconda/ui/gui/spokes/advstorage/fcoe.glade.h +pyanaconda/ui/gui/spokes/advstorage/iscsi.glade.h +pyanaconda/ui/gui/spokes/lib/cart.glade.h +pyanaconda/ui/gui/spokes/lib/detailederror.glade.h +pyanaconda/ui/gui/spokes/lib/passphrase.glade.h +pyanaconda/ui/gui/spokes/lib/refresh.glade.h +pyanaconda/ui/gui/spokes/lib/resize.glade.h +pyanaconda/ui/gui/spokes/lib/summary.glade.h +pyanaconda/ui/gui/main.glade.h +pyanaconda/ui/gui/hubs/summary.glade.h +pyanaconda/ui/gui/hubs/progress.glade.h
# liveinst source files data/liveinst/liveinst.desktop.in.h data/liveinst/console.apps/liveinst.h + +# welcome screen for GNOME Shell +data/liveinst/gnome/fedora-welcome.desktop.in.h + +# These are files that gettext does understand, but that lack an extension +# for xgettext to detect the language. Use Rules-extract to generate a .po +# that will be imported into the .pot. +anaconda.po +data/liveinst/gnome/fedora-welcome.po diff --git a/po/Rules-extract b/po/Rules-extract new file mode 100644 index 0000000..dd3e242 --- /dev/null +++ b/po/Rules-extract @@ -0,0 +1,43 @@ +# Handle files that xgettext can't handle automatically + +# intltool-extract is kind of weird. It treats the input file list as relative +# to what it thinks $srcdir is, which is either the current directory or the +# value of the undocumented -s parameter. For the output filename, it has two +# modes: --update, the default, will output files in the same directory as the +# input file. --local will output files in a tmp/ directory relative to the +# current working directory. +# +# All output files need to be in $srcdir for gettext to be able to find them. + +%.glade.h: %.glade + @intltool-extract -q --type=gettext/glade -l $< && \ + mv tmp/$$(basename $@) $@ + +%.desktop.in.h: %.desktop.in + @intltool-extract -q --type=gettext/keys -l $< && \ + mv tmp/$$(basename $@) $@ + +%liveinst.h: %liveinst + @intltool-extract -q --type=gettext/quoted -l $< && \ + mv tmp/$$(basename $@) $@ + +# Remove the $top_srcdir prefix from files so that xgettext can search for the file +# relative to $top_srcdir and get the path name right in the .po +%anaconda.po: %anaconda + @input_file="$<" && \ + $(XGETTEXT) $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \ + --language=Python -o $@ $${input_file##$(top_srcdir)/} + +# This file is actually JavaScript, but C is close enough +%fedora-welcome.po: %fedora-welcome + @input_file="$<" && \ + $(XGETTEXT) $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \ + --language=C -o $@ $${input_file##$(top_srcdir)/} + +mostlyclean: mostlyclean-extract +mostlyclean-extract: + rm -f Rules-extract \ + $(top_srcdir)/anaconda.po $(top_srcdir)/data/liveinst/gnome/fedora-welcome.po \ + $(top_srcdir)/data/liveinst/console.apps/liveinst.h + find $(top_srcdir) ( -name '*.glade.h' -o -name '*.desktop.in.h' ) \ + -exec rm -f {} ; diff --git a/po/Rules-glade b/po/Rules-glade deleted file mode 100644 index e3d7308..0000000 --- a/po/Rules-glade +++ /dev/null @@ -1,11 +0,0 @@ -UI_SRCS = $(wildcard $(top_srcdir)/data/ui/*.glade) -UI_HDRS = $(UI_SRCS:.glade=.glade.h) - -%.glade.h: %.glade - @cd $(top_builddir)/data/ui ; \ - intltool-extract -q --type=gettext/glade -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -mostlyclean-glade: - rm -f $(UI_HDRS) diff --git a/po/Rules-liveinst b/po/Rules-liveinst deleted file mode 100644 index b933c3b..0000000 --- a/po/Rules-liveinst +++ /dev/null @@ -1,17 +0,0 @@ -LIVEINST_SRCS = $(top_srcdir)/data/liveinst/liveinst.desktop.in $(top_srcdir)/data/liveinst/console.apps/liveinst -LIVEINST_HDRS = $(top_builddir)/data/liveinst/liveinst.desktop.in.h $(top_builddir)/data/liveinst/console.apps/liveinst.h - -%.desktop.in.h: %.desktop.in - @cd $(top_builddir)/data/liveinst ; \ - intltool-extract -q --type=gettext/keys -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -%liveinst.h: %liveinst - @cd $(top_builddir)/data/liveinst/console.apps ; \ - intltool-extract -q --type=gettext/quoted -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -mostlyclean-liveinst: - rm -f $(LIVEINST_HDRS)
This combines the Rules-glade and Rules-liveinst into one file and modifies the rules so that they work with all of our various glade and liveinst paths. Update POTFILES.in to point to the generated files so that xgettext doesn't try to process the source files directly.
For files that xgettext can handle but can't autodetect the type, manually extract strings into a .po file. xgettext can import .po files into the .pot and knows to leave the file names and line numbers alone. --- .gitignore | 3 +++ po/POTFILES.in | 68 +++++++++++++++++++++++++++++++------------------------ po/Rules-extract | 43 +++++++++++++++++++++++++++++++++++ po/Rules-glade | 11 --------- po/Rules-liveinst | 17 -------------- 5 files changed, 84 insertions(+), 58 deletions(-) create mode 100644 po/Rules-extract delete mode 100644 po/Rules-glade delete mode 100644 po/Rules-liveinst
diff --git a/.gitignore b/.gitignore index c076307..e888426 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ po/quot.sed po/remove-potcdate.sed po/remove-potcdate.sin po/stamp-po +po/tmp py-compile stamp-h1 tags @@ -85,3 +86,5 @@ widgets/doc/html widgets/doc/xml widgets/gtk-doc.make widgets/src/gettext.h +anaconda.po +data/liveinst/gnome/fedora-welcome.po diff --git a/po/POTFILES.in b/po/POTFILES.in index 4820137..90ce6e4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,7 +2,6 @@ # Copyright (C) 2009 Red Hat, Inc.
# Main anaconda source files -anaconda pyanaconda/bootloader.py pyanaconda/constants.py pyanaconda/image.py @@ -82,32 +81,6 @@ pyanaconda/ui/gui/spokes/lib/refresh.py pyanaconda/ui/gui/spokes/lib/resize.py pyanaconda/ui/gui/spokes/lib/summary.py
-# Interface files. -pyanaconda/ui/gui/spokes/advanced_user.glade -pyanaconda/ui/gui/spokes/datetime_spoke.glade -pyanaconda/ui/gui/spokes/filter.glade -pyanaconda/ui/gui/spokes/network.glade -pyanaconda/ui/gui/spokes/software.glade -pyanaconda/ui/gui/spokes/storage.glade -pyanaconda/ui/gui/spokes/keyboard.glade -pyanaconda/ui/gui/spokes/langsupport.glade -pyanaconda/ui/gui/spokes/password.glade -pyanaconda/ui/gui/spokes/source.glade -pyanaconda/ui/gui/spokes/welcome.glade -pyanaconda/ui/gui/spokes/user.glade -pyanaconda/ui/gui/spokes/custom.glade -pyanaconda/ui/gui/spokes/advstorage/fcoe.glade -pyanaconda/ui/gui/spokes/advstorage/iscsi.glade -pyanaconda/ui/gui/spokes/lib/cart.glade -pyanaconda/ui/gui/spokes/lib/detailederror.glade -pyanaconda/ui/gui/spokes/lib/passphrase.glade -pyanaconda/ui/gui/spokes/lib/refresh.glade -pyanaconda/ui/gui/spokes/lib/resize.glade -pyanaconda/ui/gui/spokes/lib/summary.glade -pyanaconda/ui/gui/main.glade -pyanaconda/ui/gui/hubs/summary.glade -pyanaconda/ui/gui/hubs/progress.glade - # Custom widgets. widgets/src/BaseWindow.c widgets/src/DiskOverview.c @@ -122,10 +95,45 @@ widgets/src/glade-adaptor.c widgets/src/lightbox.c widgets/src/tz.c
-# welcome screen for GNOME Shell -data/liveinst/gnome/fedora-welcome -data/liveinst/gnome/fedora-welcome.desktop.in +# For file types that gettext doesn't understand, list <filename>.h and +# use Rules-extract to extract the strings into a C-style header. + +# Interface files. +# gettext doesn't fully support glade3 +pyanaconda/ui/gui/spokes/advanced_user.glade.h +pyanaconda/ui/gui/spokes/datetime_spoke.glade.h +pyanaconda/ui/gui/spokes/filter.glade.h +pyanaconda/ui/gui/spokes/network.glade.h +pyanaconda/ui/gui/spokes/software.glade.h +pyanaconda/ui/gui/spokes/storage.glade.h +pyanaconda/ui/gui/spokes/keyboard.glade.h +pyanaconda/ui/gui/spokes/langsupport.glade.h +pyanaconda/ui/gui/spokes/password.glade.h +pyanaconda/ui/gui/spokes/source.glade.h +pyanaconda/ui/gui/spokes/welcome.glade.h +pyanaconda/ui/gui/spokes/user.glade.h +pyanaconda/ui/gui/spokes/custom.glade.h +pyanaconda/ui/gui/spokes/advstorage/fcoe.glade.h +pyanaconda/ui/gui/spokes/advstorage/iscsi.glade.h +pyanaconda/ui/gui/spokes/lib/cart.glade.h +pyanaconda/ui/gui/spokes/lib/detailederror.glade.h +pyanaconda/ui/gui/spokes/lib/passphrase.glade.h +pyanaconda/ui/gui/spokes/lib/refresh.glade.h +pyanaconda/ui/gui/spokes/lib/resize.glade.h +pyanaconda/ui/gui/spokes/lib/summary.glade.h +pyanaconda/ui/gui/main.glade.h +pyanaconda/ui/gui/hubs/summary.glade.h +pyanaconda/ui/gui/hubs/progress.glade.h
# liveinst source files data/liveinst/liveinst.desktop.in.h data/liveinst/console.apps/liveinst.h + +# welcome screen for GNOME Shell +data/liveinst/gnome/fedora-welcome.desktop.in.h + +# These are files that gettext does understand, but that lack an extension +# for xgettext to detect the language. Use Rules-extract to generate a .po +# that will be imported into the .pot. +anaconda.po +data/liveinst/gnome/fedora-welcome.po diff --git a/po/Rules-extract b/po/Rules-extract new file mode 100644 index 0000000..dd3e242 --- /dev/null +++ b/po/Rules-extract @@ -0,0 +1,43 @@ +# Handle files that xgettext can't handle automatically + +# intltool-extract is kind of weird. It treats the input file list as relative +# to what it thinks $srcdir is, which is either the current directory or the +# value of the undocumented -s parameter. For the output filename, it has two +# modes: --update, the default, will output files in the same directory as the +# input file. --local will output files in a tmp/ directory relative to the +# current working directory. +# +# All output files need to be in $srcdir for gettext to be able to find them. + +%.glade.h: %.glade + @intltool-extract -q --type=gettext/glade -l $< && \ + mv tmp/$$(basename $@) $@ + +%.desktop.in.h: %.desktop.in + @intltool-extract -q --type=gettext/keys -l $< && \ + mv tmp/$$(basename $@) $@ + +%liveinst.h: %liveinst + @intltool-extract -q --type=gettext/quoted -l $< && \ + mv tmp/$$(basename $@) $@ + +# Remove the $top_srcdir prefix from files so that xgettext can search for the file +# relative to $top_srcdir and get the path name right in the .po +%anaconda.po: %anaconda + @input_file="$<" && \ + $(XGETTEXT) $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \ + --language=Python -o $@ $${input_file##$(top_srcdir)/} + +# This file is actually JavaScript, but C is close enough +%fedora-welcome.po: %fedora-welcome + @input_file="$<" && \ + $(XGETTEXT) $(XGETTEXT_OPTIONS) --omit-header --directory=$(top_srcdir) \ + --language=C -o $@ $${input_file##$(top_srcdir)/} + +mostlyclean: mostlyclean-extract +mostlyclean-extract: + rm -f Rules-extract \ + $(top_srcdir)/anaconda.po $(top_srcdir)/data/liveinst/gnome/fedora-welcome.po \ + $(top_srcdir)/data/liveinst/console.apps/liveinst.h + find $(top_srcdir) ( -name '*.glade.h' -o -name '*.desktop.in.h' ) \ + -exec rm -f {} ; diff --git a/po/Rules-glade b/po/Rules-glade deleted file mode 100644 index e3d7308..0000000 --- a/po/Rules-glade +++ /dev/null @@ -1,11 +0,0 @@ -UI_SRCS = $(wildcard $(top_srcdir)/data/ui/*.glade) -UI_HDRS = $(UI_SRCS:.glade=.glade.h) - -%.glade.h: %.glade - @cd $(top_builddir)/data/ui ; \ - intltool-extract -q --type=gettext/glade -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -mostlyclean-glade: - rm -f $(UI_HDRS) diff --git a/po/Rules-liveinst b/po/Rules-liveinst deleted file mode 100644 index b933c3b..0000000 --- a/po/Rules-liveinst +++ /dev/null @@ -1,17 +0,0 @@ -LIVEINST_SRCS = $(top_srcdir)/data/liveinst/liveinst.desktop.in $(top_srcdir)/data/liveinst/console.apps/liveinst -LIVEINST_HDRS = $(top_builddir)/data/liveinst/liveinst.desktop.in.h $(top_builddir)/data/liveinst/console.apps/liveinst.h - -%.desktop.in.h: %.desktop.in - @cd $(top_builddir)/data/liveinst ; \ - intltool-extract -q --type=gettext/keys -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -%liveinst.h: %liveinst - @cd $(top_builddir)/data/liveinst/console.apps ; \ - intltool-extract -q --type=gettext/quoted -l $$(basename $<) ; \ - mv tmp/*h . ; \ - rmdir tmp - -mostlyclean-liveinst: - rm -f $(LIVEINST_HDRS)
On 09/10/2013 03:34 PM, David Shea wrote:
This combines the Rules-glade and Rules-liveinst into one file and modifies the rules so that they work with all of our various glade and liveinst paths. Update POTFILES.in to point to the generated files so that xgettext doesn't try to process the source files directly.
For files that xgettext can handle but can't autodetect the type, manually extract strings into a .po file. xgettext can import .po files into the .pot and knows to leave the file names and line numbers alone.
Sorry about the double send, they're the same thing.
--- pyanaconda/bootloader.py | 10 +++++----- pyanaconda/ui/gui/spokes/storage.py | 5 +++-- pyanaconda/ui/tui/spokes/network.py | 10 ++++++---- 3 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py index 276dd76..55a93a2 100644 --- a/pyanaconda/bootloader.py +++ b/pyanaconda/bootloader.py @@ -395,9 +395,9 @@ class BootLoader(object): # new arrays will be created with an appropriate metadata format if device.exists and \ metadata and device.metadataVersion not in metadata: - self.errors.append(_("RAID sets that contain '%s' must have one " - "of the following metadata versions: %s.") - % (desc, ",".join(metadata))) + self.errors.append(_("RAID sets that contain '%(desc)s' must have one " + "of the following metadata versions: %(metadata_versions)s.") + % {"desc": desc, "metadata_versions": ",".join(metadata)}) ret = False
if member_types: @@ -482,8 +482,8 @@ class BootLoader(object): sector_size = device.partedPartition.disk.device.sectorSize end_mb = (sector_size * end_sector) / (1024.0 * 1024.0) if end_mb > max_mb: - self.errors.append(_("%s must be within the first %dMB of " - "the disk.") % (desc, max_mb)) + self.errors.append(_("%(desc)s must be within the first %(max_mb)dMB of " + "the disk.") % {"desc": desc, "max_mb": max_mb}) ret = False
log.debug("_is_valid_location(%s) returning %s", device.name, ret) diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py index 41f65f1..12e8ebd 100644 --- a/pyanaconda/ui/gui/spokes/storage.py +++ b/pyanaconda/ui/gui/spokes/storage.py @@ -287,11 +287,12 @@ class InstallOptions3Dialog(InstallOptions1Dialog): self._set_free_space_labels(disk_free, fs_free)
label_text = _("<b>You don't have enough space available to install " - "%s</b>, even if you used all of the free space " + "%(productName)s</b>, even if you used all of the free space " "available on the selected disks. You could add more " "disks for additional space, " "modify your software selection to install a smaller " - "version of <b>%s</b>, or quit the installer.") % (productName, productName) + "version of <b>%(productName)s</b>, or quit the installer.") % \ + {"productName": productName} self.builder.get_object("options3_label2").set_markup(label_text)
self._add_modify_watcher("options3_label1") diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py index cdd9209..1f56eb3 100644 --- a/pyanaconda/ui/tui/spokes/network.py +++ b/pyanaconda/ui/tui/spokes/network.py @@ -119,7 +119,8 @@ class NetworkSpoke(EditTUISpoke): dnss_str = ",".join(ipv4config[1]) else: addr_str = dnss_str = gateway_str = netmask_str = "" - msg += _(" IPv4 Address: %s Netmask: %s Gateway: %s\n") % (addr_str, netmask_str, gateway_str) + msg += _(" IPv4 Address: %(addr)s Netmask: %(netmask)s Gateway: %(gateway)s\n") % \ + {"addr": addr_str, "netmask": netmask_str, "gateway": gateway_str} msg += _(" DNS: %s\n") % dnss_str
if ipv6config and ipv6config[0]: @@ -127,7 +128,8 @@ class NetworkSpoke(EditTUISpoke): addr_str, prefix, gateway_str = ipv6addr # Do not display link-local addresses if not addr_str.startswith("fe80:"): - msg += _(" IPv6 Address: %s/%d\n") % (addr_str, prefix) + msg += _(" IPv6 Address: %(addr)s/%(prefix)d\n") % \ + {"addr": addr_str, "prefix": prefix}
dnss_str = ",".join(ipv6config[1])
@@ -266,8 +268,8 @@ class ConfigureNetworkSpoke(EditTUISpoke): re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "|dhcp$"), True), Entry(_("IPv4 netmask"), "netmask", re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$"), True), Entry(_("IPv4 gateway"), "gateway", re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$"), True), - Entry(_('IPv6 address or %s for automatic, %s for DHCP, %s to turn off') - % ('"auto"', '"dhcp"', '"ignore"'), "ipv6", + Entry(_('IPv6 address or %(auto)s for automatic, %(dhcp)s for DHCP, %(ignore)s to turn off') + % {"auto": '"auto"', "dhcp": '"dhcp"', "ignore": '"ignore"'}, "ipv6", Fake_RE_IPV6(allow_prefix=True, whitelist=["auto", "dhcp", "ignore"]), True), Entry(_("IPv6 default gateway"), "ipv6gateway", re.compile(".*$"), True), Entry(_("Nameservers (comma separated)"), "nameserver", re.compile(".*$"), True),
The first patch adds a test that will fail if xgettext displays warnings while processing anything in POTFILES. The warnings about undetected language types are fixed in the second patch, and the warnings about unparameterized strings are fixed in the third.
The second patch also fixes our handling of glade files. xgettext sort of supports glade but doesn't very well with glade3, and for that reason we had some makefile rules to use intltool to extract strings. Except we were only looking for glade files in one directory and then never using the generated headers. This fixes that.
I reorganized POTFILES.in a little bit, so the .pot file will look it changed it a lot because all of the anaconda strings are at the bottom now. The filename comments in the .pot should be the same for the files that force a language in Rules-extract (anaconda, data/liveinst/gnome/fedora-welcome), but it will change for the files that switch to intltool generated headers (*.glade, fedora-welcome.desktop.in).
These look fine to me.
- Chris
anaconda-patches@lists.fedorahosted.org