Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Improve --no-empty-msgstr implementation #321

Merged
merged 2 commits into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions src/mdpo/md2po/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from mdpo.md2po import Md2Po
from mdpo.md4c import DEFAULT_MD4C_GENERIC_PARSER_EXTENSIONS
from mdpo.po import (
check_empty_msgstrs_in_filepaths,
check_fuzzy_entries_in_filepaths,
check_obsolete_entries_in_filepaths,
)
Expand Down Expand Up @@ -274,17 +275,22 @@ def run(args=frozenset()):
exitcode = 4

if opts.no_empty_msgstr:
for entry in pofile:
if not entry.msgstr:
if not opts.quiet:
locations = list(check_empty_msgstrs_in_filepaths(
(opts.po_filepath,),
))
if locations:
if len(locations) > 2: # noqa PLR2004
sys.stderr.write(
f'Found {len(locations)} empty msgstrs:\n',
)
for location in locations:
sys.stderr.write(f'{location}\n')
else:
for location in locations:
sys.stderr.write(
(
f"Empty msgstr found at {opts.po_filepath}"
" and passed '--no-empty-msgstr'\n"
),
f'Found empty msgstr at {location}\n',
)
exitcode = 5
break
exitcode = 5

return (pofile, exitcode)

Expand Down
25 changes: 9 additions & 16 deletions src/mdpo/md2po2md/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from mdpo.md2po import Md2Po
from mdpo.md4c import DEFAULT_MD4C_GENERIC_PARSER_EXTENSIONS
from mdpo.po import (
check_empty_msgstrs_in_filepaths,
check_fuzzy_entries_in_filepaths,
check_obsolete_entries_in_filepaths,
)
Expand All @@ -30,6 +31,7 @@
_check_saved_files_changed=False,
no_obsolete=False,
no_fuzzy=False,
no_empty_msgstr=False,
):
"""Translate a set of Markdown files using PO files.

Expand Down Expand Up @@ -78,6 +80,7 @@
``pofile_to_markdown`` function.
no_obsolete (bool): If ``True``, check for obsolete entries in PO files.
no_fuzzy (bool): If ``True``, check for fuzzy entries in PO files.
no_empty_msgstr (bool): If ``True``, check for empty ``msgstr`` entries.
"""
if '{lang}' not in output_paths_schema:
raise ValueError(
Expand Down Expand Up @@ -107,7 +110,7 @@
_saved_files_changed = None if not _check_saved_files_changed else False
obsoletes = []
fuzzies = []
empty = False
empties = []

for filepath in input_paths_glob_:
for lang in langs:
Expand Down Expand Up @@ -165,12 +168,6 @@
if _check_saved_files_changed and _saved_files_changed is False:
_saved_files_changed = md2po._saved_files_changed

if not empty:
for entry in md2po.pofile:
if not entry.msgstr:
empty = True
break

# po2md
po2md = Po2Md(
[po_filepath],
Expand Down Expand Up @@ -199,13 +196,9 @@
check_fuzzy_entries_in_filepaths([po_filepath]),
)

if not empty:
for pofile in po2md.pofiles:
for entry in pofile:
if not entry.msgstr:
empty = True
break
if empty:
break
if no_empty_msgstr:
empties.extend(

Check warning on line 200 in src/mdpo/md2po2md/__init__.py

View check run for this annotation

Codecov / codecov/patch

src/mdpo/md2po2md/__init__.py#L200

Added line #L200 was not covered by tests
check_empty_msgstrs_in_filepaths([po_filepath]),
)

return (_saved_files_changed, obsoletes, fuzzies, empty)
return (_saved_files_changed, obsoletes, fuzzies, empties)
20 changes: 13 additions & 7 deletions src/mdpo/md2po2md/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,14 @@ def run(args=frozenset()):
'_check_saved_files_changed': opts.check_saved_files_changed,
'no_obsolete': opts.no_obsolete,
'no_fuzzy': opts.no_fuzzy,
'no_empty_msgstr': opts.no_empty_msgstr,
}

(
_saved_files_changed,
obsoletes,
fuzzies,
empty,
empties,
) = markdown_to_pofile_to_markdown(
opts.langs,
opts.input_paths_glob,
Expand Down Expand Up @@ -189,14 +190,19 @@ def run(args=frozenset()):

exitcode = 4

if opts.no_empty_msgstr and empty:
exitcode = 5

if not opts.quiet:
if opts.no_empty_msgstr:
if len(empties) > 2: # noqa PLR2004
sys.stderr.write(
"Empty msgstr found at PO files and"
" passed '--no-empty-msgstr'\n",
f'Found {len(empties)} empty msgstrs:\n',
)
for location in empties:
sys.stderr.write(f'{location}\n')
else:
for location in empties:
sys.stderr.write(
f'Found empty msgstr at {location}\n',
)
exitcode = 5

return exitcode

Expand Down
27 changes: 17 additions & 10 deletions src/mdpo/mdpo2html/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from mdpo.io import environ
from mdpo.mdpo2html import MdPo2HTML
from mdpo.po import (
check_empty_msgstrs_in_filepaths,
check_fuzzy_entries_in_filepaths,
check_obsolete_entries_in_filepaths,
paths_or_globs_to_unique_pofiles,
Expand Down Expand Up @@ -168,16 +169,22 @@ def run(args=frozenset()):
exitcode = 4

if opts.no_empty_msgstr:
for pofile in mdpo2html.pofiles:
for entry in pofile:
if not entry.msgstr:
if not opts.quiet:
sys.stderr.write(
f"Empty msgstr for msgid '{entry.msgid}'"
" found at PO files and"
" passed '--no-empty-msgstr'\n",
)
exitcode = 5
locations = list(check_empty_msgstrs_in_filepaths(
(opts.po_filepath,),
))
if locations:
if len(locations) > 2: # noqa PLR2004
sys.stderr.write(
f'Found {len(locations)} empty msgstrs:\n',
)
for location in locations:
sys.stderr.write(f'{location}\n')
else:
for location in locations:
sys.stderr.write(
f'Found empty msgstr at {location}\n',
)
exitcode = 5

return (output, exitcode)

Expand Down
42 changes: 42 additions & 0 deletions src/mdpo/po.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,25 @@ def check_fuzzy_entries_in_filepaths(filenames):
)


def check_empty_msgstrs_in_filepaths(filenames):
"""Warns about all empty msgstr found in a set of PO files.

Args:
filenames (list): Set of file names to check.

Returns:
list(str): error messages produced.
"""
for filename in filenames:
with open(filename, 'rb') as f:
content_lines = f.readlines()

yield from parse_empty_msgstr_from_content_lines(
content_lines,
location_prefix=f'{filename}:',
)


def parse_obsoletes_from_content_lines(
content_lines,
location_prefix='line ',
Expand Down Expand Up @@ -247,3 +266,26 @@ def parse_fuzzy_from_content_lines(
for i, line in enumerate(content_lines):
if line.startswith(b'#,') and b'fuzzy' in line:
yield f'{location_prefix}{i + 1}'


def parse_empty_msgstr_from_content_lines(
content_lines,
location_prefix='line ',
):
"""Warns about all empty msgstr found in a set of PO files.

Args:
content_lines (list): Set of content lines to check.
location_prefix (str): Prefix to use in the location message.

Returns:
list(str): error locations found.
"""
n_lines = len(content_lines)
for i, line in enumerate(content_lines):
if (
line.startswith(b'msgstr ""') or line.startswith(b'#~ msgstr ""')
) and not content_lines[i - 1].startswith(b'msgid ""'):
next_i = i + 1
if next_i == n_lines or not content_lines[next_i].strip():
yield f'{location_prefix}{next_i}'
28 changes: 17 additions & 11 deletions src/mdpo/po2md/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
)
from mdpo.io import environ
from mdpo.po import (
check_empty_msgstrs_in_filepaths,
check_fuzzy_entries_in_filepaths,
check_obsolete_entries_in_filepaths,
paths_or_globs_to_unique_pofiles,
Expand Down Expand Up @@ -192,17 +193,22 @@ def run(args=frozenset()):
exitcode = 4

if opts.no_empty_msgstr:
for pofile in po2md.pofiles:
for entry in pofile:
if not entry.msgstr:
if not opts.quiet:
sys.stderr.write(
(
f"Empty msgstr found at {opts.po_filepath}"
" and passed '--no-empty-msgstr'\n"
),
)
exitcode = 5
locations = list(check_empty_msgstrs_in_filepaths(
(opts.po_filepath,),
))
if locations:
if len(locations) > 2: # noqa PLR2004
sys.stderr.write(
f'Found {len(locations)} empty msgstrs:\n',
)
for location in locations:
sys.stderr.write(f'{location}\n')
else:
for location in locations:
sys.stderr.write(
f'Found empty msgstr at {location}\n',
)
exitcode = 5

return (output, exitcode)

Expand Down
14 changes: 7 additions & 7 deletions tests/test_unit/test_md2po/test_md2po_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -893,14 +893,14 @@ def test_no_empty_mgstr(capsys, arg, tmp_file):

with tmp_file(po_input, '.po') as filename:
pofile, exitcode = run([arg, '-p', filename, '--no-location', 'Hello'])
stdout, stderr = capsys.readouterr()
stdout, stderr = capsys.readouterr()

assert exitcode == 5
assert f'{pofile}\n' == po_input
assert stdout == po_input
assert stderr == (
f"Empty msgstr found at {filename} and passed '--no-empty-msgstr'\n"
)
assert exitcode == 5
assert f'{pofile}\n' == po_input
assert stdout == po_input
assert stderr == (
f'Found empty msgstr at {filename}:6\n'
)

po_input = '''#
msgid ""
Expand Down
Loading