Skip to content

Commit

Permalink
Add hook to define a minimum number or percentage of translation in f…
Browse files Browse the repository at this point in the history
…iles
  • Loading branch information
mondeja committed Jun 6, 2021
1 parent 416f4bf commit f4a3980
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 11 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.4.0
current_version = 1.5.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 @@ -46,3 +46,9 @@
description: Checks that each one of your PO files don't contain more than X messages
files: \.po$
language: python
- id: min-translated
name: min-translated
entry: untranslated-messages-hook --min
description: Checks that each one of your PO files has at least a number or a parcentage of messages translated
files: \.po$
language: python
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Hooks for pre-commit useful working with PO files.

```yaml
- repo: https://github.com/mondeja/pre-commit-po-hooks
rev: v1.4.0
rev: v1.5.0
hooks:
- id: obsolete-messages
- id: untranslated-messages
Expand All @@ -29,6 +29,12 @@ Checks for obsolete messages printing their line numbers if found.

Checks for untranslated messages printing their line numbers if found.

#### Parameters

- `-m/--min`: Minimum number of messages that must be translated in each file
to pass this check. Can be defined as a percentage of the messages translated
appending a character `%` at the end of the value.

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

Replaces a matching string at the beginning of extracted comments.
Expand Down Expand Up @@ -112,6 +118,23 @@ first argument:

- Maximum number of messages allowed for each PO file.

### **`min-translated`**

Define a minimum number of files that must be translated in order to pass.
Pass a float or a value ending with `%` character if you wan to compare
against the percentage of translated files:

```yaml
- id: min-translated
args:
- "95%"
```

#### Parameters

- Minimum number or percentage of messages which must be translated in each
PO file.


[pypi-link]: https://pypi.org/project/pre-commit-po-hooks
[pypi-version-badge-link]: https://img.shields.io/pypi/v/pre-commit-po-hooks
Expand Down
3 changes: 3 additions & 0 deletions hooks/check_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def main():
return maximum_number_of_messages(
args.filenames, args.max_messages, quiet=args.quiet
)
else:
parser.print_help()
return 1


if __name__ == "__main__":
Expand Down
64 changes: 59 additions & 5 deletions hooks/untranslated_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sys


def check_untranslated_messages(filenames, quiet=False):
def check_untranslated_messages(filenames, min_=None, quiet=False):
"""Warns about all unstranslated messages found in a set of PO files.
Parameters
Expand All @@ -24,6 +24,8 @@ def check_untranslated_messages(filenames, quiet=False):
int: 0 if no untranslated messages found, 1 otherwise.
"""
min_string = str(min_ if min_ is not None else 0)

exitcode = 0
for filename in filenames:
with open(filename) as f:
Expand All @@ -32,17 +34,50 @@ def check_untranslated_messages(filenames, quiet=False):
if len(content_lines) > 4: # skip first empty message
content_lines = content_lines[4:]

untranslated_messages, total_messages = 0, -1

for i, line in enumerate(content_lines):
next_i = i + 1

if line.startswith('msgid "'):
total_messages += 1

if line.startswith('msgstr ""') and (
next_i == len(content_lines) or (not content_lines[next_i].strip())
):
exitcode = 1
untranslated_messages += 1
if not quiet and min_ is None:
sys.stderr.write(f"Untranslated message at {filename}:{i + 5}\n")

if min_ is not None:
_is_percent = False
if min_string[-1] == "%":
min_float = total_messages / 100 * float(min_string[:-1])
_is_percent = True
else:
min_float = float(min)

translated_messages = total_messages - untranslated_messages
if min_float > translated_messages:
exitcode = 1
if not quiet:
sys.stderr.write(
f"Found untranslated message at {filename}:{i + 5}\n"
)
if _is_percent:
translation_percent = max(
100,
translated_messages / max(1, total_messages) * 100,
)
sys.stderr.write(
"Lower percent of translation"
f" ({round(translation_percent, 3)}) than minimum"
f" required ({min_string}) at file {filename}\n"
)
else:
sys.stderr.write(
"Lower number of messages translated"
f" ({translated_messages}) than required"
f" ({min_string}) at file {filename}\n"
)

return exitcode

Expand All @@ -52,9 +87,28 @@ def main():
parser.add_argument(
"filenames", nargs="*", help="Filenames to check for untranslated messages"
)
parser.add_argument(
"-m",
"--min",
type=str,
metavar="N/N%",
required=False,
default=None,
dest="min",
help=(
"Minimum messages translated in each PO file to be considered valid."
" You can pass either a float number optionally ending in a character"
" % to indicate that is a percentage of the total of translated"
" entries in each PO file."
),
)
parser.add_argument("-q", "--quiet", action="store_true", help="Supress output")
args = parser.parse_args()
return check_untranslated_messages(args.filenames, quiet=args.quiet)
return check_untranslated_messages(
args.filenames,
min_=args.min,
quiet=args.quiet,
)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 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.4.0
version = 1.5.0
description = pre-commit hooks for PO files
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down
15 changes: 12 additions & 3 deletions tests/test_untranslated_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from hooks.untranslated_messages import check_untranslated_messages


@pytest.mark.parametrize("min_", ("100%", None), ids=("min_=100%", "min=None"))
@pytest.mark.parametrize("quiet", (False, True), ids=("quiet=False", "quiet=True"))
@pytest.mark.parametrize(
("contents", "n_printed_errors", "expected_exitcode", "expected_line_numbers"),
Expand Down Expand Up @@ -47,6 +48,7 @@ def test_check_untranslated_messages(
n_printed_errors,
expected_exitcode,
expected_line_numbers,
min_,
tmp_path,
):
filenames = []
Expand All @@ -60,7 +62,10 @@ def test_check_untranslated_messages(

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

stderr_lines = stderr.getvalue().splitlines()
if quiet:
Expand All @@ -71,8 +76,12 @@ def test_check_untranslated_messages(
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]
try:
line_number = int(line.split(":")[-1])
except ValueError:
continue
else:
assert line_number == expected_line_numbers[i]

for filename in filenames:
os.remove(filename)

0 comments on commit f4a3980

Please sign in to comment.