Skip to content

Commit 103f243

Browse files
fix(localize): Allow empty xgettext extraction
If xgettext produces no messages, x_extract now detects that the .pot/.po file wasn't created, prints a notice and returns early instead of attempting to rewrite the header. Adds a unit test to verify extraction succeeds when xgettext writes no messages and no template file is produced. This prevents errors when projects have no translatable strings.
1 parent c049430 commit 103f243

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

scripts/localize.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,10 @@ def x_extract(context: LocaleContext):
509509
]
510510

511511
run_command(command=command, root_dir=context.root_dir)
512+
if not os.path.exists(pot_filepath):
513+
print(f'No gettext messages found; {pot_filepath} was not generated.')
514+
return
515+
512516
rewrite_pot_header(context=context, pot_filepath=pot_filepath)
513517

514518

tests/unit/test_localize.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,53 @@ def fake_check_output(args, cwd):
426426
)
427427

428428

429+
def test_x_extract_allows_empty_extraction(monkeypatch, tmp_path):
430+
"""Verify extraction succeeds when xgettext has no messages to write."""
431+
432+
root_dir = str(tmp_path)
433+
os.makedirs(os.path.join(root_dir, 'src'))
434+
with open(os.path.join(root_dir, 'src', 'main.cpp'), mode='w', encoding='utf-8') as file:
435+
file.write('int main() { return 0; }\n')
436+
437+
context = localize.build_context(args=parse_args('--root-dir', root_dir, '--project-name', 'Example'))
438+
calls = []
439+
440+
def fake_check_output(args, cwd):
441+
"""Record xgettext calls without creating a template file."""
442+
443+
calls.append({
444+
'args': args,
445+
'cwd': cwd,
446+
})
447+
448+
monkeypatch.setattr(localize.subprocess, 'check_output', fake_check_output)
449+
450+
localize.x_extract(context=context)
451+
452+
assert calls == [
453+
{
454+
'args': [
455+
'xgettext',
456+
*[f'--keyword={keyword}' for keyword in localize.DEFAULT_KEYWORDS],
457+
'--default-domain=example',
458+
f'--output={os.path.join(context.locale_dir, "example.po")}',
459+
'--language=C++',
460+
'--boost',
461+
'--from-code=utf-8',
462+
'-F',
463+
'--msgid-bugs-address=https://github.com/Example/Example',
464+
'--copyright-holder=Example',
465+
'--package-name=Example',
466+
'--package-version=v0',
467+
os.path.join('src', 'main.cpp'),
468+
],
469+
'cwd': root_dir,
470+
},
471+
]
472+
assert os.path.isdir(context.locale_dir)
473+
assert not os.path.exists(os.path.join(context.locale_dir, 'example.po'))
474+
475+
429476
def test_x_extract_requires_source_files(tmp_path):
430477
"""Verify extraction fails clearly when no source files are found."""
431478

0 commit comments

Comments
 (0)