in lib/ramble/ramble/graphs.py [0:0]
def __init__(self, exec_order, executables, builtin_objects, builtin_groups, obj_inst):
"""Construct a new ExecutableGraph
Executable graphs have node attributes that are either of type
CommandExecutable, or are a function pointer to a builtin.
Args:
exec_order (list(str)): List of executable names in execution order
executables (dict): Dictionary of executable definitions.
Keys are executable names, values are CommandExecutables
builtin_objects (list(object)): List of objects to associate with each builtin
group (in order)
builtins (list(dict)): List of dictionaries containing definitions of builtins.
Keys are names values are configurations of builtins.
modifier_builtins (dict): Dictionary containing definitions of modifier builtins.
Keys are names values are configurations of builtins.
Modifier builtins are inserted between application builtins
and executables.
obj_inst (object): Object instance to extract attributes from (when necessary)
"""
super().__init__(obj_inst)
self._builtin_dependencies = defaultdict(list)
# Mapping from shorter_name -> fully qualified names
self._builtin_aliases = defaultdict(list)
# Define nodes for executable
for exec_name, cmd_exec in executables.items():
exec_node = ramble.util.graph.GraphNode(exec_name, cmd_exec, obj_inst=obj_inst)
self.node_definitions[exec_name] = exec_node
if exec_name in exec_order:
super().update_graph(exec_node)
# Define nodes for builtins
for builtin_obj, builtins in zip(builtin_objects, builtin_groups):
for builtin, blt_conf in builtins.items():
self._builtin_dependencies[builtin] = blt_conf["depends_on"].copy()
blt_func = getattr(builtin_obj, blt_conf["name"])
exec_node = ramble.util.graph.GraphNode(
builtin, attribute=blt_func, obj_inst=builtin_obj
)
self.node_definitions[builtin] = exec_node
self._build_builtin_aliases(builtin)
for builtin, blt_conf in builtins.items():
dependents = blt_conf["dependents"].copy()
for dependent in dependents:
self._builtin_dependencies[dependent].append(builtin)
dep_exec = None
for exec_name in exec_order:
if dep_exec is not None:
exec_node = self.node_definitions[exec_name]
dep_node = self.node_definitions[dep_exec]
super().update_graph(exec_node, [dep_node])
dep_exec = exec_name
head_node = None
tail_node = None
for node in self.walk():
if head_node is None:
head_node = node
tail_node = node
# Add (missing) required builtins
for builtins in builtin_groups:
for builtin, blt_conf in builtins.items():
if blt_conf["required"] and self.get_node(builtin) is None:
blt_node = self.node_definitions[builtin]
super().update_graph(blt_node)
if blt_conf["injection_method"] == "prepend":
if head_node is not None:
super().update_graph(head_node, [blt_node])
elif blt_conf["injection_method"] == "append":
if tail_node is not None:
super().update_graph(blt_node, [tail_node])
if blt_conf["depends_on"]:
deps = []
for dep in blt_conf["depends_on"]:
dep_node = self._resolve_builtin_node(dep)
super().update_graph(dep_node)
deps.append(dep_node)
exec_node = self.node_definitions[builtin]
super().update_graph(exec_node, deps)
if blt_conf["dependents"]:
exec_node = self.node_definitions[builtin]
super().update_graph(exec_node)
for dependent in blt_conf["dependents"]:
dependent_node = self._resolve_builtin_node(dependent)
super().update_graph(dependent_node, [exec_node])