longvo92/codegen-compare-tool

GitHub: longvo92/codegen-compare-tool

针对 AUTOSAR/Simulink 代码生成输出进行智能 Diff 对比的工具,自动过滤时间戳和变量重命名等噪声,仅展示真实的语义变更。

Stars: 0 | Forks: 0

# CodeGen 对比工具 [![测试](https://static.pigsec.cn/wp-content/uploads/repos/cas/ce/ce733292a922c08274cf5a2096f8fa4cf01023bfa51a36ef6beecaaef371a9d9.svg)](https://github.com/longvo92/codegen-compare-tool/actions/workflows/test.yml) [![Python 3.8+](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/) [![许可证: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) [![发布](https://img.shields.io/badge/release-v1.1.0-blue.svg)](https://github.com/longvo92/codegen-compare-tool/releases/latest) 对两个 AUTOSAR 代码生成输出文件夹(MATLAB/Simulink Embedded Coder)进行 Diff 对比,并仅展示**重要的变更**。 重新生成 Simulink 模型会重写时间戳、UUID、注释横幅和自动生成的变量名,即使行为完全相同也是如此。该工具将每个代码块(hunk)分类为*真实变更*或*可忽略变更*,随后提供两种查看结果的方式:一个独立的 **HTML 报告**,在文本 Diff 之上提供 AUTOSAR 级别的摘要;以及一个带有变更缩略图的**并排桌面查看器**。 在同一个对比核心之上构建的两个前端,因此判定结果绝不会因查看方式而异: | | 用途 | 运行条件 | |---|---|---| | [**Viewer**](#side-by-side-viewer) | 交互式查看:文件夹树、双窗格 Diff、缩略图 | 命令行未指定文件夹(或双击 `.exe` 时) | | [**CLI**](#command-line) | 流水线和脚本 — 生成报告,使用退出代码拦截构建 | 命令行同时指定两个文件夹 | **对比过程零依赖** — CLI 和 HTML 报告仅需 Python 3.8+ 标准库:无需 pip install,无需服务器,无需互联网访问。[并排查看器](#side-by-side-viewer) 额外需要 PySide6,仅在打开时才会导入。 ## 安装 直接从克隆的仓库运行 — 无需安装: ``` git clone https://github.com/longvo92/codegen-compare-tool.git cd codegen-compare-tool python -m compare_tool --help ``` 或者将其安装为命令(`compare-tool`): ``` pip install git+https://github.com/longvo92/codegen-compare-tool.git ``` 对于无法进行任何安装的设备,请参阅[单文件构建](#single-file-build)。 ## 快速开始 ``` python -m compare_tool [--report out.html] ``` 扫描会生成一个独立的 HTML 报告(默认为 `compare_report.html`),可在任何浏览器中打开,并可作为单个文件共享。 如果省略文件夹,则会改为打开[并排查看器](#side-by-side-viewer) — 将两个文件夹拖放到其中即可: ``` python -m compare_tool ``` 退出代码: | 代码 | 含义 | |---|---| | `0` | 无真实变更 | | `1` | 发现真实变更(可用作 CI 拦截) | | `2` | **对比未完成** — 部分路径无法列出、读取或对比(权限问题、文件被其他进程锁定、长路径等) | 退出代码 `2` 始终会显示:终端中的 `!!`,报告中的红色横幅。`--exit-zero` 无法抑制它。 ## 命令行 | 参数 | 含义 | |---|---| | `--report out.html` | 报告输出路径(默认为 `compare_report.html`)。在扫描开始前,已存在的文件会被删除 | | `--exclude PATTERN` | 跳过匹配 glob 的文件(相对路径或纯文件名),可重复使用。例如:`--exclude compare_report.html` | | `--exit-zero` | 即使存在真实变更也始终退出代码 0(适用于流水线的纯报告模式)。对比错误仍会返回退出代码 2 | | `--arxml-only` | 仅扫描 `.arxml`/`.xml`/`.a2l` 并生成按类型分类的紧凑报告(默认为 `arxml_update.html`) — 即使无变更也会生成 | | `--review FILE` | 从审查文件(`codegen-review.json`,由查看器写入)渲染注释和签署记录,将其显示在所属变更旁边,并附带 `Reviewed` 徽章。必须显式指定;与 `--arxml-only` 一起使用时无效 | | `--qt`, `--viewer` | 在命令行指定文件夹时打开并排查看器,而不是在终端中进行对比。需要 `viewer` 扩展(见下文) | 省略 `old_dir`/`new_dir` 会打开查看器。`--gui`(tkinter 面板)已 在 1.1.0 版本中移除。 ## 并排查看器 桌面应用 (PySide6):文件夹树、带缩略图的双窗格 Diff、单次变更审查备注。 ``` pip install "codegen-compare-tool[viewer]" # or: pip install PySide6 python -m compare_tool # then drop the folders in python -m compare_tool --qt # or start loaded ``` ![并排查看器](https://static.pigsec.cn/wp-content/uploads/repos/cas/f7/f70cee5f160dee34087b1890d34978ec54a67cfc54537da188ae4c1ec6fbf1d8.png) 完整的操作指南已内置到应用中 — 工具栏中的 `User guide`(`F1`)或 `Release notes` 均可离线使用。独立 `.exe`(无需 Python):请参阅[单文件构建](#single-file-build)。 ## 哪些算作噪声 | 类型 | 规则 | 文件 | |---|---|---| | `comment` | C 注释 (`//`, `/* */`)、XML 注释 (``) | .c .h .arxml .a2l | | `rename` | 一致的 1 对 1 变量重命名(MATLAB 自动生成的名称)。映射无法完全解释的任何内容仍视为真实变更 | .c .h | | `uuid` | `UUID="..."` 属性 | .arxml .xml | | `timestamp` | `` 块、`` | .arxml .xml | | `sw-version` | `` 版本戳(每次重新生成时都会递增)。已锚定,因此 `` 等类似项不受影响 | .arxml .xml | | `whitespace` | 缩进、行尾空格、空行 | 所有 | | `line-endings` | CRLF 与 LF,BOM | 所有 | 自动生成的名称扰动被识别为 `rename`:诸如 `rtb_*` 的 Embedded Coder 临时变量、混淆后缀以及重新编号的临时变量在不同运行间会发生变化,但不会改变行为。 **注释变更有其独立的类别。** 如果文件的差异*仅*包含注释,则会报告为**Comment**,与**Unimportant**(UUID、时间戳、SW-VERSION、重命名、空白)分开 — 重写的注释横幅与重命名的标识符在分类上是不同的。CLI 摘要中有独立的计数,查看器中有其专属的树标记和颜色(紫色与黄色)。如果文件中混合了注释*以及*其他噪声,则仍归为 Unimportant。HTML 报告保留判定结果,但不显示注释内容 — 请参阅 [HTML 报告](#html-report)。 ## 移动块检测 在一个位置被删除并在其他位置完整重现的代码块(当模型发生变化时,Embedded Coder 会重新排列函数和声明)会被标记为 `moved`,并显示为**蓝色**,而不是红色/绿色。这仍计为**Modified** — 因为重排可能会改变行为 — 只是它比两个巨大的红/绿块更容易查看。 ## AUTOSAR 语义摘要 该工具会提取双方的 AUTOSAR 信息,并在**语义**级别(而不仅仅是文本)报告变更: | 来源 | 提取内容 | 报告内容 | |---|---|---| | `.arxml`/`.xml` | **端口接口** (SENDER-RECEIVER, CLIENT-SERVER, MODE-SWITCH, NV-DATA, PARAMETER, TRIGGER) 及其完整的包路径 | 已添加 / 已移除 | | `.arxml`/`.xml` | **SWCs** (APPLICATION, SENSOR-ACTUATOR, SERVICE, CDD, ECU-ABSTRACTION, NV-BLOCK) | 已添加 / 已移除 | | `.arxml`/`.xml` | SWC **端口** (P/R/PR + 引用的接口)、**runnables** (+ SYMBOL)、**事件** (类型, PERIOD, 触发的 runnable) | 已添加 / 已移除 / **已变更** (例如 TIMING-EVENT 周期从 `0.01s → 0.02s`,或端口指向了不同的接口) | | `.c` | **RTE 访问点** — 每个 `Rte_Read/Write/Call/IrvRead/IrvWrite/Mode/Switch/…` 调用(计数前会剥离注释) | 已添加 / 已移除 | | `.a2l` | **标定对象** — 按名称分类的 `CHARACTERISTIC` / `MEASUREMENT`(优先剥离注释和字符串,因此被注释掉的块不会被计数) | 已添加 / 已移除 | 展示方式: - **CLI**:`ARXML interfaces`、`AUTOSAR behavior`、`RTE access points` 和 `A2L objects` 块会列出带有各自所属文件的 `+`/`-`/`~` 条目。 - **HTML 报告**:页面顶部的 **AUTOSAR changes** 部分,按类型分组(端口接口 / 软件组件 / 端口 / runnables / 事件 / RTE 访问点 / A2L 特性和测量值)。点击文件名可跳转到其详细的 Diff,且详细变更中的每个文件都会带有其专属的 `Interfaces:` / `Behavior:` / `RTE:` / `A2L:` 备注。 - 整体添加或删除的文件,会将其中包含的所有接口 / SWC / RTE 调用 / A2L 对象计为已添加或已移除。 XML 解析失败的文件将被排除在此摘要之外(但其文本 Diff 仍会完整显示)。未知的 `Rte_` 调用不会在此处计数,但依然会出现在 Diff 中。 ## 按模型 / SWC 分组 文件会使用 Embedded Coder AUTOSAR 命名约定(`X.c`、`X.h`、`X.arxml`、`Rte_X.h`、模块化 ARXML 集等)按 **Simulink 模型**进行分组。不匹配任何模型的文件将归入最后的 **Shared / other** 组。 ## HTML 报告 每次对比生成一个独立的文件:包含徽章切换、文件夹树、过滤框以及每个文件的可折叠 Diff。默认隐藏 `Unimportant` 并展开 `Modified`,以便直接聚焦于重要内容。 ![报告查看器](https://static.pigsec.cn/wp-content/uploads/repos/cas/b2/b2b2fe30235bca06dad34418e67f04f693b7a47cb08da10cb560f7dc52bd5e6b.png) ## CI 集成 作为流水线关卡运行 — 一条命令,有意义的退出代码: ``` python -m compare_tool old_dir new_dir --exit-zero --exclude compare_report.html ``` `--exit-zero` 可确保在重新生成的代码上保持构建通过;`--exclude` 可防止将上一次运行的报告计入 Diff。请将 `compare_report.html` 发布为构建产物。 有关具体示例,请参阅 [azure-pipelines.yml](azure-pipelines.yml)(OLD 通过 `git worktree` 检出,NEW 为工作树)。 ## 单文件构建 ``` .\build.ps1 # dist\compare-tool.exe - one file, nothing to install on the target .\build.ps1 -Pyz # also dist\compare_tool.pyz (~26 KB) for machines that have Python 3.8+ .\build.ps1 -PyzOnly # zipapp only (building it needs no PyInstaller / PySide6) ``` `dist\compare-tool.exe` 是**一个集成了两个前端的二进制文件**,并带有该工具专属的图标: | 调用方式 | 结果 | |---|---| | `compare-tool.exe [flags]` | CLI:扫描,生成 HTML 报告,退出代码为 `0`/`1`/`2` | | `compare-tool.exe --qt ` | 并排查看器,自动加载指定的文件夹 | | 双击(无参数) | 并排查看器,等待放入两个文件夹 | 它作为**控制台**应用程序构建,因此终端运行可以保留其退出代码(`1` = 真实变更,`2` = 对比未完成)供 CI 关卡使用。查看器在运行时会隐藏控制台窗口 — 双击时您会看到短暂闪烁。如果发生崩溃,控制台将取消隐藏,以便查看错误。 - **`.pyz` (zipapp, 标准库)**:`python compare_tool.pyz [flags]`。当有 Python 环境时首选此方式 — 大小约 26 KB,无构建依赖,不会被杀毒软件标记。CLI 可在任何地方运行;查看器额外需要该机器上安装有 PySide6(若未安装,工具会给予提示而不是直接打开)。 - **`.exe` (PyInstaller onefile, ~47 MB)**:目标机器上无需 Python。构建过程需要开发机上安装有 `pyinstaller` 和 `PySide6`(`build.ps1` 会安装它们),并且生成的二进制文件只能在构建它的操作系统上运行。PyInstaller 可执行文件有时会被杀毒软件或 AppLocker 拦截 — 在这种情况下,请退而使用 `.pyz`。 所有 CLI 参数在打包构建版本中的行为完全一致。`build/` 和 `dist/` 已经包含在 `.gitignore` 中。 ## 开发 ``` python -m unittest discover -s tests ``` CI 会在 Linux 和 Windows 上针对 Python 3.8 和 3.11 运行测试套件,此外还会对 fixture 树进行无头扫描,以检查报告和退出代码。 ``` compare_tool/ ├── main.py # entry point: picks the CLI or the viewer, run_compare() core ├── resources.py # finds the shipped icons/logo, in a checkout and in the .exe ├── qtviewer/ # PySide6 side-by-side viewer (app, diff pane, minimap, dialogs) ├── scanner.py # walks both trees, pairs files by relative path ├── diff_engine.py # two-pass diff (raw + normalized), hunk classification, moved-block detection ├── c_rules.py # C/H rules: strip comments, tokenize, detect renames, extract RTE access points ├── arxml_rules.py # ARXML rules: UUID, ADMIN-DATA, DATE, comments + extract port interfaces, SWCs (ports/runnables/events) ├── a2l_rules.py # A2L rules: strip C-style comments + extract CHARACTERISTIC/MEASUREMENT └── report.py # self-contained HTML report (badge toggles, model overview, grouping, filter, collapsible diffs) ``` 添加规则的方法:在c_rules.py` / `arxml_rules.py` 中编写过滤函数,然后将其注册到 shadow builder 以及 `diff_engine.py` 中的 `_build_variants`。 欢迎提交 Issues 和 pull requests。请保持**对比核心仅使用标准库** — 它必须在锁定的构建服务器上运行,因此 PySide6 仅限于保留在 `compare_tool/qtviewer/` 中,且仅在查看器打开时才导入 — 并且请在 `tests/` 下为任何新规则添加测试。 ## 作者 **Long Vo Thien** ## 许可证 基于 [MIT License](LICENSE) 发布 © 2026 Long Vo Thien。
标签:AUTOSAR, HTML报告, Python, Simulink, SOC Prime, 代码对比, 代码生成, 开发工具, 无后门, 渗透测试工具, 漏洞挖掘, 逆向工具