mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-24 11:21:25 -07:00
If we can't squash for any reason, then simply do not optimize the items loop.
Also add more squashing testcases Fixes #15649
This commit is contained in:
parent
8a184381af
commit
292f0ed0d6
2 changed files with 124 additions and 81 deletions
|
@ -269,59 +269,64 @@ class TaskExecutor:
|
|||
Squash items down to a comma-separated list for certain modules which support it
|
||||
(typically package management modules).
|
||||
'''
|
||||
# _task.action could contain templatable strings (via action: and
|
||||
# local_action:) Template it before comparing. If we don't end up
|
||||
# optimizing it here, the templatable string might use template vars
|
||||
# that aren't available until later (it could even use vars from the
|
||||
# with_items loop) so don't make the templated string permanent yet.
|
||||
templar = Templar(loader=self._loader, shared_loader_obj=self._shared_loader_obj, variables=variables)
|
||||
task_action = self._task.action
|
||||
if templar._contains_vars(task_action):
|
||||
task_action = templar.template(task_action, fail_on_undefined=False)
|
||||
try:
|
||||
# _task.action could contain templatable strings (via action: and
|
||||
# local_action:) Template it before comparing. If we don't end up
|
||||
# optimizing it here, the templatable string might use template vars
|
||||
# that aren't available until later (it could even use vars from the
|
||||
# with_items loop) so don't make the templated string permanent yet.
|
||||
templar = Templar(loader=self._loader, shared_loader_obj=self._shared_loader_obj, variables=variables)
|
||||
task_action = self._task.action
|
||||
if templar._contains_vars(task_action):
|
||||
task_action = templar.template(task_action, fail_on_undefined=False)
|
||||
|
||||
if len(items) > 0 and task_action in self.SQUASH_ACTIONS:
|
||||
if all(isinstance(o, string_types) for o in items):
|
||||
final_items = []
|
||||
if len(items) > 0 and task_action in self.SQUASH_ACTIONS:
|
||||
if all(isinstance(o, string_types) for o in items):
|
||||
final_items = []
|
||||
|
||||
name = None
|
||||
for allowed in ['name', 'pkg', 'package']:
|
||||
name = self._task.args.pop(allowed, None)
|
||||
if name is not None:
|
||||
break
|
||||
name = None
|
||||
for allowed in ['name', 'pkg', 'package']:
|
||||
name = self._task.args.pop(allowed, None)
|
||||
if name is not None:
|
||||
break
|
||||
|
||||
# This gets the information to check whether the name field
|
||||
# contains a template that we can squash for
|
||||
template_no_item = template_with_item = None
|
||||
if name:
|
||||
if templar._contains_vars(name):
|
||||
variables[loop_var] = '\0$'
|
||||
template_no_item = templar.template(name, variables, cache=False)
|
||||
variables[loop_var] = '\0@'
|
||||
template_with_item = templar.template(name, variables, cache=False)
|
||||
del variables[loop_var]
|
||||
# This gets the information to check whether the name field
|
||||
# contains a template that we can squash for
|
||||
template_no_item = template_with_item = None
|
||||
if name:
|
||||
if templar._contains_vars(name):
|
||||
variables[loop_var] = '\0$'
|
||||
template_no_item = templar.template(name, variables, cache=False)
|
||||
variables[loop_var] = '\0@'
|
||||
template_with_item = templar.template(name, variables, cache=False)
|
||||
del variables[loop_var]
|
||||
|
||||
# Check if the user is doing some operation that doesn't take
|
||||
# name/pkg or the name/pkg field doesn't have any variables
|
||||
# and thus the items can't be squashed
|
||||
if template_no_item != template_with_item:
|
||||
for item in items:
|
||||
variables[loop_var] = item
|
||||
if self._task.evaluate_conditional(templar, variables):
|
||||
new_item = templar.template(name, cache=False)
|
||||
final_items.append(new_item)
|
||||
self._task.args['name'] = final_items
|
||||
# Wrap this in a list so that the calling function loop
|
||||
# executes exactly once
|
||||
return [final_items]
|
||||
else:
|
||||
# Restore the name parameter
|
||||
self._task.args['name'] = name
|
||||
#elif:
|
||||
# Right now we only optimize single entries. In the future we
|
||||
# could optimize more types:
|
||||
# * lists can be squashed together
|
||||
# * dicts could squash entries that match in all cases except the
|
||||
# name or pkg field.
|
||||
# Check if the user is doing some operation that doesn't take
|
||||
# name/pkg or the name/pkg field doesn't have any variables
|
||||
# and thus the items can't be squashed
|
||||
if template_no_item != template_with_item:
|
||||
for item in items:
|
||||
variables[loop_var] = item
|
||||
if self._task.evaluate_conditional(templar, variables):
|
||||
new_item = templar.template(name, cache=False)
|
||||
final_items.append(new_item)
|
||||
self._task.args['name'] = final_items
|
||||
# Wrap this in a list so that the calling function loop
|
||||
# executes exactly once
|
||||
return [final_items]
|
||||
else:
|
||||
# Restore the name parameter
|
||||
self._task.args['name'] = name
|
||||
#elif:
|
||||
# Right now we only optimize single entries. In the future we
|
||||
# could optimize more types:
|
||||
# * lists can be squashed together
|
||||
# * dicts could squash entries that match in all cases except the
|
||||
# name or pkg field.
|
||||
except:
|
||||
# Squashing is an optimization. If it fails for any reason,
|
||||
# simply use the unoptimized list of items.
|
||||
pass
|
||||
return items
|
||||
|
||||
def _execute(self, variables=None):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue