feat(config): document # @required for host config management (v1.0.115)
All checks were successful
技能自动化发布 / release (push) Successful in 6s
All checks were successful
技能自动化发布 / release (push) Successful in 6s
This commit is contained in:
@@ -30,6 +30,7 @@ POLICY_IDS = (
|
||||
"POLICY-CONFIG-002",
|
||||
"POLICY-CONFIG-003",
|
||||
"POLICY-CONFIG-004",
|
||||
"POLICY-CONFIG-005",
|
||||
"POLICY-TESTING-001",
|
||||
"POLICY-TESTING-002",
|
||||
"POLICY-RPA-001",
|
||||
@@ -96,8 +97,11 @@ CONFIG_ENV_FORBIDDEN_PATTERNS = (
|
||||
)
|
||||
|
||||
CONFIG_004_SOURCE = "development/CONFIG.md §.env.example 注释 = 配置管理用户文案"
|
||||
CONFIG_005_SOURCE = "development/CONFIG.md §必填项:# @required"
|
||||
CONFIG_004_ENV_KEY_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
|
||||
CONFIG_004_CJK_RE = re.compile(r"[\u4e00-\u9fff]")
|
||||
CONFIG_005_REQUIRED_MARKER_RE = re.compile(r"^@required\b", re.IGNORECASE)
|
||||
CONFIG_005_INLINE_REQUIRED_RE = re.compile(r"@required\b", re.IGNORECASE)
|
||||
# 注释中禁止出现的开发向指向 / 黑话(大小写不敏感子串)
|
||||
CONFIG_004_FORBIDDEN_COMMENT_SUBSTRINGS = (
|
||||
"development/",
|
||||
@@ -316,6 +320,34 @@ def _config_004_comment_offenders(path: str) -> list[str]:
|
||||
return offenders
|
||||
|
||||
|
||||
def _is_env_required_marker(text: str) -> bool:
|
||||
return bool(CONFIG_005_REQUIRED_MARKER_RE.match(text.strip()))
|
||||
|
||||
|
||||
def _config_005_offenders(path: str) -> list[str]:
|
||||
offenders: list[str] = []
|
||||
for lineno, key, _value, headers, inline in _iter_env_example_active_entries(path):
|
||||
if inline and CONFIG_005_INLINE_REQUIRED_RE.search(inline):
|
||||
offenders.append(
|
||||
f".env.example:{lineno}: {key}= 禁止在行尾写 @required(须单独一行放在中文行头上方)"
|
||||
)
|
||||
|
||||
required_markers = [part for part in headers if _is_env_required_marker(part)]
|
||||
non_marker_headers = [part for part in headers if not _is_env_required_marker(part)]
|
||||
if not required_markers:
|
||||
continue
|
||||
if not non_marker_headers:
|
||||
offenders.append(
|
||||
f".env.example:{lineno}: {key}= 使用了 # @required 但缺少中文行头"
|
||||
)
|
||||
continue
|
||||
if not any(CONFIG_004_CJK_RE.search(part) for part in non_marker_headers):
|
||||
offenders.append(
|
||||
f".env.example:{lineno}: {key}= # @required 下方须有中文行头(说明「是什么」)"
|
||||
)
|
||||
return offenders
|
||||
|
||||
|
||||
def _rel(skill_root: str, path: str) -> str:
|
||||
return os.path.relpath(path, skill_root).replace("\\", "/")
|
||||
|
||||
@@ -575,6 +607,23 @@ class TestPolicyConfig004(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class TestPolicyConfig005(unittest.TestCase):
|
||||
def test_env_example_required_markers_are_well_formed(self) -> None:
|
||||
path = os.path.join(get_skill_root(), ".env.example")
|
||||
self.assertTrue(os.path.isfile(path), msg=".env.example missing")
|
||||
offenders = _config_005_offenders(path)
|
||||
self.assertEqual(
|
||||
offenders,
|
||||
[],
|
||||
msg=_policy_msg(
|
||||
"POLICY-CONFIG-005",
|
||||
CONFIG_005_SOURCE,
|
||||
"\n".join(offenders)
|
||||
or "every # @required marker needs its own Chinese header line above the key",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class TestPolicyTesting001(unittest.TestCase):
|
||||
def test_root_tests_do_not_hardcode_real_targets(self) -> None:
|
||||
skill_root = get_skill_root()
|
||||
|
||||
Reference in New Issue
Block a user