Files
Leantime/.dev/onebot-bom-lint.py

112 lines
3.2 KiB
Python

# -*- coding: utf-8 -*-
"""对改动过的 PHP/Blade 文件做静态检查(无 php CLI 时的替代):
跳过 /* */ 与 // 与 # 注释,再检查括号/引号平衡。
"""
import os
import re
root = r"d:\开发\leantime-master\leantime-master"
files = [
r"app\Domain\Bom\Repositories\Bom.php",
r"app\Domain\Bom\Services\Bom.php",
r"app\Domain\Bom\Services\Teable.php",
r"app\Domain\Bom\Services\Excel.php",
r"app\Domain\Bom\Permissions\BomPermissions.php",
r"app\Domain\Bom\Controllers\Show.php",
r"app\Domain\Bom\Controllers\Api.php",
r"app\Domain\Bom\routes.php",
r"app\Domain\Bom\Templates\show.blade.php",
r"app\Domain\Bom\Templates\detail.blade.php",
r"app\Domain\Install\Repositories\Install.php",
r"app\Domain\Install\Services\SchemaBuilder.php",
r"app\Domain\Menu\Repositories\Menu.php",
r"app\Views\Templates\components\pdfPreview.blade.php",
r"app\Views\Templates\sections\header.blade.php",
]
def strip_comments(src):
# 去掉 /* ... */ 和 // 行注释(保留换行结构便于定位)
out = []
i = 0
n = len(src)
while i < n:
c = src[i]
nxt = src[i + 1] if i + 1 < n else ''
if c == '/' and nxt == '*':
j = src.find('*/', i + 2)
out.append(' ' * (n if j == -1 else (j + 2 - i)))
i = n if j == -1 else j + 2
elif c == '/' and nxt == '/':
j = src.find('\n', i)
out.append(' ' * (n if j == -1 else (j - i)))
i = n if j == -1 else j
elif c == '#':
j = src.find('\n', i)
out.append(' ' * (n if j == -1 else (j - i)))
i = n if j == -1 else j
else:
out.append(c)
i += 1
return ''.join(out)
def check_balance(s):
pairs = {')': '(', '}': '{', ']': '['}
stack = []
in_s = in_d = False
i = 0
esc = False
while i < len(s):
ch = s[i]
if esc:
esc = False
i += 1
continue
if ch == '\\' and (in_s or in_d):
esc = True
i += 1
continue
if ch == "'" and not in_d:
in_s = not in_s
i += 1
continue
if ch == '"' and not in_s:
in_d = not in_d
i += 1
continue
if not in_s and not in_d:
if ch in '({[':
stack.append(ch)
elif ch in ')}]':
if not stack or stack[-1] != pairs[ch]:
return f"不匹配 '{ch}' 于位置 {i}"
stack.pop()
i += 1
if in_s:
return "单引号未闭合"
if in_d:
return "双引号未闭合"
if stack:
return f"未闭合 {stack[-1]}"
return None
all_ok = True
for f in files:
p = os.path.join(root, f)
if not os.path.exists(p):
print(f"[SKIP] {f} (不存在)")
continue
with open(p, encoding="utf-8") as fh:
src = fh.read()
stripped = strip_comments(src)
bal = check_balance(stripped)
if bal:
print(f"[FAIL] {f} <- {bal}")
all_ok = False
else:
print(f"[OK] {f}")
print("\n总判定:", "PASS" if all_ok else "存在需人工复核的项")