Skip to content

Commit

Permalink
Add hook to check for fuzzy messages (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
mondeja committed Feb 25, 2022
1 parent 6c96941 commit 2c9e710
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.6.1
current_version = 1.7.0

[bumpversion:file:setup.cfg]

Expand Down
6 changes: 6 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
description: Checks for untranslated messages in PO files
files: \.po$
language: python
- id: fuzzy-messages
name: fuzzy-messages
entry: fuzzy-messages-hook
description: Checks for fuzzy messages in PO files
files: \.po$
language: python
- id: remove-django-translators
name: remove-django-translators
entry: lreplace-extracted-comments-hook --django-translators
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ Hooks for pre-commit useful working with PO files.

```yaml
- repo: https://github.com/mondeja/pre-commit-po-hooks
rev: v1.6.1
rev: v1.7.0
hooks:
- id: obsolete-messages
- id: untranslated-messages
- id: fuzzy-messages
- id: remove-django-translators
- id: standard-metadata
- id: max-lines
Expand All @@ -37,6 +38,10 @@ Checks for untranslated messages printing their line numbers if found.
to pass this check. Can be defined as a percentage of the messages translated
appending a character `%` at the end of the value.

### **`fuzzy-messages`**

Checks for fuzzy messages printing their line numbers if found.

### **`lreplace-extracted-comments`**

Replaces a matching string at the beginning of extracted comments.
Expand Down
52 changes: 52 additions & 0 deletions hooks/fuzzy_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Checks for fuzzy messages in PO files.
Returns an error code if a PO file has a fuzzy message.
"""

import argparse
import sys


def check_fuzzy_messages(filenames, quiet=False):
"""Warns about all fuzzy messages found in a set of PO files.
Parameters
----------
filenames : list
Set of file names to check.
quiet : bool, optional
Enabled, don't print output to stderr when an fuzzy message is found.
Returns
-------
int: 0 if no fuzzy messages found, 1 otherwise.
"""
exitcode = 0
for filename in filenames:
with open(filename) as f:
content_lines = f.readlines()

for i, line in enumerate(content_lines):
if line.startswith("#,") and "fuzzy" in line:
exitcode = 1
if not quiet:
sys.stderr.write(f"Found fuzzy message at {filename}:{i + 1}\n")

return exitcode


def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"filenames", nargs="*", help="Filenames to check for fuzzy messages"
)
parser.add_argument("-q", "--quiet", action="store_true", help="Supress output")
args = parser.parse_args()
return check_fuzzy_messages(args.filenames, quiet=args.quiet)


if __name__ == "__main__":
exit(main())
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = pre_commit_po_hooks
version = 1.6.1
version = 1.7.0
description = pre-commit hooks for PO files
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down Expand Up @@ -32,6 +32,7 @@ exclude =
console_scripts =
obsolete-messages-hook = hooks.obsolete_messages:main
untranslated-messages-hook = hooks.untranslated_messages:main
fuzzy-messages-hook = hooks.fuzzy_messages:main
lreplace-extracted-comments-hook = hooks.lreplace_extracted_comments:main
check-metadata-hook = hooks.check_metadata:main
check-entries-hook = hooks.check_entries:main
Expand Down
115 changes: 115 additions & 0 deletions tests/test_fuzzy_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"""Obsolete messages hook tests."""

import contextlib
import io
import os
import uuid

import pytest

from hooks.fuzzy_messages import check_fuzzy_messages


"""
(
[
(
'#\nmsgid ""\nmsgstr ""\n\n#~ msgid "Obsolete "\n#~ "message"'
'\n#~ msgstr "Mensaje obsoleto"\n'
),
'#\nmsgid ""\nmsgstr ""\n\nmsgid "Hello"\nmsgstr "Hola"\n',
(
'#\nmsgid ""\nmsgstr ""\n\n#~ msgid "Hello"\n#~ msgstr "Hola"\n'
'\nmsgid "Foo"\nmsgstr "Bar"\n'
),
],
2,
1,
[5, 5],
),
(
['#\nmsgid ""\nmsgstr ""\n\nmsgid "Current"\nmsgstr "Actual"\n'],
0,
0,
None,
),
"""


@pytest.mark.parametrize("quiet", (False, True), ids=("quiet=False", "quiet=True"))
@pytest.mark.parametrize(
("contents", "n_printed_errors", "expected_exitcode", "expected_line_numbers"),
(
pytest.param(
[
(
'#\nmsgid ""\nmsgstr ""\n\n'
'#, fuzzy\n#~ msgid "Obsolete"\n#~ msgstr "Obsoleto"\n'
)
],
1,
1,
[5],
id="one-fuzzy-message",
),
pytest.param(
[
(
'#\nmsgid ""\nmsgstr ""\n\n'
'#, fuzzy\n#~ msgid "Obsolete"\n#~ msgstr "Obsoleto"\n'
),
(
'#\nmsgid ""\nmsgstr ""\n\n'
'#, fuzzy\nmsgid "Foo"\nmsgstr "Foo es"\n\n'
'msgid "Bar"\nmsgstr "Bar es"\n'
),
],
2,
1,
[5, 5],
id="two-fuzzy-messages-in-two-files",
),
pytest.param(
['#\nmsgid ""\nmsgstr ""\n\nmsgid "Current"\nmsgstr "Actual"\n'],
0,
0,
None,
id="no-fuzzy-messages",
),
),
)
def test_check_fuzzy_messages(
quiet,
contents,
n_printed_errors,
expected_exitcode,
expected_line_numbers,
tmp_path,
):
filenames = []
for content in contents:
filename = tmp_path / f"{uuid.uuid4().hex[:16]}.po"

with open(filename, "w") as f:
f.write(content)

filenames.append(filename)

stderr = io.StringIO()
with contextlib.redirect_stderr(stderr):
assert check_fuzzy_messages(filenames, quiet=quiet) == expected_exitcode

stderr_lines = stderr.getvalue().splitlines()
if quiet:
n_printed_errors = 0
assert len(stderr_lines) == n_printed_errors

if n_printed_errors:
assert len(stderr_lines) == len(expected_line_numbers)

for i, line in enumerate(stderr_lines):
line_number = int(line.split(":")[-1])
assert line_number == expected_line_numbers[i]

for filename in filenames:
os.remove(filename)

0 comments on commit 2c9e710

Please sign in to comment.