From 7225ef09ba9ca10a50f449517fabdbae1f8c6f46 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Thu, 20 Apr 2023 15:00:58 +0200 Subject: [PATCH] Script for detecting out-of-sync dbscheme fragments --- .github/workflows/sync-files.yml | 2 + config/dbscheme-fragments.json | 6 +++ config/sync-dbscheme-fragments.py | 76 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 config/dbscheme-fragments.json create mode 100755 config/sync-dbscheme-fragments.py diff --git a/.github/workflows/sync-files.yml b/.github/workflows/sync-files.yml index afa1e78edfa..8f4678f1788 100644 --- a/.github/workflows/sync-files.yml +++ b/.github/workflows/sync-files.yml @@ -17,4 +17,6 @@ jobs: - uses: actions/checkout@v3 - name: Check synchronized files run: python config/sync-files.py + - name: Check dbscheme fragments + run: python config/sync-dbscheme-fragments.py diff --git a/config/dbscheme-fragments.json b/config/dbscheme-fragments.json new file mode 100644 index 00000000000..fdcadb53049 --- /dev/null +++ b/config/dbscheme-fragments.json @@ -0,0 +1,6 @@ +{ + "files": [ + ], + "fragments": [ + ] +} diff --git a/config/sync-dbscheme-fragments.py b/config/sync-dbscheme-fragments.py new file mode 100755 index 00000000000..5ada01537e9 --- /dev/null +++ b/config/sync-dbscheme-fragments.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +import json +import os +import re + + +def make_groups(blocks): + groups = {} + for block in blocks: + groups.setdefault("".join(block["lines"]), []).append(block) + return list(groups.values()) + + +def validate_fragments(fragments): + ok = True + for header, blocks in fragments.items(): + groups = make_groups(blocks) + if len(groups) > 1: + ok = False + print("Warning: dbscheme fragments with header '{}' are different for {}".format(header, ["{}:{}:{}".format( + group[0]["file"], group[0]["start"], group[0]["end"]) for group in groups])) + return ok + + +def main(): + script_dir = os.path.dirname(os.path.realpath(__file__)) + + with open(os.path.join(script_dir, "dbscheme-fragments.json"), "r") as f: + config = json.load(f) + + fragment_headers = set(config["fragments"]) + fragments = {} + ok = True + for file in config["files"]: + with open(os.path.join(os.path.dirname(script_dir), file), "r") as dbscheme: + header = None + line_number = 1 + block = {"file": file, "start": line_number, + "end": None, "lines": []} + + def end_block(): + block["end"] = line_number - 1 + if len(block["lines"]) > 0: + if header is None: + if re.match(r'(?m)\A(\s|//.*$|/\*(\**[^\*])*\*+/)*\Z', "".join(block["lines"])): + # Ignore comments at the beginning of the file + pass + else: + ok = False + print("Warning: dbscheme fragment without header: {}:{}:{}".format( + block["file"], block["start"], block["end"])) + else: + fragments.setdefault(header, []).append(block) + for line in dbscheme: + m = re.match(r"^\/\*-.*-\*\/$", line) + if m: + end_block() + header = line.strip() + if header not in fragment_headers: + ok = False + print("Warning: unknown header for dbscheme fragment: '{}': {}:{}".format( + header, file, line_number)) + block = {"file": file, "start": line_number, + "end": None, "lines": []} + block["lines"].append(line) + line_number += 1 + block["lines"].append('\n') + line_number += 1 + end_block() + if not ok or not validate_fragments(fragments): + exit(1) + + +if __name__ == "__main__": + main()