import json import os import re from collections import OrderedDict from copy import deepcopy
import yaml
here = os.path.dirname(__file__)
def first(iterable): # First item from a list or iterator ifnot hasattr(iterable, "next"): if hasattr(iterable, "__iter__"):
iterable = iter(iterable) else: raise ValueError("Object isn't iterable") return next(iterable)
def load_task_file(path): with open(path) as f: return yaml.safe_load(f)
def update_recursive(data, update_data): for key, value in update_data.items(): if key notin data:
data[key] = value else:
initial_value = data[key] if isinstance(value, dict): ifnot isinstance(initial_value, dict): raise ValueError("Variable %s has inconsistent types " "(expected object)" % key)
update_recursive(initial_value, value) elif isinstance(value, list): ifnot isinstance(initial_value, list): raise ValueError("Variable %s has inconsistent types " "(expected list)" % key)
initial_value.extend(value) else:
data[key] = value
def resolve_use(task_data, templates):
rv = {} if"use"in task_data: for template_name in task_data["use"]:
update_recursive(rv, deepcopy(templates[template_name]))
update_recursive(rv, task_data)
rv.pop("use", None) return rv
def resolve_chunks(task_data): if"chunks"notin task_data: return [task_data]
rv = []
total_chunks = task_data["chunks"] if"chunks-override"in task_data:
override = task_data["chunks-override"].get(task_data["vars"]["test-type"]) if override isnotNone:
total_chunks = override for i in range(1, total_chunks + 1):
chunk_data = deepcopy(task_data)
chunk_data["chunks"] = {"id": i, "total": total_chunks}
rv.append(chunk_data) return rv
def replace_vars(input_string, variables): # TODO: support replacing as a non-string type?
variable_re = re.compile(r"(?)
def replacer(m):
var = m.group(1).split(".")
repl = variables for part in var: try:
repl = repl[part] except Exception: # Don't substitute return m.group(0) return str(repl)
return variable_re.sub(replacer, input_string)
def sub_variables(data, variables): if isinstance(data, str): return replace_vars(data, variables) if isinstance(data, list): return [sub_variables(item, variables) for item in data] if isinstance(data, dict): return {key: sub_variables(value, variables) for key, value in data.items()} return data
def expand_maps(task):
name = first(task.keys()) if name != "$map": return [task]
map_data = task["$map"] if set(map_data.keys()) != {"for", "do"}: raise ValueError("$map objects must have exactly two properties named 'for' " "and 'do' (got %s)" % ("no properties"ifnot map_data.keys() else", ". join(map_data.keys())))
rv = [] for for_data in map_data["for"]:
do_items = map_data["do"] ifnot isinstance(do_items, list):
do_items = expand_maps(do_items) for do_data in do_items:
task_data = deepcopy(for_data) if len(do_data.keys()) != 1: raise ValueError("Each item in the 'do' list must be an object " "with a single property")
name = first(do_data.keys())
update_recursive(task_data, deepcopy(do_data[name]))
rv.append({name: task_data}) return rv
for task in tasks_data["tasks"]: if len(task.keys()) != 1: raise ValueError("Each task must be an object with a single property") for task in expand_maps(task): if len(task.keys()) != 1: raise ValueError("Each task must be an object with a single property")
name = first(task.keys())
data = task[name]
new_name = sub_variables(name, {"vars": data.get("vars", {})}) if new_name in map_resolved_tasks: raise ValueError("Got duplicate task name %s" % new_name)
map_resolved_tasks[new_name] = substitute_variables(data)
for task_default_name, data in map_resolved_tasks.items():
task = resolve_use(data, tasks_data["components"])
task = resolve_name(task, task_default_name)
tasks.extend(resolve_chunks(task))
tasks = [substitute_variables(task_data) for task_data in tasks] return OrderedDict([(t["name"], t) for t in tasks])
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.