From 1a4b20f46c8d9f87b9888e31ccbdc60f6e5b4014 Mon Sep 17 00:00:00 2001 From: robcxyz Date: Sat, 3 Dec 2022 00:24:37 +0530 Subject: [PATCH] provider: add glob hook --- tackle/providers/paths/hooks/globs.py | 62 +++++++++++++++++++ tackle/providers/paths/tests/glob.yaml | 1 + .../paths/tests/test_provider_system_path.py | 6 ++ 3 files changed, 69 insertions(+) create mode 100644 tackle/providers/paths/hooks/globs.py create mode 100644 tackle/providers/paths/tests/glob.yaml diff --git a/tackle/providers/paths/hooks/globs.py b/tackle/providers/paths/hooks/globs.py new file mode 100644 index 000000000..5077d1073 --- /dev/null +++ b/tackle/providers/paths/hooks/globs.py @@ -0,0 +1,62 @@ +import sys +import glob + +from tackle.models import BaseHook, Field +from tackle import exceptions + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from tackle.models import Context + + +def raise_version_error_msg(field_name, version: int, context: 'Context'): + raise exceptions.HookCallException( + f"The field={field_name} in the glob hook not available in version 3.{version}", + context=context, + ) from None + + +class GlobHook(BaseHook): + """ + Hook for running python's glob module. Return a possibly empty list of path names + that match pathname, which must be a string containing a path specification. + """ + + hook_type: str = 'glob' + pathname: str = Field(..., description="The path to file or directory") + root_dir: str = Field(None, description="The root dir to run glob from.") + dir_fd: int = Field( + None, + description="Similar to root_dir, but it specifies the root directory as an " + "open directory descriptor instead of a path", + ) + recursive: bool = Field(False, description="Search underlying directories.") + include_hidden: bool = Field(False, description="Include hidden files / dirs.") + + args: list = ['pathname'] + + def exec(self) -> list: + options = { + 'recursive': self.recursive, + } + + if sys.version_info.major >= 10: + options['root_dir'] = self.root_dir + options['dir_fd'] = self.dir_fd + else: + if self.root_dir is not None: + raise_version_error_msg('root_dir', 10, self) + if self.dir_fd is not None: + raise_version_error_msg('dir_fd', 10, self) + + if sys.version_info.major >= 11: + options['include_hidden'] = self.include_hidden + else: + if self.include_hidden: + raise_version_error_msg('include_hidden', 11, self) + + return glob.glob( + self.pathname, + **options, + ) diff --git a/tackle/providers/paths/tests/glob.yaml b/tackle/providers/paths/tests/glob.yaml new file mode 100644 index 000000000..a86c09030 --- /dev/null +++ b/tackle/providers/paths/tests/glob.yaml @@ -0,0 +1 @@ +g->: glob * \ No newline at end of file diff --git a/tackle/providers/paths/tests/test_provider_system_path.py b/tackle/providers/paths/tests/test_provider_system_path.py index 764d915d8..69907adcd 100644 --- a/tackle/providers/paths/tests/test_provider_system_path.py +++ b/tackle/providers/paths/tests/test_provider_system_path.py @@ -28,3 +28,9 @@ def test_provider_paths_base_dir_name(change_dir): assert output['base'] == 'tests' assert 'paths' in output['dir'] + + +def test_provider_paths_glob(change_dir): + output = tackle('glob.yaml') + + assert 'dirs' in output['g']