brokenbartender/blast-radius

GitHub: brokenbartender/blast-radius

一款基于 Python AST 的增量调用图分析工具,用于快速查询代码修改的潜在影响范围与依赖关系。

Stars: 1 | Forks: 0

# blast-radius **如果我更改了这个文件,会影响哪些部分?** `blast-radius` 会为你的 Python 项目构建一个增量的 AST 调用图,并 瞬间回答这个问题。它将导入和符号定义索引到 SQLite 中(使用 SHA-256 缓存——仅重新索引更改过的文件),并在几毫秒内 解析传递依赖。 ``` pip install impact-radius ``` [![PyPI 版本](https://badge.fury.io/py/impact-radius.svg)](https://pypi.org/project/impact-radius/) [![下载量](https://img.shields.io/pypi/dm/impact-radius.svg)](https://pypi.org/project/impact-radius/) [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/) [![许可证:MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/5909d4e393110431.svg)](https://github.com/brokenbartender/blast-radius/actions) ## 快速入门 ``` # 构建依赖图 (增量构建 — 仅重新索引已更改的文件) impact-radius --build # 如果我更改 src/utils.py,会影响哪些地方? impact-radius --query src/utils.py # 输出 Mermaid 图表 (可在 GitHub READMEs / PRs 中渲染) impact-radius --query src/utils.py --mermaid # Watch 模式 — 每次保存时自动重新构建 impact-radius --watch # 原始 JSON 输出 (通过管道传递给 jq、脚本、CI) impact-radius --query src/utils.py --json ``` ## 终端输出 (使用 Rich) ``` src/utils.py ⚡ GOD NODE ├── 📄 src/api/routes.py ├── 📄 src/models/user.py ├── 🧪 tests/test_utils.py └── 🧪 tests/test_api.py 14 file(s) affected · in-degree 47 · 2 test file(s) ``` 安装 Rich 以获得彩色输出: ``` pip install impact-radius[rich] ``` ## Mermaid 图表 (在 GitHub 中渲染) ``` from blast_radius import build_graph, get_blast_radius, to_mermaid build_graph() result = get_blast_radius("src/utils.py") print(to_mermaid(result)) ``` 将输出粘贴到任何 GitHub issue、PR 或 README 中: ``` graph TD utils_py["src/utils.py"] utils_py --> routes_py["src/api/routes.py"] utils_py --> user_py["src/models/user.py"] utils_py --> test_utils_py["tests/test_utils.py"] style test_utils_py fill:#22c55e,color:#fff %% total affected: 3 | in-degree: 0 ``` ## Python API ``` from blast_radius import build_graph, get_blast_radius, to_mermaid, watch # 构建 import graph (增量构建 — 仅重新索引已更改的文件) n = build_graph() print(f"{n} files indexed") # 查询 blast radius result = get_blast_radius("src/mymodule.py") print(result["total_affected"]) # int print(result["direct_dependents"]) # list of file paths print(result["test_files"]) # files that start with tests/ # Mermaid 输出 diagram = to_mermaid(result) # Watch 模式 (阻塞式 — 运行直到 Ctrl+C) watch(interval=2.0) ``` ## 配置 所有路径均可配置——没有硬编码的假设: ``` # 仅扫描特定目录 impact-radius --build --scan src tests # 使用自定义 DB 路径 (在 CI 中很有用) impact-radius --build --db /tmp/my-graph.db # 调整 watch 轮询间隔 impact-radius --watch --interval 1.0 ``` 或者通过 Python API: ``` from pathlib import Path build_graph(scan_dirs=["src", "tests"], db_path=Path("/tmp/my-graph.db")) get_blast_radius("src/utils.py", db_path=Path("/tmp/my-graph.db")) ``` ## pytest 插件 — 针对性测试选择 只运行那些实际受到你暂存更改影响的测试: ``` pip install "impact-radius[pytest]" ``` ``` # 仅运行位于暂存文件 blast radius 内的测试 (pre-commit 模式) pytest --blast-radius # 显式文件 pytest --blast-radius --br-file src/utils.py # 绕过过滤器 — 运行完整套件 (当 --blast-radius 位于 addopts 中时很有用) pytest --blast-radius --br-all ``` 添加到 `pytest.ini` 或 `pyproject.toml` 中,将针对性测试设为默认设置: ``` [pytest] addopts = --blast-radius ``` 该插件会取消选择任何不在你更改文件影响范围内的测试。 如果未找到暂存文件或图谱不可用,则会安全地回退到完整的测试套件。 ## --staged 标志 — 所有更改文件的影响报告 查看你即将提交的所有更改的综合影响范围: ``` impact-radius --build impact-radius --staged ``` ``` Staged (2 file(s)): src/utils.py src/models/user.py Blast radius — 6 file(s) affected: -> src/api/routes.py -> src/api/auth.py -> tests/test_utils.py [TEST] -> tests/test_api.py [TEST] -> tests/test_auth.py [TEST] -> src/cli.py ``` 添加 `--json` 以获取机器可读的输出: ``` impact-radius --staged --json | jq '.test_files' ``` ## pre-commit 集成 添加到你的 `.pre-commit-config.yaml` 中: ``` repos: - repo: https://github.com/brokenbartender/blast-radius rev: v1.1.0 hooks: # Rebuild the graph whenever Python files change - id: blast-radius-build # Show impact report for staged files (informational, never blocks) - id: blast-radius-staged ``` ## GitHub Action — 在 PR 上评论影响范围 ``` # .github/workflows/blast-radius.yml name: Blast Radius on: [pull_request] jobs: blast-radius: runs-on: ubuntu-latest permissions: pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-python@v5 with: {python-version: "3.11"} - run: pip install impact-radius - name: Compute blast radius for changed files id: br run: | impact-radius --build # Get the first changed .py file to query CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- '*.py' | head -1) if [ -n "$CHANGED" ]; then echo "mermaid<> $GITHUB_OUTPUT impact-radius --query "$CHANGED" --mermaid >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT else echo "mermaid=No Python files changed." >> $GITHUB_OUTPUT fi - uses: marocchino/sticky-pull-request-comment@v2 with: message: | ## Blast Radius ${{ steps.br.outputs.mermaid }} ``` ## Graphify 上帝节点检测 (可选) 如果你安装了 [`graphify`](https://github.com/graphify-io/graphify) 并且 在你的仓库中运行了 `graphify update .`,`blast-radius` 将使用 传递中心性数据丰富结果,并标记 **上帝节点** (被 30 个以上模块导入的文件): ``` result = get_blast_radius("src/core.py") if result.get("graphify", {}).get("god_node"): print("WARNING: this is a god node — change it carefully") ``` ## 安装说明 ``` # Core (无依赖) pip install impact-radius # 带 Rich 彩色输出 pip install impact-radius[rich] # 带 watchdog 文件监控 (比轮询更快) pip install impact-radius[watch] # Everything pip install impact-radius[all] ``` ## 已知限制 | 限制 | 影响 | 缓解措施 | |------------|--------|------------| | 仅支持静态分析 | 动态导入 (`__import__`, `importlib`) 会被标记,但不会在图谱中进行遍历 | 检查结果中的 `result["dynamic_import_warning"]`;手动验证动态目标 | | 仅支持 Python | 无跨语言分析 | 在多语言仓库中配合使用特定语言的工具 | | 未解析导入别名 | `import numpy as np; np.something` 无法解析符号级别的依赖 | 仍会捕获结构性的文件级依赖 | | 未解析 `__all__` 以进行重新导出 | 通过 `__all__` 重新导出的符号看起来像死胡同 | 按照约定,将重新导出文件视为高影响范围 | | 无运行时导入分析 | 条件导入 (`if TYPE_CHECKING`) 被计为实时依赖 | 使用 `--type-checking-only` 标志 (计划中) 进行过滤 | ## 对比:impact-radius 与替代方案 | 功能 | impact-radius | `pydeps` | `importlab` | `modulegraph` | |---------|--------------|---------|------------|--------------| | 传递影响范围查询 | 是 | 否 | 部分 | 否 | | 增量 SQLite 缓存 | 是 (SHA-256) | 否 | 否 | 否 | | 上帝节点检测 | 是 | 否 | 否 | 否 | | Mermaid 图表输出 | 是 | 否 | 否 | 否 | | 文件监视模式 | 是 | 否 | 否 | 否 | | 动态导入检测 | 是 (已标记) | 否 | 部分 | 否 | | CLI + Python API | 两者皆有 | 仅 CLI | 仅 Python | 仅 Python | | 安装大小 | 最小 | 中等 | 最小 | 中等 | ## 性能 | 项目大小 | 索引构建 | 影响范围查询 | |---|---|---| | 50 个文件 | ~0.3s | <1ms | | 500 个文件 | ~2s | <5ms | | 5,000 个文件 | ~18s | <20ms | 在初次构建之后,增量重新索引仅处理更改过的文件。 查询时间与项目大小无关——SQLite 索引查找的时间复杂度为 O(log n)。 ## 许可证 MIT — 详见 [LICENSE](LICENSE)。 由 [Broken Arrow Entertainment LLC](https://lexipro.online) 构建 · Sovereign Intelligence Systems Group ## OS 集成 — 上帝节点门控 `blast-radius` 接入编辑前的安全门控,在任何 智能体接触高中心性文件之前强制执行硬停止。这是在 [LexiPro Sovereign OS](https://lexipro.online) 中使用的 v9.6 集成模式: ``` # tool_hook_pipeline.py — _hook_guardian_path_guard (v9.6) from blast_radius import get_blast_radius, rebuild_if_stale async def pre_edit_gate(file_path: str) -> dict: rebuild_if_stale(max_age_seconds=300) br = get_blast_radius(file_path) # Hard block — god-node writes require explicit mutex acquisition if br.get("graphify", {}).get("god_node"): in_deg = br["graphify"]["in_degree_sum"] return { "allowed": False, "error": ( f"GOD_NODE_PROTECTED: {file_path} has in_degree_sum={in_deg}. " f"Acquire hard mutex before editing god-node files." ), } # High blast radius — warn + emit contention pheromone if br["total_affected"] >= 10: emit_contention_pheromone(file_path, strength=br["total_affected"] / 50.0) return {"allowed": True, "warning": f"{br['total_affected']} dependents affected"} ``` **上帝节点阈值:** 具有 `in_degree_sum >= 30` 的文件(通过 Graphify)在执行任何写入之前需要获取显式互斥锁。在没有 Graphify 的情况下,当 `total_affected >= 10` 时,门控仍会发出警告。 **信息素广播:** 高影响范围的编辑会向 NeuralBus 发出 `WRITE_CONTENTION` 信号,以便其他智能体能够观察到争议资源,并可以推迟非关键的写入操作。 在你的仓库根目录中运行 `graphify update .` 以生成 `graphify-out/graph.json` 并启用上帝节点检测。
标签:Mermaid, odt, Python, SOC Prime, SQLite, WebSocket, 云安全监控, 代码分析, 代码审查, 代码维护, 依赖关系图, 依赖分析, 凭证管理, 增量索引, 安全规则引擎, 开发工具, 影响范围分析, 抽象语法树, 无后门, 自动化payload嵌入, 调用图, 逆向工具, 重构, 静态分析