Skip to content

Commit b9652bd

Browse files
authored
Merge pull request #322 from ai-agent-assembly/v0.1.0/AAASM-4757/fix/sonar_smells
[AAASM-4757] ♻️ (examples): Clear 5 Sonar smells in generate_example_metadata
2 parents 43cdfea + 4aa2de5 commit b9652bd

1 file changed

Lines changed: 136 additions & 59 deletions

File tree

scripts/generate_example_metadata.py

Lines changed: 136 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,14 @@ def _sub(match: re.Match[str]) -> str:
242242
# or, inside a require ( ... ) block:
243243
# \tgithub.com/ai-agent-assembly/go-sdk v0.0.1-rc.3
244244
# The regex captures the prefix (indent + optional "require ") so we preserve
245-
# whichever form the surrounding file uses. The tail requires whitespace before a
246-
# ``// comment`` so the version token ``\S+`` has an unambiguous, non-whitespace
247-
# boundary — otherwise the engine could backtrack ``\S+`` into the ``//``,
248-
# non-linear behavior static analysis flags as a ReDoS risk.
245+
# whichever form the surrounding file uses. The tail is a prefix-free alternation
246+
# — either whitespace before a ``// comment`` (``\s+//[^\n]*``) or bare trailing
247+
# whitespace (``\s*``). Written as ``(?:\s+//.*)?\s*`` instead, the comment's
248+
# ``.*`` and the trailing ``\s*`` both compete for trailing whitespace, a
249+
# super-linear ambiguity static analysis flags as a ReDoS risk (S8786); the
250+
# disjoint alternation removes that overlap while matching the same set.
249251
_GO_PIN_RE = re.compile(
250-
r'''^(?P<prefix>\s*(?:require\s+)?)github\.com/ai-agent-assembly/go-sdk\s+\S+(?P<tail>(?:\s+//.*)?\s*)$''',
252+
r'''^(?P<prefix>\s*(?:require\s+)?)github\.com/ai-agent-assembly/go-sdk\s+\S+(?P<tail>\s+//[^\n]*|\s*)$''',
251253
re.MULTILINE,
252254
)
253255

@@ -451,8 +453,13 @@ def rewrite_go_readme(path: Path, sdk: GoSdk) -> bool:
451453
# alpha/beta/rc pre-release suffix. Only the version token is rewritten, so an
452454
# operator prefix (``>= ``) and any trailing note (``(with the LlamaIndex
453455
# adapter)``) are preserved verbatim.
456+
# The pre-release alternation is prefix-free: ``b(?:eta)?`` / ``a(?:lpha)?``
457+
# fold the ``beta``/``b`` and ``alpha``/``a`` pairs together so no branch is a
458+
# prefix of another. The flat ``(?:rc|beta|alpha|b|a)`` form has ``b``/``a``
459+
# shadowing ``beta``/``alpha``, the kind of alternation overlap static analysis
460+
# flags as super-linear (S8786); this folds it out while matching the same set.
454461
_VERSION_TOKEN_RE = re.compile(
455-
r"v?\d+\.\d+\.\d+(?:[-.]?(?:rc|beta|alpha|b|a)\.?\d+)?"
462+
r"v?\d+\.\d+\.\d+(?:[-.]?(?:rc|b(?:eta)?|a(?:lpha)?)\.?\d+)?"
456463
)
457464

458465

@@ -862,6 +869,25 @@ def _prereq_readmes(repo_root: Path) -> list[Path]:
862869
return out
863870

864871

872+
def _align_prereq_readme(
873+
readme: Path,
874+
labels: tuple[tuple[str, str], ...],
875+
backtick_packages: tuple[tuple[str, str], ...],
876+
) -> bool:
877+
"""Align every prereq row/bullet in one README; return True if any changed."""
878+
879+
touched = False
880+
for label, version in labels:
881+
if rewrite_prereq_row(readme, label, version):
882+
touched = True
883+
if rewrite_prereq_bullet(readme, label, version):
884+
touched = True
885+
for package, version in backtick_packages:
886+
if rewrite_prereq_backtick_row(readme, package, version):
887+
touched = True
888+
return touched
889+
890+
865891
def process_prereq_rows(repo_root: Path, versions: SdkVersions) -> list[Path]:
866892
"""Align every hand-written ``Agent Assembly <Lang> SDK`` prereq row.
867893
@@ -884,16 +910,7 @@ def process_prereq_rows(repo_root: Path, versions: SdkVersions) -> list[Path]:
884910
)
885911
changed: list[Path] = []
886912
for readme in _prereq_readmes(repo_root):
887-
touched = False
888-
for label, version in labels:
889-
if rewrite_prereq_row(readme, label, version):
890-
touched = True
891-
if rewrite_prereq_bullet(readme, label, version):
892-
touched = True
893-
for package, version in backtick_packages:
894-
if rewrite_prereq_backtick_row(readme, package, version):
895-
touched = True
896-
if touched:
913+
if _align_prereq_readme(readme, labels, backtick_packages):
897914
changed.append(readme)
898915
return changed
899916

@@ -1017,7 +1034,7 @@ def _audit_pins(repo_root: Path, versions: SdkVersions) -> list[str]:
10171034
# pins are a bare ``"<version>"`` string and go pins are a bare ``go.mod``
10181035
# version. The workflow rewriter already forces ``==`` on a bump, but this pass
10191036
# also fails CI on a hand-authored bad operator before a regen runs.
1020-
def _audit_py_operator(repo_root: Path, versions: SdkVersions) -> list[str]:
1037+
def _audit_py_operator(repo_root: Path) -> list[str]:
10211038
"""Report every operator-bearing core-SDK pin that is not exact (``==``).
10221039
10231040
Covers both the python manifests and the CI-workflow pip-install pins.
@@ -1038,6 +1055,102 @@ def _audit_py_operator(repo_root: Path, versions: SdkVersions) -> list[str]:
10381055
return problems
10391056

10401057

1058+
def _audit_prose_label(line: str, expected_by_label: dict[str, str]) -> str | None:
1059+
"""Return a drift message for an ``Agent Assembly <Lang> SDK`` prose line."""
1060+
1061+
label_match = _PROSE_LABEL_RE.search(line)
1062+
if label_match is None:
1063+
return None
1064+
token_match = _VERSION_TOKEN_RE.search(line)
1065+
if token_match is None:
1066+
return None
1067+
expected = expected_by_label[label_match.group(1)]
1068+
if token_match.group(0) == expected:
1069+
return None
1070+
return f"states {token_match.group(0)!r}, expected {expected!r}"
1071+
1072+
1073+
def _audit_prose_backtick(
1074+
line: str, backtick_checks: tuple[tuple[re.Pattern[str], str], ...]
1075+
) -> list[str]:
1076+
"""Return drift messages for backtick-``package``-labelled prereq rows."""
1077+
1078+
problems: list[str] = []
1079+
for row_re, expected in backtick_checks:
1080+
row_match = row_re.search(line)
1081+
if row_match is None:
1082+
continue
1083+
token_match = _VERSION_TOKEN_RE.search(row_match.group("val"))
1084+
if token_match is not None and token_match.group(0) != expected:
1085+
problems.append(f"states {token_match.group(0)!r}, expected {expected!r}")
1086+
return problems
1087+
1088+
1089+
def _audit_prose_install(
1090+
line: str, install_checks: tuple[tuple[re.Pattern[str], str], ...]
1091+
) -> list[str]:
1092+
"""Return drift messages for raw install-hint literals on a prose line."""
1093+
1094+
problems: list[str] = []
1095+
for hint_re, expected in install_checks:
1096+
hint_match = hint_re.search(line)
1097+
if hint_match and hint_match.group("ver") != expected:
1098+
problems.append(
1099+
f"install hint pins {hint_match.group('ver')!r}, "
1100+
f"expected {expected!r}"
1101+
)
1102+
return problems
1103+
1104+
1105+
def _audit_prose_line(
1106+
line: str,
1107+
in_block: bool,
1108+
expected_by_label: dict[str, str],
1109+
backtick_checks: tuple[tuple[re.Pattern[str], str], ...],
1110+
install_checks: tuple[tuple[re.Pattern[str], str], ...],
1111+
) -> list[str]:
1112+
"""Return every drift message for one prose line, in stable emit order.
1113+
1114+
Install hints are skipped inside the generated sdk-install block — that
1115+
block is generator-owned and the prose install-hint pass excludes it.
1116+
"""
1117+
1118+
problems: list[str] = []
1119+
label_problem = _audit_prose_label(line, expected_by_label)
1120+
if label_problem is not None:
1121+
problems.append(label_problem)
1122+
problems.extend(_audit_prose_backtick(line, backtick_checks))
1123+
if not in_block:
1124+
problems.extend(_audit_prose_install(line, install_checks))
1125+
return problems
1126+
1127+
1128+
def _audit_prose_file(
1129+
path: Path,
1130+
rel: Path,
1131+
expected_by_label: dict[str, str],
1132+
backtick_checks: tuple[tuple[re.Pattern[str], str], ...],
1133+
install_checks: tuple[tuple[re.Pattern[str], str], ...],
1134+
) -> list[str]:
1135+
"""Report drift for one README/doc, tracking the generated-block region."""
1136+
1137+
problems: list[str] = []
1138+
in_block = False
1139+
for lineno, line in _audit_lines(path):
1140+
if SDK_BLOCK_BEGIN in line:
1141+
in_block = True
1142+
elif SDK_BLOCK_END in line:
1143+
in_block = False
1144+
continue
1145+
if EXEMPT_MARKER in line:
1146+
continue
1147+
for suffix in _audit_prose_line(
1148+
line, in_block, expected_by_label, backtick_checks, install_checks
1149+
):
1150+
problems.append(f"{rel}:{lineno}: {suffix}")
1151+
return problems
1152+
1153+
10411154
def _audit_prose(repo_root: Path, versions: SdkVersions) -> list[str]:
10421155
"""Report every README/doc prose line whose SDK version drifts from the SoT.
10431156
@@ -1072,47 +1185,11 @@ def _audit_prose(repo_root: Path, versions: SdkVersions) -> list[str]:
10721185
problems: list[str] = []
10731186
for path in _globbed(repo_root, _README_GLOBS + ("docs/*.md",)):
10741187
rel = path.relative_to(repo_root)
1075-
in_block = False
1076-
for lineno, line in _audit_lines(path):
1077-
if SDK_BLOCK_BEGIN in line:
1078-
in_block = True
1079-
elif SDK_BLOCK_END in line:
1080-
in_block = False
1081-
continue
1082-
if EXEMPT_MARKER in line:
1083-
continue
1084-
1085-
label_match = _PROSE_LABEL_RE.search(line)
1086-
if label_match:
1087-
token_match = _VERSION_TOKEN_RE.search(line)
1088-
if token_match is not None:
1089-
expected = expected_by_label[label_match.group(1)]
1090-
if token_match.group(0) != expected:
1091-
problems.append(
1092-
f"{rel}:{lineno}: states {token_match.group(0)!r}, "
1093-
f"expected {expected!r}"
1094-
)
1095-
1096-
for row_re, expected in backtick_checks:
1097-
row_match = row_re.search(line)
1098-
if row_match is None:
1099-
continue
1100-
token_match = _VERSION_TOKEN_RE.search(row_match.group("val"))
1101-
if token_match is not None and token_match.group(0) != expected:
1102-
problems.append(
1103-
f"{rel}:{lineno}: states {token_match.group(0)!r}, "
1104-
f"expected {expected!r}"
1105-
)
1106-
1107-
if in_block:
1108-
continue
1109-
for hint_re, expected in install_checks:
1110-
hint_match = hint_re.search(line)
1111-
if hint_match and hint_match.group("ver") != expected:
1112-
problems.append(
1113-
f"{rel}:{lineno}: install hint pins "
1114-
f"{hint_match.group('ver')!r}, expected {expected!r}"
1115-
)
1188+
problems.extend(
1189+
_audit_prose_file(
1190+
path, rel, expected_by_label, backtick_checks, install_checks
1191+
)
1192+
)
11161193
return problems
11171194

11181195

@@ -1121,7 +1198,7 @@ def audit(repo_root: Path, versions: SdkVersions) -> list[str]:
11211198

11221199
return sorted(
11231200
_audit_pins(repo_root, versions)
1124-
+ _audit_py_operator(repo_root, versions)
1201+
+ _audit_py_operator(repo_root)
11251202
+ _audit_prose(repo_root, versions)
11261203
)
11271204

0 commit comments

Comments
 (0)