[master] Porting #49837 to master (#54552)

* Porting PR #49837 to 2019.2.1

* Fixing versionchanged

Fixing versionchanged

* Fixing black issues and docstring issues.

* Another doc fix.

Co-authored-by: Daniel Wozniak <dwozniak@saltstack.com>
This commit is contained in:
Gareth J. Greenaway 2020-04-29 15:25:09 -07:00 committed by GitHub
parent ce45306f7f
commit 7c37be44eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 10 deletions

View file

@ -4097,8 +4097,8 @@ def recurse(
: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
@ -4108,9 +4108,19 @@ def recurse(
- include_pat: E@hello :: regexp matches 'otherhello',
'hello01' ...
.. versionchanged:: Sodium
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.
@ -4125,6 +4135,16 @@ def recurse(
- exclude_pat: E@(APPDATA)|(TEMPDATA) :: regexp matches APPDATA
or TEMPDATA for exclusion
.. versionchanged:: Sodium
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.
@ -4169,6 +4189,7 @@ def recurse(
True to inherit permissions from parent, otherwise False
.. versionadded:: 2017.7.7
"""
if "env" in kwargs:
# "env" is not supported; Use "saltenv".

View file

@ -466,19 +466,32 @@ 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

@ -535,3 +535,30 @@ class StringutilsTestCase(TestCase):
"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)"
)
)