/
man4j
/
spotbugs-java-audit
Обзор
Документация
Войти
/
man4j
/
spotbugs-java-audit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
scripts/spotbugs_table.py
91 строка
3 KB
Vladimir
fixes
07 июн 2026, 14:01
07 июн 2026, 14:01
abcf74e
Код
Авторство
О чём код?
#!/usr/bin/env python3 import argparse import os import xml.etree.ElementTree as ET DEFAULT_EXCLUDED = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2", "MS_EXPOSE_REP"} def severity(priority, rank, bug_type): rank_value = int(rank or 20) priority_value = int(priority or 3) if bug_type in {"DLS_DEAD_LOCAL_STORE", "NM_SAME_SIMPLE_NAME_AS_INTERFACE"}: return 3, "⚪" if bug_type in { "DM_EXIT", "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", "RV_RETURN_VALUE_IGNORED", } or rank_value <= 7: return 0, "🔴" if priority_value == 1 or bug_type in { "DM_DEFAULT_ENCODING", "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", "CT_CONSTRUCTOR_THROW", }: return 1, "🟠" return 2, "🟡" def source_location(instance): line = instance.find("SourceLine[@primary='true']") if line is None: line = instance.find("SourceLine") if line is None: return "" filename = os.path.basename(line.get("sourcefile") or line.get("sourcepath") or "") start = line.get("start") if start and start != "None": return f"{filename}:{start}" return filename def why(instance): long_message = (instance.findtext("LongMessage") or "").strip() short_message = (instance.findtext("ShortMessage") or "").strip() return long_message or short_message def main(): parser = argparse.ArgumentParser(description="Render a compact SpotBugs findings table.") parser.add_argument("xml", help="Path to target/spotbugsXml.xml") parser.add_argument( "--include-mutable", action="store_true", help="Include EI_EXPOSE_REP, EI_EXPOSE_REP2, and MS_EXPOSE_REP findings.", ) parser.add_argument( "--exclude-style", action="store_true", help="Hide STYLE findings. By default the table includes every non-mutable SpotBugs finding.", ) args = parser.parse_args() root = ET.parse(args.xml).getroot() rows = [] for instance in root.findall("BugInstance"): bug_type = instance.get("type") or "" category = instance.get("category") or "" if not args.include_mutable and bug_type in DEFAULT_EXCLUDED: continue if args.exclude_style and category == "STYLE": continue severity_order, icon = severity(instance.get("priority"), instance.get("rank"), bug_type) priority = int(instance.get("priority") or 3) rank = int(instance.get("rank") or 20) rows.append((severity_order, priority, rank, icon, source_location(instance), why(instance))) rows.sort(key=lambda row: (row[0], row[1], row[2], row[4])) print("| Criticality | File | Why it matters |") print("|---|---|---|") for _, _, _, icon, filename, message in rows: message = message.replace("|", "\\|") print(f"| {icon} | {filename} | {message} |") if __name__ == "__main__": main()