163 lines
5.9 KiB
Python

import copy
from pathlib import Path
from albero.utils import render_template
from albero.plugin.common import PluginBackendClass
from pprint import pprint
import logging
import anyconfig
import textwrap
class Plugin(PluginBackendClass):
_plugin_name = "loop"
_plugin_help = """
This module helps to loop over a backend
""",
_schema_props_new = {
"loop": {
"description": _plugin_help,
"default": None,
"optional": True,
"examples": [
{
"value": "site/{{ loop_env }}/config/{{ os }}",
"loop": {
"var": "loop_env",
"data": [
"dev",
"preprod",
"prod",
],
},
"comment": "The module will loop three time over the value, and the variable `loop_env` will consecutely have `dev`, `preprod` and `prod` as value",
},
{
"value": "site/{{ loop_env2 }}/config/{{ os }}",
"loop": {
"var": "loop_env2",
"data": "my_scope_var",
},
"comment": "Like the previous example, but it will fetch the list from any scope variables",
},
{
"loop": None,
"comment": "Disable this module, no loop will operate",
},
# "loop": {
# "var": "my_var",
# },
# },
# "loop": {
# "var": "my_var",
# },
# "example": "",
# },
# "loop": {
# "var": "my_var",
# },
# "example": "",
# },
],
"oneOf": [
{
"type": "object",
"additionalProperties": False,
"default": {},
"title": "Complete config",
"description": "",
"properties": {
"data": {
"default": None,
"optional": False,
"title": "Module configuration",
"description": "Data list used for iterations. It only accept lists as type. It disable the module if set to `null`.",
"anyOf":[
{
"type": "null",
"title": "Disable Module",
"description": "Disable the module",
},
{
"type": "string",
"title": "Scope variable",
"description": "Will look the value of the loop list from the scope. TOFIX: What if variablle does not exists?",
},
{
"type": "array",
"title": "Hardcoded list",
"description": "Simply enter the list of value to be iterated to.",
},
]
},
"var": {
"type": "string",
"default": "loop_item",
"optional": True,
"title": "Module configuration",
"description": "Name of the variable to be used in templating language",
},
},
},
{
"type": "string",
"title": "Short config",
"description": "If set to string, it will define the name of the variable to lookup into the scope.",
},
{
"type": "null",
"title": "Disable",
"description": "If set to null, it disable the module",
},
]
}
}
def process(self, backends: list, ctx: dict) -> (list, dict):
new_backends = []
for cand in backends:
cand = dict(cand)
# Init
loop_config = cand.get("loop", {})
loop_data = loop_config.get("data", None)
if not loop_data:
new_backends.append(cand)
continue
# Retrieve config data
loop_var = loop_config.get("var", "item")
if isinstance(loop_data, str):
loop_data = cand['_run']['scope'].get(loop_data, None)
assert (isinstance(loop_data, list)), f"Got: {loop_data}"
# Build a new list
ret = []
for idx, item in enumerate(loop_data):
_cand = copy.deepcopy(cand)
run = {
"loop_index": idx,
"loop_value": item,
"loop_var": loop_var,
}
_cand['_run']['loop'] = run
_cand['_run']['scope'][loop_var] = item
#_cand.scope[loop_var] = item
ret.append(_cand)
new_backends.extend(ret)
return new_backends, ctx