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嵌入, 调用图, 逆向工具, 错误基检测, 静态代码分析