Skip to content

Commit e33f3a6

Browse files
authored
Merge pull request github#13154 from aibaars/sync-dbscheme-py
JS/Ruby/QL/Python: sync dbscheme fragments
2 parents 6fca8df + bec2b7f commit e33f3a6

File tree

51 files changed

+34408
-16332
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+34408
-16332
lines changed

.github/workflows/ql-for-ql-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
path: |
3333
ql/extractor-pack/
3434
ql/target/release/buramu
35-
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }}
35+
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ql/**/*.rs') }}
3636
- name: Cache cargo
3737
if: steps.cache-extractor.outputs.cache-hit != 'true'
3838
uses: actions/cache@v3

.github/workflows/ruby-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
ruby/extractor/target/release/codeql-extractor-ruby
6262
ruby/extractor/target/release/codeql-extractor-ruby.exe
6363
ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
64-
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}--${{ hashFiles('ruby/extractor/**/*.rs') }}
64+
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ruby/extractor/**/*.rs') }}
6565
- uses: actions/cache@v3
6666
if: steps.cache-extractor.outputs.cache-hit != 'true'
6767
with:

.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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"files": [
3+
"javascript/ql/lib/semmlecode.javascript.dbscheme",
4+
"python/ql/lib/semmlecode.python.dbscheme",
5+
"ruby/ql/lib/ruby.dbscheme",
6+
"ql/ql/src/ql.dbscheme"
7+
],
8+
"fragments": [
9+
"/*- External data -*/",
10+
"/*- Files and folders -*/",
11+
"/*- Diagnostic messages -*/",
12+
"/*- Diagnostic messages: severity -*/",
13+
"/*- Source location prefix -*/",
14+
"/*- Lines of code -*/",
15+
"/*- Configuration files with key value pairs -*/",
16+
"/*- YAML -*/",
17+
"/*- XML Files -*/",
18+
"/*- XML: sourceline -*/",
19+
"/*- DEPRECATED: External defects and metrics -*/",
20+
"/*- DEPRECATED: Snapshot date -*/",
21+
"/*- DEPRECATED: Duplicate code -*/",
22+
"/*- DEPRECATED: Version control data -*/",
23+
"/*- JavaScript-specific part -*/",
24+
"/*- Ruby dbscheme -*/",
25+
"/*- Erb dbscheme -*/",
26+
"/*- QL dbscheme -*/",
27+
"/*- Dbscheme dbscheme -*/",
28+
"/*- Yaml dbscheme -*/",
29+
"/*- Blame dbscheme -*/",
30+
"/*- JSON dbscheme -*/",
31+
"/*- Python dbscheme -*/"
32+
]
33+
}

config/sync-dbscheme-fragments.py

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

0 commit comments

Comments
 (0)