From e0b490fdc0365365c6bda0b9c30ffce41433788f Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Fri, 1 Jan 2021 15:48:24 +0000 Subject: [PATCH] Add support for multiline values in .conf files --- app/tasks/minetestcheck/config.py | 61 ++++++++++++++++++++++++++++--- app/tasks/minetestcheck/tree.py | 5 ++- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/app/tasks/minetestcheck/config.py b/app/tasks/minetestcheck/config.py index a8187d28..c28bcbfc 100644 --- a/app/tasks/minetestcheck/config.py +++ b/app/tasks/minetestcheck/config.py @@ -1,10 +1,59 @@ def parse_conf(string): retval = {} - for line in string.split("\n"): - idx = line.find("=") - if idx > 0: - key = line[:idx].strip() - value = line[idx+1:].strip() - retval[key] = value + lines = string.splitlines() + i = 0 + + def syntax_error(message): + raise SyntaxError("Line {}: {}".format(i + 1, message)) + + while i < len(lines): + line = lines[i].strip() + + # Comments + if line.startswith("#") or line == "": + i += 1 + continue + + key_value = line.split("=", 2) + if len(key_value) < 2: + syntax_error("No value given") + + key = key_value[0].strip() + if key == "": + syntax_error("Empty key") + + value = key_value[1].strip() + if value == "": + syntax_error("Empty value") + + if value.startswith('"""'): + value_lines = [] + closed = False + i += 1 + while i < len(lines): + value = lines[i] + if value == '"""': + closed = True + value = value[:-3] + break + + value_lines.append(value) + i += 1 + + if not closed: + i -= 1 + syntax_error("Unclosed multiline value") + + value_lines.append(value) + value = "\n".join(value_lines) + + else: + value = value.rstrip() + + if key in retval: + syntax_error("Duplicate key {}".format(key)) + + retval[key] = value + i += 1 return retval diff --git a/app/tasks/minetestcheck/tree.py b/app/tasks/minetestcheck/tree.py index 511f73e7..e4e687c6 100644 --- a/app/tasks/minetestcheck/tree.py +++ b/app/tasks/minetestcheck/tree.py @@ -84,11 +84,14 @@ class PackageTreeNode: result = {} # .conf file + meta_file_path = self.getMetaFilePath() try: - with open(self.getMetaFilePath() or "", "r") as myfile: + with open(meta_file_path or "", "r") as myfile: conf = parse_conf(myfile.read()) for key, value in conf.items(): result[key] = value + except SyntaxError as e: + raise MinetestCheckError("Error while reading {}: {}".format(meta_file_path , e.msg)) except IOError: pass