Skip to content
Open
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
5 changes: 4 additions & 1 deletion babel/messages/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def extract_from_dir(
callback: Callable[[str, str, dict[str, Any]], object] | None = None,
strip_comment_tags: bool = False,
directory_filter: Callable[[str], bool] | None = None,
follow_links: bool = False,
) -> Generator[_FileExtractionResult, None, None]:
"""Extract messages from any source files found in the given directory.

Expand Down Expand Up @@ -194,6 +195,8 @@ def extract_from_dir(
:param directory_filter: a callback to determine whether a directory should
be recursed into. Receives the full directory path;
should return True if the directory is valid.
:param follow_links: Whether symbolic links should be followed in OS's that
support them. By default they are not followed.
:see: `pathmatch`
"""
if dirname is None:
Expand All @@ -204,7 +207,7 @@ def extract_from_dir(
directory_filter = default_directory_filter

absname = os.path.abspath(dirname)
for root, dirnames, filenames in os.walk(absname):
for root, dirnames, filenames in os.walk(absname, followlinks=follow_links):
dirnames[:] = [
subdir for subdir in dirnames
if directory_filter(os.path.join(root, subdir))
Expand Down
6 changes: 5 additions & 1 deletion babel/messages/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,12 @@ class ExtractMessages(CommandMixin):
'header comment for the catalog'),
('last-translator=', None,
'set the name and email of the last translator in output'),
('follow-links', 'l',
'follow symbolic links when traversing directories'),
]
boolean_options = [
'no-default-keywords', 'no-location', 'omit-header', 'no-wrap',
'sort-output', 'sort-by-file', 'strip-comments',
'sort-output', 'sort-by-file', 'strip-comments', 'follow-links',
]
as_args = 'input-paths'
multiple_value_options = (
Expand Down Expand Up @@ -381,6 +383,7 @@ def initialize_options(self):
self.version = None
self.add_comments = None
self.strip_comments = False
self.follow_links = False
self.include_lineno = True
self.ignore_dirs = None
self.header_comment = None
Expand Down Expand Up @@ -509,6 +512,7 @@ def run(self):
callback=callback,
strip_comment_tags=self.strip_comments,
directory_filter=self.directory_filter,
follow_links=self.follow_links,
)
for filename, lineno, message, comments, context in extracted:
if os.path.isfile(path):
Expand Down
2 changes: 2 additions & 0 deletions docs/cmdline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ a collection of source files::
Patterns for directories to ignore when scanning for
messages. Separate multiple patterns with spaces
(default ".* ._")
-f, --follow-links
follow symbolic links when traversing directories
--header-comment=HEADER_COMMENT
header comment for the catalog

Expand Down
7 changes: 7 additions & 0 deletions tests/messages/test_frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,13 @@ def test_extract_cli_knows_dash_s():
assert cmdinst.strip_comments


def test_extract_cli_knows_follow_links():
# This tests the follow-links command line argument
cmdinst = configure_cli_command("extract --follow-links -o foo babel")
assert isinstance(cmdinst, ExtractMessages)
assert cmdinst.follow_links


def test_extract_cli_knows_dash_dash_last_dash_translator():
cmdinst = configure_cli_command('extract --last-translator "FULL NAME EMAIL@ADDRESS" -o foo babel')
assert isinstance(cmdinst, ExtractMessages)
Expand Down