def _sub(self, step): if step.file.module is not None: # Look for file inside a Python package path = pkg_resources.resource_filename(step.file.module, step.file.path) else: # Look for file relative to current scriic path = os.path.join(self.dir_path, step.file.path) # Build dictionary of parameters parameters = { parameter.name: substitute_variables(parameter.value, self.variables, self.file_path) for parameter in step.parameters } # Run the subscriic and add its resulting instruction runner = FileRunner(path) self.instruction.children.append(runner.run(parameters)) if step.assign_to is not None: if runner.return_value is not None: # Add return value into a variable self._set_variable(step.assign_to, runner.return_value) else: raise ScriicRuntimeException( self.file_path, "Expecting a return value from {path}, but one was not given", )
def run(self, parameters=None): """ Run this file and return a tree of Instructions. :param parameters: Dictionary of parameters to pass to the script. :returns: Tree of instructions. The root instruction's text will be the title. :raises ScriicRuntimeException: A problem was encountered during execution. """ self.variables = parameters or dict() self.return_value = None given_parameters = set(self.variables.keys()) missing_parameters = self.required_parameters.difference( given_parameters) if len(missing_parameters) > 0: raise ScriicRuntimeException( self.file_path, "Missing one or more parameters: " + ", ".join(missing_parameters), ) title = substitute_variables(self.title, self.variables, self.file_path) self.instruction = Instruction(title) for step in self.steps: self._run_step(step) return self.instruction
def test_substitution(s_type): assert substitute_variables(["A", s_type("var", False), "C"], {"var": "B"}) == [ "A", "B", "C", ]
def test_no_quotation_marks_on_unknown(s_type): from scriic.value import UnknownValue from scriic.instruction import Instruction instruction = Instruction("text") instruction.display_index = 1 unknown = UnknownValue(instruction) assert substitute_variables([s_type("x", True)], {"x": unknown}) == [unknown]
def _letters(self, step): substitution = substitute_variables(step.text, self.variables, self.file_path) if substitution.is_unknown(): # We don't know the exact value of the string # Ask the user to jump back and repeat for each letter self._letters_unknown(step, substitution) else: # We know the exact value of the string # Repeat the instructions directly self._letters_known(step, str(substitution))
def _run_step(self, step): """ :param step: Step to execute. :raises ScriicRuntimeException: We do not know how to run this step. """ if isinstance(step, Do): self._do(step) elif isinstance(step, Sub): self._sub(step) elif isinstance(step, Repeat): self._repeat(step) elif isinstance(step, Letters): self._letters(step) elif isinstance(step, Return): self.return_value = substitute_variables(step.value, self.variables, self.file_path) else: raise ScriicRuntimeException(self.file_path, f"Unrecognized step: {step}")
def _return(self, step): self.return_value = substitute_variables(step.value, self.variables, self.file_path)
def _do(self, step): text = substitute_variables(step.text, self.variables, self.file_path) child = self.instruction.add_child(text) if step.assign_to is not None: self._set_variable(step.assign_to, UnknownValue(child))
def test_invalid_variable(s_type): with pytest.raises(ScriicRuntimeException): substitute_variables([s_type("var", False)], {})
def test_quotation_marks(s_type): assert substitute_variables([s_type("x", True)], {"x": "X"}) == ['"', "X", '"']