Skip to content

Commit 7225ef0

Browse files
committed
Script for detecting out-of-sync dbscheme fragments
1 parent ed79113 commit 7225ef0

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

.github/workflows/sync-files.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ jobs:
1717
- uses: actions/checkout@v3
1818
- name: Check synchronized files
1919
run: python config/sync-files.py
20+
- name: Check dbscheme fragments
21+
run: python config/sync-dbscheme-fragments.py
2022

config/dbscheme-fragments.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"files": [
3+
],
4+
"fragments": [
5+
]
6+
}

config/sync-dbscheme-fragments.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env python3
2+
3+
import json
4+
import os
5+
import re
6+
7+
8+
def make_groups(blocks):
9+
groups = {}
10+
for block in blocks:
11+
groups.setdefault("".join(block["lines"]), []).append(block)
12+
return list(groups.values())
13+
14+
15+
def validate_fragments(fragments):
16+
ok = True
17+
for header, blocks in fragments.items():
18+
groups = make_groups(blocks)
19+
if len(groups) > 1:
20+
ok = False
21+
print("Warning: dbscheme fragments with header '{}' are different for {}".format(header, ["{}:{}:{}".format(
22+
group[0]["file"], group[0]["start"], group[0]["end"]) for group in groups]))
23+
return ok
24+
25+
26+
def main():
27+
script_dir = os.path.dirname(os.path.realpath(__file__))
28+
29+
with open(os.path.join(script_dir, "dbscheme-fragments.json"), "r") as f:
30+
config = json.load(f)
31+
32+
fragment_headers = set(config["fragments"])
33+
fragments = {}
34+
ok = True
35+
for file in config["files"]:
36+
with open(os.path.join(os.path.dirname(script_dir), file), "r") as dbscheme:
37+
header = None
38+
line_number = 1
39+
block = {"file": file, "start": line_number,
40+
"end": None, "lines": []}
41+
42+
def end_block():
43+
block["end"] = line_number - 1
44+
if len(block["lines"]) > 0:
45+
if header is None:
46+
if re.match(r'(?m)\A(\s|//.*$|/\*(\**[^\*])*\*+/)*\Z', "".join(block["lines"])):
47+
# Ignore comments at the beginning of the file
48+
pass
49+
else:
50+
ok = False
51+
print("Warning: dbscheme fragment without header: {}:{}:{}".format(
52+
block["file"], block["start"], block["end"]))
53+
else:
54+
fragments.setdefault(header, []).append(block)
55+
for line in dbscheme:
56+
m = re.match(r"^\/\*-.*-\*\/$", line)
57+
if m:
58+
end_block()
59+
header = line.strip()
60+
if header not in fragment_headers:
61+
ok = False
62+
print("Warning: unknown header for dbscheme fragment: '{}': {}:{}".format(
63+
header, file, line_number))
64+
block = {"file": file, "start": line_number,
65+
"end": None, "lines": []}
66+
block["lines"].append(line)
67+
line_number += 1
68+
block["lines"].append('\n')
69+
line_number += 1
70+
end_block()
71+
if not ok or not validate_fragments(fragments):
72+
exit(1)
73+
74+
75+
if __name__ == "__main__":
76+
main()

0 commit comments

Comments
 (0)