Commit 29d66a89 authored by intrigeri's avatar intrigeri
Browse files

lint_po: make PEP-8 compliant, improve some user-visible strings and comments.

parent b82cc087
......@@ -17,7 +17,7 @@ Run with a list of files:
Run for all po files that are staged for git commit:
./lint_po --cached
Run for all po files of one language in the current directory (including subdirs):
Run for all po files of one language in the current directory (recursively):
./lint_po --lang de
When modifying lint_po (this script), you should check if the current type
......@@ -76,21 +76,26 @@ I18NSPECTOR_ACCEPT = [
"unusual-unused-plural-forms",
]
class NoLanguageError(Exception):
def __init__(self, fname):
self.fname = fname
def __str__(self):
return "Can't detect expect file suffix .XX.po for '{fname}'.".format(fname=self.fname)
return(
"Can't detect expect file suffix .XX.po for '{fname}'."
.format(fname=self.fname))
pass
class PoFile:
def __init__(self, fname: str) -> None:
self.fname = fname
self.wrapwidth = 79
def fixedHeaders(self) -> Dict[str, str]:
"""@returns: a dict of key,value parts that should be fixed within the po file"""
"""@returns: a dict of key,value parts that should be fixed
within the po file"""
return {"Language": self.lang(),
"Content-Type": "text/plain; charset=UTF-8",
"Project-Id-Version": "",
......@@ -145,7 +150,8 @@ class PoFile:
if self.__changed:
_prefix = os.path.basename(self.fname)
_dir = os.path.dirname(self.fname)
with tempfile.NamedTemporaryFile(prefix=_prefix, dir=_dir, delete=False) as fd:
with tempfile.NamedTemporaryFile(
prefix=_prefix, dir=_dir, delete=False) as fd:
try:
self.pf.save(fd.name)
fd.flush()
......@@ -174,7 +180,8 @@ class PoFile:
"""@returns a list of issues raised by i18nspector removes
allowed issues from @I18NINSPECTOR_ACCEPT.
"""
cmd = ["i18nspector", "--language", self.lang_without_script(), self.fname]
cmd = ["i18nspector", "--language",
self.lang_without_script(), self.fname]
process = subprocess.run(
cmd,
stdout=subprocess.PIPE,
......@@ -215,7 +222,8 @@ def check_po_file(fname: str, extended: bool) -> Tuple[str, List[str]]:
try:
issues = poFile.i18nspector()
if issues:
errors.append("i18nspector is not happy:\n\t"+"\n\t".join(issues))
errors.append(
"i18nspector is not happy:\n\t"+"\n\t".join(issues))
except subprocess.CalledProcessError as e:
errors.append("i18nspector exited with {e.returncode} - stderr:\n"
"{e.stderr}".format(e=e))
......@@ -223,7 +231,8 @@ def check_po_file(fname: str, extended: bool) -> Tuple[str, List[str]]:
if extended:
for key, value in poFile.fixedHeaders().items():
if not poFile.check(key, value):
errors.append("{key} is not '{value}'.".format(key=key, value=value))
errors.append("{key} is not '{value}'."
.format(key=key, value=value))
return (fname, errors)
......@@ -233,39 +242,48 @@ def unify_po_file(fname: str) -> None:
with pofile_writable(fname) as poFile:
for key, value in poFile.fixedHeaders().items():
poFile.unifyKey(key, value)
poFile.needs_rewrap() # as sideeffect it updates the store flag,
# if file is not wrapped properly
# As a side-effect this updates the store flag,
# if the file is not properly wrapped:
poFile.needs_rewrap()
def main(logger) -> None:
parser = argparse.ArgumentParser(description='Unify PO files')
parser.add_argument('--fix', dest='fix', action='store_true',
help='Fixes the issues of the PO headers, otherwise only check is done.')
parser.add_argument('--check-extended', dest='extended', action='store_true',
help='Fixes issues found in PO headers.')
parser.add_argument('--check-extended', dest='extended',
action='store_true',
help='Do extended checks of PO headers.')
parser.add_argument('--lang', dest='lang', help='all files of a specific language.')
parser.add_argument('--lang', dest='lang',
help='Check all PO files of the specified language.')
parser.add_argument('--cached', dest='cached', action='store_true',
help='all git staged PO files.')
help='Only check PO files staged with Git.')
parser.add_argument('files', metavar='file', type=str, nargs='*',
help='list of files to process.')
help='List of files to process.')
args = parser.parse_args()
if args.lang:
args.files += glob.glob("**/*.{lang}.po".format(lang=args.lang), recursive=True)
args.files += glob.glob("**/{lang}.po".format(lang=args.lang), recursive=True)
args.files += glob.glob("**/*.{lang}.po".format(lang=args.lang),
recursive=True)
args.files += glob.glob("**/{lang}.po".format(lang=args.lang),
recursive=True)
if args.cached:
# get top level directory of the current git repository
# git diff returns always relative paths to the top level directory
toplevel = subprocess.check_output(["git", "rev-parse", "--show-toplevel"], universal_newlines=True).rstrip()
toplevel = subprocess.check_output(
["git", "rev-parse", "--show-toplevel"],
universal_newlines=True).rstrip()
# get a list of changes and added files in stage for the next commit
output = subprocess.check_output(
["git", "diff", "--name-only", "--cached", "--ignore-submodules", "--diff-filter=d"],
universal_newlines=True)
["git", "diff", "--name-only", "--cached",
"--ignore-submodules", "--diff-filter=d"],
universal_newlines=True)
# add all po files to list to unify
args.files += [os.path.join(toplevel, f) for f in output.splitlines() if f.endswith(".po")]
args.files += [os.path.join(toplevel, f) for f in output.splitlines()
if f.endswith(".po")]
if not args.files and not args.cached and not args.lang:
args.files += glob.glob("**/*.po", recursive=True)
......@@ -282,7 +300,8 @@ def main(logger) -> None:
for prog in ("i18nspector",):
if shutil.which(prog) is None:
sys.exit("{prog}: command not found\n"
"You need to install {prog} first. See /contribute/l10n_tricks."
"You need to install {prog} first.\n"
"See /contribute/l10n_tricks."
.format(prog=prog))
pool = multiprocessing.Pool()
......@@ -293,12 +312,16 @@ def main(logger) -> None:
fine = True
# check only the headers
pool = multiprocessing.Pool()
_check_po_file = functools.partial(check_po_file, extended=args.extended)
for fname, issues in pool.imap_unordered(_check_po_file, args.files, 10):
_check_po_file = functools.partial(check_po_file,
extended=args.extended)
for fname, issues in pool.imap_unordered(_check_po_file,
args.files, 10):
if issues:
fine = False
issues = [i.replace("\n", "\n\t") for i in issues] # indent subissues
logger.error("{fname}:\n\t{issues}".format(fname=fname, issues="\n\t".join(issues)))
# indent sub-issues:
issues = [i.replace("\n", "\n\t") for i in issues]
logger.error("{fname}:\n\t{issues}"
.format(fname=fname, issues="\n\t".join(issues)))
else:
logger.debug("{fname} - No issue found.".format(fname=fname))
......@@ -307,5 +330,6 @@ def main(logger) -> None:
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
logging.basicConfig(level=logging.INFO,
format='%(levelname)s: %(message)s')
main(logging.getLogger())
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment