Spy125/codecartographer

GitHub: Spy125/codecartographer

CodeCartographer 是一款零依赖的 Python 代码库静态分析工具,通过 AST 解析生成依赖图、调用图并检测循环 import 与潜在死代码。

Stars: 0 | Forks: 0

# CodeCartographer 针对 Python 代码库的静态分析工具。将其指向某个代码仓库,它会报告 import 图、循环 import、入口点、调用图以及似乎从未被调用的函数。 分析基于抽象语法树进行,因此结果是可重现的:对未修改的源码运行两次将产生完全相同的输出。 ## 功能 | 分析 | 方法 | |---|---| | 模块依赖图 | 解析 `import` 和 `from ... import` 语句,包括相对 import,并将其与项目中找到的模块进行匹配 | | 循环 import | 强连通分量(Tarjan 算法),以具体的循环路径形式报告 | | 入口点 | 带有 `__main__` 保护代码的模块,以及没有被任何模块 import 的模块 | | 依赖最多的模块 | 根据 import 图中的入度进行排名 | | 调用图 | 使用导入的符号、模块别名、`self`/`cls` 方法和构造函数,跨文件解析调用点 | | 未使用的函数 | 在调用图中没有入边的函数 | | 调用链查找 | 从入口点到目标函数的广度优先搜索 | 该包没有运行时依赖项,仅使用标准库,包括用于解析的内置 `ast` 模块。图算法是直接实现的,而不是从库中引入的。 ## 安装说明 ``` git clone https://github.com/Spy125/codecartographer cd codecartographer pip install -e . ``` 需要 Python 3.10 或更高版本。 ## 用法 分析代码仓库。默认情况下,这会将 `report.json`、`report.md` 和一个交互式的 `map.html` 写入到 `codecarto-report/` 中: ``` codecarto analyze path/to/repo ``` 实用选项: ``` codecarto analyze path/to/repo --open # open the HTML map when done codecarto analyze path/to/repo -o out --json # JSON only, custom output directory ``` 追踪执行是如何到达特定函数的: ``` codecarto explain path/to/repo process_order ``` ``` Call chain to shop.orders::process_order (3 hops): shop.cli (top-level) shop/cli.py:1 -> shop.cli::main shop/cli.py:12 -> shop.api::submit shop/api.py:40 -> shop.orders::process_order shop/orders.py:18 ``` 目标可以是单独的名称、`Class.method`,或者是完全限定的 `module::name`。单独的名称在仅匹配到唯一一个函数时会被解析。 ### 库的使用 ``` from codecartographer import analyze result = analyze("path/to/repo") result.cycles # [['pkg.alpha', 'pkg.beta']] result.entry_points # ['main'] result.summary # counts, edges, call resolution rate ``` ## HTML 图谱 `map.html` 是一个没有外部请求的单个文件,因此可以直接从磁盘打开、提交到版本库,或者作为静态页面提供服务。 模块通过力导向模拟进行布局。入口点会被高亮显示,涉及循环 import 的模块会被标记,节点大小反映了有多少其他模块 import 了它。选择一个节点会显示其 import、导入者、外部依赖、函数和类。 要查看它在此代码仓库上的应用效果: ``` codecarto analyze . --open ``` ## 工作原理 ``` repository -> walker -> extractor -> analyzer -> reports ``` 1. **walker** 查找每个 `.py` 文件并得出其点分形式的模块名称,同时处理 `src/` 布局并跳过虚拟环境、缓存和构建目录。 2. **extractor** 使用 `ast` 解析每个文件一次,并记录 import(解析相对路径)、函数和类定义、调用点以及 `__main__` 保护代码。无法读取的文件和语法错误会被记录在结果中,而不是抛出异常,这样一个有问题的文件就不会中止整个运行过程。 3. **analyzer** 解析跨文件的名称并构建两个图,一个是模块和 import 图,另一个是函数和调用图,然后对它们运行图算法。 4. **report** 将结果呈现为 JSON、Markdown 或 HTML。 `graph.py` 包含图的实现:Tarjan 的强连通分量、广度优先最短路径、可达性以及 Kahn 的拓扑排序。遍历是迭代式的,因此大型代码仓库不会超出 Python 的递归限制。 ## 限制 对动态语言进行静态分析必然是不完整的,在阅读输出结果时应牢记这一点: - 通过类型未知的变量进行的调用,仅当项目中只有一个类定义了该名称的方法时,才会被解析。 - 不会追踪针对另一个调用结果的调用,例如 `build().save()`。 - 动态分派、`getattr`、反射和 monkey-patching 对它是不可见的。一个被报告为没有静态调用者的函数,仍然可能在运行时被到达,或者从项目外部被调用,因此应将这些结果视为需要审查的候选项,而不是已确认的死代码。 - 报告的调用解析百分比表明了调用图被解析的比例,这是对其他输出的完整性进行检验的一个有用指标。 仅分析 Python 源代码。 ## 开发 ``` pip install -e ".[dev]" pytest ``` 测试套件涵盖了图算法、AST 提取、跨文件分析和 CLI。它包含了具有已知属性的测试仓库,例如故意的 import 循环和故意不被调用的函数,以便将分析器的发现与预期结果进行对比检查。其中一个测试断言,对相同源代码的两次运行会产生完全相同的输出。
标签:AST解析, Python, WebSocket, 依赖分析, 无后门, 死代码检测, 自动化payload嵌入, 调用图, 逆向工具, 错误基检测, 静态代码分析