From: David Shea <dshea(a)redhat.com>
The tests/gettext directory looks too much like a python module, so
rename it to something else to avoid conflicts with python's gettext.
---
tests/Makefile.am | 18 +++---
tests/gettext/__init__.py | 0
tests/gettext/click.py | 72 ----------------------
tests/gettext/contexts.py | 88 --------------------------
tests/gettext/gettext_potfiles.py | 67 --------------------
tests/gettext/gettext_warnings.sh | 44 -------------
tests/gettext/style_guide.py | 105 --------------------------------
tests/gettext_tests/__init__.py | 0
tests/gettext_tests/click.py | 72 ++++++++++++++++++++++
tests/gettext_tests/contexts.py | 88 ++++++++++++++++++++++++++
tests/gettext_tests/gettext_potfiles.py | 67 ++++++++++++++++++++
tests/gettext_tests/gettext_warnings.sh | 44 +++++++++++++
tests/gettext_tests/style_guide.py | 105 ++++++++++++++++++++++++++++++++
13 files changed, 383 insertions(+), 387 deletions(-)
delete mode 100644 tests/gettext/__init__.py
delete mode 100755 tests/gettext/click.py
delete mode 100755 tests/gettext/contexts.py
delete mode 100755 tests/gettext/gettext_potfiles.py
delete mode 100755 tests/gettext/gettext_warnings.sh
delete mode 100755 tests/gettext/style_guide.py
create mode 100644 tests/gettext_tests/__init__.py
create mode 100755 tests/gettext_tests/click.py
create mode 100755 tests/gettext_tests/contexts.py
create mode 100755 tests/gettext_tests/gettext_potfiles.py
create mode 100755 tests/gettext_tests/gettext_warnings.sh
create mode 100755 tests/gettext_tests/style_guide.py
diff --git a/tests/Makefile.am b/tests/Makefile.am
index eb02b73..f3682ba 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,12 +43,8 @@ dist_check_SCRIPTS = $(srcdir)/glade/*.py \
pylint/runpylint.py \
cppcheck/runcppcheck.sh \
testenv.sh \
- $(srcdir)/gettext/*.py \
- gettext/click.py \
- gettext/gettext_warnings.sh \
- gettext/gettext_potfiles.py \
- gettext/style_guide.py \
- gettext/contexts.py \
+ $(srcdir)/gettext_tests/*.py \
+ gettext_tests/gettext_warnings.sh \
storage/run_storage_tests.py \
install/run_install_test.sh \
$(srcdir)/kickstart_tests/*.ks.in \
@@ -64,11 +60,11 @@ dist_check_SCRIPTS = $(srcdir)/glade/*.py \
TESTS = nosetests.sh \
pylint/runpylint.py \
cppcheck/runcppcheck.sh \
- gettext/click.py \
- gettext/gettext_warnings.sh \
- gettext/gettext_potfiles.py \
- gettext/style_guide.py \
- gettext/contexts.py \
+ gettext_tests/click.py \
+ gettext_tests/gettext_warnings.sh \
+ gettext_tests/gettext_potfiles.py \
+ gettext_tests/style_guide.py \
+ gettext_tests/contexts.py \
storage/run_storage_tests.py \
glade/run_glade_tests.sh \
kickstart_tests/scripts/run_kickstart_tests.sh
diff --git a/tests/gettext/__init__.py b/tests/gettext/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/gettext/click.py b/tests/gettext/click.py
deleted file mode 100755
index 22851b7..0000000
--- a/tests/gettext/click.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/python3
-#
-# Copyright (C) 2015 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <
http://www.gnu.org/licenses/>.
-#
-# Author: David Shea <dshea(a)redhat.com>
-
-import os, re, sys
-
-# Something like looks more or less like an <a> tag
-link_re = re.compile(r'<\s*a(\s|>)')
-
-# Something that looks like a clickable message
-click_re = re.compile(r'\b[Cc]lick for\b')
-
-# Strings to ignore
-ignore_msgs = ['Click for help.']
-
-# Use polib to parse anaconda.pot
-try:
- import polib
-except ImportError:
- print("You need to install the python-polib package to read anaconda.pot")
- # This return code tells the automake test driver that the test setup failed
- sys.exit(99)
-
-if "top_srcdir" not in os.environ:
- sys.stderr.write("$top_srcdir must be defined in the test environment\n")
- sys.exit(99)
-
-if "top_builddir" not in os.environ:
- sys.stderr.write("$top_srcdir must be defined in the test environment\n")
- sys.exit(99)
-
-# Update the .pot file with the latest strings
-if os.system('make -C %s anaconda.pot-update' %
(os.environ['top_builddir'] + "/po")) != 0:
- sys.stderr.write("Unable to update anaconda.pot")
- sys.exit(1)
-
-# Parse anaconda.pot and rearrange the POFile object into a dict of {msgid: POEntry}
-pofile = polib.pofile(os.environ['top_srcdir'] + "/po/anaconda.pot")
-msgs = {e.msgid: e for e in pofile}
-
-success = True
-for msg in msgs.keys():
- if msg in ignore_msgs:
- continue
-
- # Remove underscores to avoid trouble with underline-based accelerators
- trimmed_msg = msg.replace('_', '')
-
- # Look for claims of clickability
- if click_re.search(trimmed_msg):
- # Look for something to click
- if not link_re.search(trimmed_msg):
- print("String at %s appears to be clickable but has nothing to
click." %
- " ".join("%s:%s" % (o[0], o[1]) for o in
msgs[msg].occurrences))
- success = False
-
-sys.exit(0 if success else 1)
diff --git a/tests/gettext/contexts.py b/tests/gettext/contexts.py
deleted file mode 100755
index 62470da..0000000
--- a/tests/gettext/contexts.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/python3
-#
-# Copyright (C) 2015 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <
http://www.gnu.org/licenses/>.
-#
-# Author: David Shea <dshea(a)redhat.com>
-
-import os, sys, re
-
-def list_occurrences(occurrences):
- # Return polib's occurrences list [('file1', line1), ('file2',
line2), ...]
- # as a space-separated list of file1:line1 etc.
- return " ".join("%s:%s" % (o[0], o[1]) for o in occurrences)
-
-def is_accelerated(message):
- # True if there is a _ anywhere outside of a format parameter name
- if "_" not in message.msgid:
- return False
-
- if "python-format" in message.flags:
- # Assume this is a %-formatted string, strip out everything from %
- # to the end of a word, or at least to the end of the identifier
- # we're trying to ignore
- if "_" not in re.sub('%[()_a-zA-Z0-9]*', '',
message.msgid):
- return False
-
- return True
-
-# Use polib to parse anaconda.pot
-try:
- import polib
-except ImportError:
- print("You need to install the python-polib package to read anaconda.pot")
- # This return code tells the automake test driver that the test setup failed
- sys.exit(99)
-
-if "top_srcdir" not in os.environ:
- sys.stderr.write("$top_srcdir must be defined in the test environment\n")
- sys.exit(99)
-
-if "top_builddir" not in os.environ:
- sys.stderr.write("$top_srcdir must be defined in the test environment\n")
- sys.exit(99)
-
-# Update the .pot file with the latest strings
-if os.system('make -C %s anaconda.pot-update' %
(os.environ['top_builddir'] + "/po")) != 0:
- sys.stderr.write("Unable to update anaconda.pot")
- sys.exit(1)
-
-# Parse anaconda.pot
-pofile = polib.pofile(os.environ['top_srcdir'] + "/po/anaconda.pot")
-
-success = True
-
-# There are two cases that require contexts: GUI strings with keyboard accelerators,
-# and single-character TUI strings (e.g. c for continue)
-
-# First, the GUI strings with accelerators
-for msg in (p for p in pofile if is_accelerated(p)):
- if not msg.msgctxt:
- print("Keyboard accelerator missing context at %s" %
list_occurrences(msg.occurrences))
- success = False
-
-# Next, the abbreviations. These strings also require a comment to explain what
-# they are abbreviating.
-for msg in (p for p in pofile if len(p.msgid) == 1):
- if not msg.msgctxt:
- print("Abbreviation %s is missing context at %s" %
- (msg.msgid, list_occurrences(msg.occurrences)))
- success = False
-
- if not msg.comment:
- print("Abbreviation %s is missing a comment at %s" %
- (msg.msgid, list_occurrences(msg.occurrences)))
-
-sys.exit(0 if success else 1)
diff --git a/tests/gettext/gettext_potfiles.py b/tests/gettext/gettext_potfiles.py
deleted file mode 100755
index 1d8f7f1..0000000
--- a/tests/gettext/gettext_potfiles.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/python3
-
-# Ignore any interruptible calls
-# pylint: disable=interruptible-system-call
-
-import os, sys, subprocess, tempfile
-
-if "top_srcdir" not in os.environ:
- sys.stderr.write("$top_srcdir must be defined in the test environment\n")
- # This return code tells the automake test driver that the test setup failed
- sys.exit(99)
-
-# Ensure that tests/lib is in sys.path
-testlibpath = os.path.abspath(os.path.join(os.environ["top_srcdir"],
"tests/lib"))
-if testlibpath not in sys.path:
- sys.path.append(testlibpath)
-
-from filelist import testfilelist
-
-success = True
-
-# from po/Makevars
-XGETTEXT_OPTIONS = ["--keyword=_", "--keyword=N_",
"--keyword=P_:1,2",
- "--keyword=C_:1c,2", "--keyword=CN_:1c,2",
"--keyword=CP_:1c,2,3",
- "--from-code=UTF-8"]
-
-def check_potfile(checkfile, potlist):
- global success
-
- potcheckfile = None
-
- _root, ext = os.path.splitext(checkfile)
- if ext in (".py", ".c", ".glade"):
- # These files are handled directly by gettext. Use xgettext to look for
- # translatable strings. If anything is written to the output file, xgettext
- # found something
- with tempfile.NamedTemporaryFile() as pofile:
- subprocess.check_call(["xgettext", "-o", pofile.name] +
XGETTEXT_OPTIONS + [checkfile])
- if os.path.getsize(pofile.name) > 0:
- potcheckfile = checkfile
- elif checkfile.endswith(".desktop.in"):
- # These are handled by intltool, make sure the .h version is present
- potcheckfile = checkfile + ".h"
-
- if not potcheckfile:
- return
-
- # Compute the path relative to top_srcdir
- potcheckfile = os.path.relpath(potcheckfile, os.environ["top_srcdir"])
-
- if potcheckfile not in potlist:
- sys.stderr.write("%s not in POTFILES.in\n" % potcheckfile)
- success = False
-
-# Read in POTFILES.in, skip comments and blank lines
-POTFILES = set()
-with open(os.path.join(os.environ["top_srcdir"], "po",
"POTFILES.in")) as f:
- for line in (line.strip() for line in f):
- if line and not line.startswith("#"):
- POTFILES.add(line)
-
-# Walk the source tree and look for files with translatable strings
-for testfile in testfilelist():
- check_potfile(testfile, POTFILES)
-
-if not success:
- sys.exit(1)
diff --git a/tests/gettext/gettext_warnings.sh b/tests/gettext/gettext_warnings.sh
deleted file mode 100755
index 2974e32..0000000
--- a/tests/gettext/gettext_warnings.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh -e
-
-if [ -z "$top_srcdir" ]; then
- top_srcdir="$(dirname "$0")/../.."
- . "${top_srcdir}/tests/testenv.sh"
-fi
-podir="${top_builddir}/po"
-POTFILES="${podir}/POTFILES"
-
-# Extract XGETTEXT_OPTIONS from po/Makevars
-# Makevars is one of our files, so it's in $srcdir
-XGETTEXT_OPTIONS="$(sed -n
's/^[[:space:]]*XGETTEXT_OPTIONS[[:space:]]*=[[:space:]]*\(.*\)/\1/p' \
- "${top_srcdir}/po/Makevars")"
-
-# Fail if POTFILES doesn't exist, since set -e doesn't catch this for some
-# dumb reason that I'm sure has a long and storied history
-if [ ! -f "${POTFILES}" ] ; then
- echo "POTFILES does not exist"
- exit 1
-fi
-
-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 < "$POTFILES"
-
-exit "$status"
diff --git a/tests/gettext/style_guide.py b/tests/gettext/style_guide.py
deleted file mode 100755
index b326f38..0000000
--- a/tests/gettext/style_guide.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/python3
-#
-# Copyright (C) 2014 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <
http://www.gnu.org/licenses/>.
-#
-# Author: David Shea <dshea(a)redhat.com>
-
-import os, re, sys
-
-# {'bad re': 'suggestion'}
-# (?i) makes the re case-insensitive
-bad_strings = {'(?i)bootloader': 'boot loader',
- '(?i)filesystem': 'file system',
- '(?i)username': 'user name',
- '[Vv]lan': 'VLAN',
- '(?i)hostname': 'hostname',
- 'ZFCP': 'zFCP',
- 'zfcp': 'zFCP',
- 'BTRFS': 'Btrfs',
- 'btrfs': 'Btrfs',
- '[Cc]an not': 'cannot',
- '(?i)mountpoint': 'mount point',
- 'Ok': 'OK'}
-
-# Sometimes we need to use a bad string, or it's just too much of a pain to
-# write a more specific regex. List occurrences here.
-# {'filename': {'matched string', occurrences}}
-expected_badness = {'pyanaconda/bootloader.py': {'mountpoint': 1}, #
format string specifier
- 'pyanaconda/kickstart.py': {'btrfs': 1}, #
quoted filesystem type
- 'pyanaconda/network.py': {'vlan': 1}, #
format string specifier
- 'pyanaconda/rescue.py': {'mountpoint': 1}} #
format string specifier
-
-# Use polib to parse anaconda.pot
-try:
- import polib
-except ImportError:
- print("You need to install the python-polib package to read anaconda.pot")
- # This return code tells the automake test driver that the test setup failed
- sys.exit(99)
-
-if "top_srcdir" not in os.environ:
- sys.stderr.write("$top_srcdir must be defined in the test environment\n")
- sys.exit(99)
-
-if "top_builddir" not in os.environ:
- sys.stderr.write("$top_srcdir must be defined in the test environment\n")
- sys.exit(99)
-
-# Update the .pot file with the latest strings
-if os.system('make -C %s anaconda.pot-update' %
(os.environ['top_builddir'] + "/po")) != 0:
- sys.stderr.write("Unable to update anaconda.pot")
- sys.exit(1)
-
-# Parse anaconda.pot and rearrange the POFile object into a dict of {msgid: POEntry}
-pofile = polib.pofile(os.environ['top_srcdir'] + "/po/anaconda.pot")
-msgs = {e.msgid: e for e in pofile}
-
-# Look for each of the bad regexes
-success = True
-for badre in bad_strings.keys():
- regex = re.compile(badre)
- for msg in msgs.keys():
- # Remove underscores to avoid trouble with underline-based accelerators
- match = re.search(regex, msg.replace('_', ''))
- if match:
- # If this is something expected, decrement the occurrence count in
expected_badness
- badstr = match.group(0)
- remainder = []
- for occur in msgs[msg].occurrences:
- if occur[0] in expected_badness and badstr in
expected_badness[occur[0]]:
- expected_badness[occur[0]][badstr] -= 1
- if expected_badness[occur[0]][badstr] == 0:
- del expected_badness[occur[0]][badstr]
- if not expected_badness[occur[0]]:
- del expected_badness[occur[0]]
- else:
- remainder.append(occur)
-
- if remainder:
- print("Bad string %(bad)s found at %(occurrences)s. Try
%(suggestion)s instead." %
- {"bad": badstr,
- "occurrences": " ".join(("%s:%s" %
(o[0], o[1]) for o in remainder)),
- "suggestion": bad_strings[badre]})
- success = False
-
-if expected_badness:
- for filename in expected_badness.keys():
- for badstr in expected_badness[filename].keys():
- print("Did not find %d occurrences of %s in %s" %
- (expected_badness[filename][badstr], badstr, filename))
- success = False
-
-sys.exit(0 if success else 1)
diff --git a/tests/gettext_tests/__init__.py b/tests/gettext_tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/gettext_tests/click.py b/tests/gettext_tests/click.py
new file mode 100755
index 0000000..22851b7
--- /dev/null
+++ b/tests/gettext_tests/click.py
@@ -0,0 +1,72 @@
+#!/usr/bin/python3
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <
http://www.gnu.org/licenses/>.
+#
+# Author: David Shea <dshea(a)redhat.com>
+
+import os, re, sys
+
+# Something like looks more or less like an <a> tag
+link_re = re.compile(r'<\s*a(\s|>)')
+
+# Something that looks like a clickable message
+click_re = re.compile(r'\b[Cc]lick for\b')
+
+# Strings to ignore
+ignore_msgs = ['Click for help.']
+
+# Use polib to parse anaconda.pot
+try:
+ import polib
+except ImportError:
+ print("You need to install the python-polib package to read anaconda.pot")
+ # This return code tells the automake test driver that the test setup failed
+ sys.exit(99)
+
+if "top_srcdir" not in os.environ:
+ sys.stderr.write("$top_srcdir must be defined in the test environment\n")
+ sys.exit(99)
+
+if "top_builddir" not in os.environ:
+ sys.stderr.write("$top_srcdir must be defined in the test environment\n")
+ sys.exit(99)
+
+# Update the .pot file with the latest strings
+if os.system('make -C %s anaconda.pot-update' %
(os.environ['top_builddir'] + "/po")) != 0:
+ sys.stderr.write("Unable to update anaconda.pot")
+ sys.exit(1)
+
+# Parse anaconda.pot and rearrange the POFile object into a dict of {msgid: POEntry}
+pofile = polib.pofile(os.environ['top_srcdir'] + "/po/anaconda.pot")
+msgs = {e.msgid: e for e in pofile}
+
+success = True
+for msg in msgs.keys():
+ if msg in ignore_msgs:
+ continue
+
+ # Remove underscores to avoid trouble with underline-based accelerators
+ trimmed_msg = msg.replace('_', '')
+
+ # Look for claims of clickability
+ if click_re.search(trimmed_msg):
+ # Look for something to click
+ if not link_re.search(trimmed_msg):
+ print("String at %s appears to be clickable but has nothing to
click." %
+ " ".join("%s:%s" % (o[0], o[1]) for o in
msgs[msg].occurrences))
+ success = False
+
+sys.exit(0 if success else 1)
diff --git a/tests/gettext_tests/contexts.py b/tests/gettext_tests/contexts.py
new file mode 100755
index 0000000..62470da
--- /dev/null
+++ b/tests/gettext_tests/contexts.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python3
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <
http://www.gnu.org/licenses/>.
+#
+# Author: David Shea <dshea(a)redhat.com>
+
+import os, sys, re
+
+def list_occurrences(occurrences):
+ # Return polib's occurrences list [('file1', line1), ('file2',
line2), ...]
+ # as a space-separated list of file1:line1 etc.
+ return " ".join("%s:%s" % (o[0], o[1]) for o in occurrences)
+
+def is_accelerated(message):
+ # True if there is a _ anywhere outside of a format parameter name
+ if "_" not in message.msgid:
+ return False
+
+ if "python-format" in message.flags:
+ # Assume this is a %-formatted string, strip out everything from %
+ # to the end of a word, or at least to the end of the identifier
+ # we're trying to ignore
+ if "_" not in re.sub('%[()_a-zA-Z0-9]*', '',
message.msgid):
+ return False
+
+ return True
+
+# Use polib to parse anaconda.pot
+try:
+ import polib
+except ImportError:
+ print("You need to install the python-polib package to read anaconda.pot")
+ # This return code tells the automake test driver that the test setup failed
+ sys.exit(99)
+
+if "top_srcdir" not in os.environ:
+ sys.stderr.write("$top_srcdir must be defined in the test environment\n")
+ sys.exit(99)
+
+if "top_builddir" not in os.environ:
+ sys.stderr.write("$top_srcdir must be defined in the test environment\n")
+ sys.exit(99)
+
+# Update the .pot file with the latest strings
+if os.system('make -C %s anaconda.pot-update' %
(os.environ['top_builddir'] + "/po")) != 0:
+ sys.stderr.write("Unable to update anaconda.pot")
+ sys.exit(1)
+
+# Parse anaconda.pot
+pofile = polib.pofile(os.environ['top_srcdir'] + "/po/anaconda.pot")
+
+success = True
+
+# There are two cases that require contexts: GUI strings with keyboard accelerators,
+# and single-character TUI strings (e.g. c for continue)
+
+# First, the GUI strings with accelerators
+for msg in (p for p in pofile if is_accelerated(p)):
+ if not msg.msgctxt:
+ print("Keyboard accelerator missing context at %s" %
list_occurrences(msg.occurrences))
+ success = False
+
+# Next, the abbreviations. These strings also require a comment to explain what
+# they are abbreviating.
+for msg in (p for p in pofile if len(p.msgid) == 1):
+ if not msg.msgctxt:
+ print("Abbreviation %s is missing context at %s" %
+ (msg.msgid, list_occurrences(msg.occurrences)))
+ success = False
+
+ if not msg.comment:
+ print("Abbreviation %s is missing a comment at %s" %
+ (msg.msgid, list_occurrences(msg.occurrences)))
+
+sys.exit(0 if success else 1)
diff --git a/tests/gettext_tests/gettext_potfiles.py
b/tests/gettext_tests/gettext_potfiles.py
new file mode 100755
index 0000000..1d8f7f1
--- /dev/null
+++ b/tests/gettext_tests/gettext_potfiles.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python3
+
+# Ignore any interruptible calls
+# pylint: disable=interruptible-system-call
+
+import os, sys, subprocess, tempfile
+
+if "top_srcdir" not in os.environ:
+ sys.stderr.write("$top_srcdir must be defined in the test environment\n")
+ # This return code tells the automake test driver that the test setup failed
+ sys.exit(99)
+
+# Ensure that tests/lib is in sys.path
+testlibpath = os.path.abspath(os.path.join(os.environ["top_srcdir"],
"tests/lib"))
+if testlibpath not in sys.path:
+ sys.path.append(testlibpath)
+
+from filelist import testfilelist
+
+success = True
+
+# from po/Makevars
+XGETTEXT_OPTIONS = ["--keyword=_", "--keyword=N_",
"--keyword=P_:1,2",
+ "--keyword=C_:1c,2", "--keyword=CN_:1c,2",
"--keyword=CP_:1c,2,3",
+ "--from-code=UTF-8"]
+
+def check_potfile(checkfile, potlist):
+ global success
+
+ potcheckfile = None
+
+ _root, ext = os.path.splitext(checkfile)
+ if ext in (".py", ".c", ".glade"):
+ # These files are handled directly by gettext. Use xgettext to look for
+ # translatable strings. If anything is written to the output file, xgettext
+ # found something
+ with tempfile.NamedTemporaryFile() as pofile:
+ subprocess.check_call(["xgettext", "-o", pofile.name] +
XGETTEXT_OPTIONS + [checkfile])
+ if os.path.getsize(pofile.name) > 0:
+ potcheckfile = checkfile
+ elif checkfile.endswith(".desktop.in"):
+ # These are handled by intltool, make sure the .h version is present
+ potcheckfile = checkfile + ".h"
+
+ if not potcheckfile:
+ return
+
+ # Compute the path relative to top_srcdir
+ potcheckfile = os.path.relpath(potcheckfile, os.environ["top_srcdir"])
+
+ if potcheckfile not in potlist:
+ sys.stderr.write("%s not in POTFILES.in\n" % potcheckfile)
+ success = False
+
+# Read in POTFILES.in, skip comments and blank lines
+POTFILES = set()
+with open(os.path.join(os.environ["top_srcdir"], "po",
"POTFILES.in")) as f:
+ for line in (line.strip() for line in f):
+ if line and not line.startswith("#"):
+ POTFILES.add(line)
+
+# Walk the source tree and look for files with translatable strings
+for testfile in testfilelist():
+ check_potfile(testfile, POTFILES)
+
+if not success:
+ sys.exit(1)
diff --git a/tests/gettext_tests/gettext_warnings.sh
b/tests/gettext_tests/gettext_warnings.sh
new file mode 100755
index 0000000..2974e32
--- /dev/null
+++ b/tests/gettext_tests/gettext_warnings.sh
@@ -0,0 +1,44 @@
+#!/bin/sh -e
+
+if [ -z "$top_srcdir" ]; then
+ top_srcdir="$(dirname "$0")/../.."
+ . "${top_srcdir}/tests/testenv.sh"
+fi
+podir="${top_builddir}/po"
+POTFILES="${podir}/POTFILES"
+
+# Extract XGETTEXT_OPTIONS from po/Makevars
+# Makevars is one of our files, so it's in $srcdir
+XGETTEXT_OPTIONS="$(sed -n
's/^[[:space:]]*XGETTEXT_OPTIONS[[:space:]]*=[[:space:]]*\(.*\)/\1/p' \
+ "${top_srcdir}/po/Makevars")"
+
+# Fail if POTFILES doesn't exist, since set -e doesn't catch this for some
+# dumb reason that I'm sure has a long and storied history
+if [ ! -f "${POTFILES}" ] ; then
+ echo "POTFILES does not exist"
+ exit 1
+fi
+
+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 < "$POTFILES"
+
+exit "$status"
diff --git a/tests/gettext_tests/style_guide.py b/tests/gettext_tests/style_guide.py
new file mode 100755
index 0000000..b326f38
--- /dev/null
+++ b/tests/gettext_tests/style_guide.py
@@ -0,0 +1,105 @@
+#!/usr/bin/python3
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <
http://www.gnu.org/licenses/>.
+#
+# Author: David Shea <dshea(a)redhat.com>
+
+import os, re, sys
+
+# {'bad re': 'suggestion'}
+# (?i) makes the re case-insensitive
+bad_strings = {'(?i)bootloader': 'boot loader',
+ '(?i)filesystem': 'file system',
+ '(?i)username': 'user name',
+ '[Vv]lan': 'VLAN',
+ '(?i)hostname': 'hostname',
+ 'ZFCP': 'zFCP',
+ 'zfcp': 'zFCP',
+ 'BTRFS': 'Btrfs',
+ 'btrfs': 'Btrfs',
+ '[Cc]an not': 'cannot',
+ '(?i)mountpoint': 'mount point',
+ 'Ok': 'OK'}
+
+# Sometimes we need to use a bad string, or it's just too much of a pain to
+# write a more specific regex. List occurrences here.
+# {'filename': {'matched string', occurrences}}
+expected_badness = {'pyanaconda/bootloader.py': {'mountpoint': 1}, #
format string specifier
+ 'pyanaconda/kickstart.py': {'btrfs': 1}, #
quoted filesystem type
+ 'pyanaconda/network.py': {'vlan': 1}, #
format string specifier
+ 'pyanaconda/rescue.py': {'mountpoint': 1}} #
format string specifier
+
+# Use polib to parse anaconda.pot
+try:
+ import polib
+except ImportError:
+ print("You need to install the python-polib package to read anaconda.pot")
+ # This return code tells the automake test driver that the test setup failed
+ sys.exit(99)
+
+if "top_srcdir" not in os.environ:
+ sys.stderr.write("$top_srcdir must be defined in the test environment\n")
+ sys.exit(99)
+
+if "top_builddir" not in os.environ:
+ sys.stderr.write("$top_srcdir must be defined in the test environment\n")
+ sys.exit(99)
+
+# Update the .pot file with the latest strings
+if os.system('make -C %s anaconda.pot-update' %
(os.environ['top_builddir'] + "/po")) != 0:
+ sys.stderr.write("Unable to update anaconda.pot")
+ sys.exit(1)
+
+# Parse anaconda.pot and rearrange the POFile object into a dict of {msgid: POEntry}
+pofile = polib.pofile(os.environ['top_srcdir'] + "/po/anaconda.pot")
+msgs = {e.msgid: e for e in pofile}
+
+# Look for each of the bad regexes
+success = True
+for badre in bad_strings.keys():
+ regex = re.compile(badre)
+ for msg in msgs.keys():
+ # Remove underscores to avoid trouble with underline-based accelerators
+ match = re.search(regex, msg.replace('_', ''))
+ if match:
+ # If this is something expected, decrement the occurrence count in
expected_badness
+ badstr = match.group(0)
+ remainder = []
+ for occur in msgs[msg].occurrences:
+ if occur[0] in expected_badness and badstr in
expected_badness[occur[0]]:
+ expected_badness[occur[0]][badstr] -= 1
+ if expected_badness[occur[0]][badstr] == 0:
+ del expected_badness[occur[0]][badstr]
+ if not expected_badness[occur[0]]:
+ del expected_badness[occur[0]]
+ else:
+ remainder.append(occur)
+
+ if remainder:
+ print("Bad string %(bad)s found at %(occurrences)s. Try
%(suggestion)s instead." %
+ {"bad": badstr,
+ "occurrences": " ".join(("%s:%s" %
(o[0], o[1]) for o in remainder)),
+ "suggestion": bad_strings[badre]})
+ success = False
+
+if expected_badness:
+ for filename in expected_badness.keys():
+ for badstr in expected_badness[filename].keys():
+ print("Did not find %d occurrences of %s in %s" %
+ (expected_badness[filename][badstr], badstr, filename))
+ success = False
+
+sys.exit(0 if success else 1)
--
To view this commit on github, visit
https://github.com/rhinstaller/anaconda/commit/3df9a7574616ecf483d2da68ce...