Merge pull request #49837 from mchugh19/2747

Support list for include_pat/exclude_pat in file.recurse
This commit is contained in:
Nicole Thomas 2018-10-10 09:34:41 -04:00 committed by GitHub
commit c1b6706011
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 22 deletions

View File

@ -3636,8 +3636,8 @@ def recurse(name,
:ref:`backup_mode documentation <file-state-backups>` for more details.
include_pat
When copying, include only this pattern from the source. Default
is glob match; if prefixed with 'E@', then regexp match.
When copying, include only this pattern, or list of patterns, from the
source. Default is glob match; if prefixed with 'E@', then regexp match.
Example:
.. code-block:: text
@ -3647,9 +3647,19 @@ def recurse(name,
- include_pat: E@hello :: regexp matches 'otherhello',
'hello01' ...
.. versionchanged:: Neon
List patterns are now supported
.. code-block:: text
- include_pat:
- hello01
- hello02
exclude_pat
Exclude this pattern from the source when copying. If both
`include_pat` and `exclude_pat` are supplied, then it will apply
Exclude this pattern, or list of patterns, from the source when copying.
If both `include_pat` and `exclude_pat` are supplied, then it will apply
conditions cumulatively. i.e. first select based on include_pat, and
then within that result apply exclude_pat.
@ -3664,6 +3674,15 @@ def recurse(name,
- exclude_pat: E@(APPDATA)|(TEMPDATA) :: regexp matches APPDATA
or TEMPDATA for exclusion
.. versionchanged:: Neon
List patterns are now supported
.. code-block:: text
- exclude_pat:
- APPDATA.01
- APPDATA.02
maxdepth
When copying, only copy paths which are of depth `maxdepth` from the
source path.

View File

@ -450,31 +450,37 @@ def check_include_exclude(path_str, include_pat=None, exclude_pat=None):
- If both include_pat and exclude_pat are supplied: return 'True' if
include_pat matches AND exclude_pat does not match
'''
def _pat_check(path_str, check_pat):
if re.match('E@', check_pat):
return True if re.search(
check_pat[2:],
path_str
) else False
else:
return True if fnmatch.fnmatch(
path_str,
check_pat
) else False
ret = True # -- default true
# Before pattern match, check if it is regexp (E@'') or glob(default)
if include_pat:
if re.match('E@', include_pat):
retchk_include = True if re.search(
include_pat[2:],
path_str
) else False
if isinstance(include_pat, list):
for include_line in include_pat:
retchk_include = _pat_check(path_str, include_line)
if retchk_include:
break
else:
retchk_include = True if fnmatch.fnmatch(
path_str,
include_pat
) else False
retchk_include = _pat_check(path_str, include_pat)
if exclude_pat:
if re.match('E@', exclude_pat):
retchk_exclude = False if re.search(
exclude_pat[2:],
path_str
) else True
if isinstance(exclude_pat, list):
for exclude_line in exclude_pat:
retchk_exclude = not _pat_check(path_str, exclude_line)
if not retchk_exclude:
break
else:
retchk_exclude = False if fnmatch.fnmatch(
path_str,
exclude_pat
) else True
retchk_exclude = not _pat_check(path_str, exclude_pat)
# Now apply include/exclude conditions
if include_pat and not exclude_pat:

View File

@ -548,3 +548,18 @@ class StringutilsTestCase(TestCase):
salt.utils.stringutils.check_whitelist_blacklist,
'foo', blacklist=123
)
def test_check_include_exclude_empty(self):
self.assertTrue(salt.utils.stringutils.check_include_exclude("/some/test"))
def test_check_include_exclude_exclude(self):
self.assertFalse(salt.utils.stringutils.check_include_exclude("/some/test", None, "*test*"))
def test_check_include_exclude_exclude_list(self):
self.assertFalse(salt.utils.stringutils.check_include_exclude("/some/test", None, ["*test"]))
def test_check_include_exclude_exclude_include(self):
self.assertTrue(salt.utils.stringutils.check_include_exclude("/some/test", "*test*", "/some/"))
def test_check_include_exclude_regex(self):
self.assertFalse(salt.utils.stringutils.check_include_exclude("/some/test", None, "E@/some/(test|other)"))