Refactored main parse method

This commit is contained in:
Emmanuel BENOîT 2022-09-18 17:57:21 +02:00
parent 4a56566c58
commit 28f1d3308a
No known key found for this signature in database
GPG key ID: 2356DC6956CF54EF

View file

@ -317,49 +317,78 @@ class RcInstruction(abc.ABC):
raise AnsibleParserError( raise AnsibleParserError(
"%s: unsupported fields: %s" % (self._action, ", ".join(extra_fields)) "%s: unsupported fields: %s" % (self._action, ", ".join(extra_fields))
) )
# Extract the condition # Extract the loop, condition and local variable clauses
if "when" in record: self.parse_condition(record)
if not isinstance(record["when"], string_types): self.parse_loop(record)
raise AnsibleParserError(
"%s: 'when' clause is not a string" % (self._action,)
)
self._condition = record["when"]
# Extract the loop data and configuration
if "loop" in record:
loop = record["loop"]
if not isinstance(loop, string_types + (list,)):
raise AnsibleParserError(
"%s: 'loop' clause is neither a string nor a list" % (self._action,)
)
loop_var = record.get("loop_var", RcInstruction.DEFAULT_LOOP_VAR)
if not isinstance(loop_var, string_types):
raise AnsibleParserError(
"%s: 'loop_var' clause is not a string" % (self._action,)
)
if not isidentifier(loop_var):
raise AnsibleParserError(
"%s: 'loop_var' value '%s' is not a valid identifier"
% (self._action, loop_var)
)
self._loop = loop
self._loop_var = loop_var
elif "loop_var" in record:
raise AnsibleParserError(
"%s: 'loop_var' clause found without 'loop'" % (self._action,)
)
# Extract local variables
self._vars = self.parse_vars(record) self._vars = self.parse_vars(record)
self.parse_run_once(record)
# Cache the list of variables to save before execution # Cache the list of variables to save before execution
save = list(self._vars.keys()) save = list(self._vars.keys())
if self._loop is not None: if self._loop is not None:
save.append(self._loop_var) save.append(self._loop_var)
self._save = tuple(save) self._save = tuple(save)
# Handle instructions that may only be executed once
if record.get("run_once", False):
self._executed_once = False
# Process action-specific fields # Process action-specific fields
self.parse_action(record) self.parse_action(record)
def parse_condition(self, record):
"""Parse the ``when`` clause of an instruction.
If the ``when`` clause is present, ensure it contains a string then
store it.
Args:
record: the YAML data
Raises:
AnsibleParserError: if the ``when`` clause is present but does not \
contain a string
"""
if "when" not in record:
return
if not isinstance(record["when"], string_types):
raise AnsibleParserError(
"%s: 'when' clause is not a string" % (self._action,)
)
self._condition = record["when"]
def parse_loop(self, record):
"""Parse the ``loop`` and ``loop_var`` clauses of an instruction.
Check for proper usage of both the ``loop`` and ``loop_var`` clauses,
then extract the values and store them.
Args:
record: the instruction's YAML data
Raises:
AnsibleParserError: when ``loop_var`` is being used without \
``loop``, when the type of either is incorrect, or when the \
value of ``loop_var`` is not a valid identifier.
"""
if "loop" not in record:
if "loop_var" in record:
raise AnsibleParserError(
"%s: 'loop_var' clause found without 'loop'" % (self._action,)
)
return
loop = record["loop"]
if not isinstance(loop, string_types + (list,)):
raise AnsibleParserError(
"%s: 'loop' clause is neither a string nor a list" % (self._action,)
)
loop_var = record.get("loop_var", RcInstruction.DEFAULT_LOOP_VAR)
if not isinstance(loop_var, string_types):
raise AnsibleParserError(
"%s: 'loop_var' clause is not a string" % (self._action,)
)
if not isidentifier(loop_var):
raise AnsibleParserError(
"%s: 'loop_var' value '%s' is not a valid identifier"
% (self._action, loop_var)
)
self._loop = loop
self._loop_var = loop_var
def parse_vars(self, record): def parse_vars(self, record):
"""Parse local variable definitions from the record. """Parse local variable definitions from the record.
@ -393,6 +422,25 @@ class RcInstruction(abc.ABC):
) )
return record["vars"] return record["vars"]
def parse_run_once(self, record):
"""Parse an instruction's ``run_once`` clause.
Args:
record: the YAML data for the instruction
Raises:
AnsibleParserError: when the clause is present but does not \
contain a truthy value
"""
if "run_once" not in record:
return
if not isinstance(record["run_once"], bool):
raise AnsibleParserError(
"%s: run_once must be a truthy value" % (self._action,)
)
if record["run_once"]:
self._executed_once = False
def parse_group_name(self, record, name): def parse_group_name(self, record, name):
"""Parse a field containing the name of a group, or a template. """Parse a field containing the name of a group, or a template.