From 24569ff28412cb1b439070e83caa3bbb5fbd01c5 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Thu, 20 Jul 2017 10:31:04 +0200 Subject: Allow unknown configuration keys, but warn check_config_schema: collect errors and warnings, and only exit if there are any errors --- tools/readconfig.py | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/tools/readconfig.py b/tools/readconfig.py index 9c023b1..d883815 100644 --- a/tools/readconfig.py +++ b/tools/readconfig.py @@ -72,50 +72,53 @@ def transform_schema(in_schema): def check_config_schema(config, schema): transformed_schema = transform_schema(schema) - error = check_config_schema_part(config, transformed_schema) - if error: - print >>sys.stderr, "error:", error - sys.exit(1) + problems = check_config_schema_part(config, transformed_schema) + if problems: + haserrors = False + for problem in problems: + if problem.startswith("error:"): + haserrors = True + else: + assert(problem.startswith("WARNING:")) + print >>sys.stderr, problem + if haserrors: + sys.exit(1) def check_config_schema_part(term, schema, path=[]): joined_path = render_path(path) + problems = [] if isinstance(term, basestring): (schema_lowlevel, schema_highlevel) = schema if schema_lowlevel != "string": - return "expected %s at %s, not a string" % (schema_lowlevel, joined_path,) - return None + problems.append("error: expected %s at %s, not a string" % (schema_lowlevel, joined_path,)) elif isinstance(term, int): (schema_lowlevel, schema_highlevel) = schema if schema_lowlevel != "integer": - return "expected %s at %s, not an integer" % (schema_lowlevel, joined_path,) - return None + problems.append("error: expected %s at %s, not an integer" % (schema_lowlevel, joined_path,)) elif isinstance(term, dict): if not isinstance(schema, dict): - return "expected %s at %s, not a key" % (schema, joined_path,) + problems.append("error: expected %s at %s, not a key" % (schema, joined_path,)) for k, v in term.items(): schema_part = schema.get(k) if schema_part == None and len(schema.keys()) == 1 and schema.keys()[0].startswith("*"): schema_part = schema[schema.keys()[0]] if schema_part == None: - return "configuration key '%s' at %s unknown" % (k, joined_path) - result = check_config_schema_part(v, schema_part, path + [k]) - if result: - return result - return None + problems.append("WARNING: configuration key '%s' at %s unknown" % (k, joined_path)) + del term[k] + continue + problems.extend(check_config_schema_part(v, schema_part, path + [k])) elif isinstance(term, list): if not isinstance(schema, dict): - return "expected %s at %s, not a list" % (schema, joined_path,) + problems.append("error: expected %s at %s, not a list" % (schema, joined_path,)) schema_part = schema.get("[]") if schema_part == None: - return "expected dict at %s, not a list" % (joined_path,) + problems.append("error: expected dict at %s, not a list" % (joined_path,)) for i, e in enumerate(term, start=1): - result = check_config_schema_part(e, schema_part, path + ["item %d" % i]) - if result: - return result - return None + problems.extend(check_config_schema_part(e, schema_part, path + ["item %d" % i])) else: print >>sys.stderr, "unknown type", type(term) sys.exit(1) + return problems def insert_defaults(config, configdefaults): for (rawpath, value) in configdefaults: -- cgit v1.1