112 lines
3.2 KiB
Python
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 "存在需人工复核的项")
|