Skip to content

Commit fd278bc

Browse files
akxkinshukdua
andcommitted
Add frontend for extract directory filter
Co-authored-by: Kinshuk Dua <[email protected]>
1 parent d8fc05b commit fd278bc

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

babel/messages/frontend.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"""
1111
from __future__ import print_function
1212

13+
import fnmatch
1314
import logging
1415
import optparse
1516
import os
@@ -256,6 +257,20 @@ def _run_domain(self, domain):
256257
return catalogs_and_errors
257258

258259

260+
def _make_directory_filter(ignore_patterns):
261+
"""
262+
Build a directory_filter function based on a list of ignore patterns.
263+
"""
264+
def cli_directory_filter(dirname):
265+
basename = os.path.basename(dirname)
266+
return not any(
267+
fnmatch.fnmatch(basename, ignore_pattern)
268+
for ignore_pattern
269+
in ignore_patterns
270+
)
271+
return cli_directory_filter
272+
273+
259274
class extract_messages(Command):
260275
"""Message extraction command for use in ``setup.py`` scripts.
261276
@@ -320,13 +335,20 @@ class extract_messages(Command):
320335
'files or directories with commas(,)'), # TODO: Support repetition of this argument
321336
('input-dirs=', None, # TODO (3.x): Remove me.
322337
'alias for input-paths (does allow files as well as directories).'),
338+
('ignore-dirs=', None,
339+
'Patterns for directories to ignore when scanning for messages. '
340+
'Separate multiple patterns with spaces (default ".* ._")'),
323341
]
324342
boolean_options = [
325343
'no-default-keywords', 'no-location', 'omit-header', 'no-wrap',
326344
'sort-output', 'sort-by-file', 'strip-comments'
327345
]
328346
as_args = 'input-paths'
329-
multiple_value_options = ('add-comments', 'keywords')
347+
multiple_value_options = (
348+
'add-comments',
349+
'keywords',
350+
'ignore-dirs',
351+
)
330352
option_aliases = {
331353
'keywords': ('--keyword',),
332354
'mapping-file': ('--mapping',),
@@ -359,6 +381,7 @@ def initialize_options(self):
359381
self.add_comments = None
360382
self.strip_comments = False
361383
self.include_lineno = True
384+
self.ignore_dirs = None
362385

363386
def finalize_options(self):
364387
if self.input_dirs:
@@ -427,6 +450,13 @@ def finalize_options(self):
427450
elif self.add_location == 'file':
428451
self.include_lineno = False
429452

453+
ignore_dirs = listify_value(self.ignore_dirs)
454+
if ignore_dirs:
455+
self.directory_filter = _make_directory_filter(self.ignore_dirs)
456+
else:
457+
self.directory_filter = None
458+
459+
430460
def run(self):
431461
mappings = self._get_mappings()
432462
with open(self.output_file, 'wb') as outfile:
@@ -469,7 +499,8 @@ def callback(filename, method, options):
469499
keywords=self.keywords,
470500
comment_tags=self.add_comments,
471501
callback=callback,
472-
strip_comment_tags=self.strip_comments
502+
strip_comment_tags=self.strip_comments,
503+
directory_filter=self.directory_filter,
473504
)
474505
for filename, lineno, message, comments, context in extracted:
475506
if os.path.isfile(path):
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from gettext import gettext
2+
3+
4+
def foo():
5+
print(gettext('ssshhh....'))

tests/messages/test_frontend.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,3 +1431,26 @@ def test_extract_error_code(monkeypatch, capsys):
14311431
if err:
14321432
# replace hack below for py2/py3 compatibility
14331433
assert "unknown named placeholder 'merkki'" in err.replace("u'", "'")
1434+
1435+
1436+
@pytest.mark.parametrize("with_underscore_ignore", (False, True))
1437+
def test_extract_ignore_dirs(monkeypatch, capsys, tmp_path, with_underscore_ignore):
1438+
pot_file = tmp_path / 'temp.pot'
1439+
monkeypatch.chdir(project_dir)
1440+
cmd = "extract . -o '{}' --ignore-dirs '*ignored*' ".format(pot_file)
1441+
if with_underscore_ignore:
1442+
# This also tests that multiple arguments are supported.
1443+
cmd += "--ignore-dirs '_*'"
1444+
cmdinst = configure_cli_command(cmd)
1445+
assert isinstance(cmdinst, extract_messages)
1446+
assert cmdinst.directory_filter
1447+
cmdinst.run()
1448+
pot_content = pot_file.read_text()
1449+
1450+
# The `ignored` directory is now actually ignored:
1451+
assert 'this_wont_normally_be_here' not in pot_content
1452+
1453+
# Since we manually set a filter, the otherwise `_hidden` directory is walked into,
1454+
# unless we opt in to ignore it again
1455+
assert ('ssshhh....' in pot_content) != with_underscore_ignore
1456+
assert ('_hidden_by_default' in pot_content) != with_underscore_ignore

0 commit comments

Comments
 (0)