Adds `limit` parameter to `ansible.builtin.find` (#83153)

* Explicitly guarantee topdown search.
* Makes max matches unlimited == None.
pull/83574/head
Colin Nolan 5 months ago committed by GitHub
parent 1c156e2b70
commit a0aad17912
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -154,6 +154,14 @@ options:
- When doing a O(contains) search, determine the encoding of the files to be searched.
type: str
version_added: "2.17"
limit:
description:
- Limit the maximum number of matching paths returned. After finding this many, the find action will stop looking.
- Matches are made from the top, down (i.e. shallowest directory first).
- If not set, or set to v(null), it will do unlimited matches.
- Default is unlimited matches.
type: int
version_added: "2.18"
extends_documentation_fragment: action_common_attributes
attributes:
check_mode:
@ -227,6 +235,16 @@ EXAMPLES = r'''
- '^_[0-9]{2,4}_.*.log$'
- '^[a-z]{1,5}_.*log$'
- name: Find file containing "wally" without necessarily reading all files
ansible.builtin.find:
paths: /var/log
file_type: file
contains: wally
read_whole_file: true
patterns: "^.*\\.log$"
use_regex: true
recurse: true
limit: 1
'''
RETURN = r'''
@ -467,7 +485,8 @@ def main():
depth=dict(type='int'),
mode=dict(type='raw'),
exact_mode=dict(type='bool', default=True),
encoding=dict(type='str')
encoding=dict(type='str'),
limit=dict(type='int')
),
supports_check_mode=True,
)
@ -520,6 +539,9 @@ def main():
else:
module.fail_json(size=params['size'], msg="failed to process size")
if params['limit'] is not None and params['limit'] <= 0:
module.fail_json(msg="limit cannot be %d (use None for unlimited)" % params['limit'])
now = time.time()
msg = 'All paths examined'
looked = 0
@ -530,7 +552,8 @@ def main():
if not os.path.isdir(npath):
raise Exception("'%s' is not a directory" % to_native(npath))
for root, dirs, files in os.walk(npath, onerror=handle_walk_errors, followlinks=params['follow']):
# Setting `topdown=True` to explicitly guarantee matches are made from the shallowest directory first
for root, dirs, files in os.walk(npath, onerror=handle_walk_errors, followlinks=params['follow'], topdown=True):
looked = looked + len(files) + len(dirs)
for fsobj in (files + dirs):
fsname = os.path.normpath(os.path.join(root, fsobj))
@ -596,7 +619,12 @@ def main():
r.update(statinfo(st))
filelist.append(r)
if not params['recurse']:
if len(filelist) == params["limit"]:
# Breaks out of directory files loop only
msg = "Limit of matches reached"
break
if not params['recurse'] or len(filelist) == params["limit"]:
break
except Exception as e:
skipped[npath] = to_text(e)

Loading…
Cancel
Save