尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

使用 Infer 构建 CI 差异化分析流程:从变更文件到增量报告

使用 Infer 构建 CI 差异化分析流程:从变更文件到增量报告 静态分析代码质量开发工具【免费下载链接】inferA static analyzer for Java, C, C, and Objective-C项目地址https://gitcode.com/gh_mirrors/infer/infer点击查看免费下载导读本文基于 Infer 官方推荐的 CI 集成方案website/docs/01-steps-for-ci.md系统讲解如何在持续集成环境中只分析代码变更、对比两个版本的分析结果并输出新增 / 已修复 / 既有三类差异化报告。读完本文你将掌握--changed-files-index、--reactive、--incremental-analysis、--eradicate与infer reportdiff的组合用法能够直接照抄落地到 Git Gradle/Make 等常见 CI 流水线中。CI 集成的推荐思路Infer 官方文档给出的 CI 集成推荐流程是先确定本次变更涉及的文件然后以这些文件为起点以反应式reactive模式启动分析而不是对全量项目做无差别扫描。如果希望在同一份代码上运行多个分析器例如默认分析器之外再叠加eradicate、pulse、starvation等更高效的做法是分离 capture 阶段只捕获一次编译信息让所有分析器复用同一份中间结果避免每个分析器都重复执行构建与翻译。这一思路建立在 Infer 两阶段工作流之上。任何语言Java、Objective-C、C/C的一次 Infer 运行都分为Capture 阶段拦截真实编译命令如javac、clang、make、gradle把源码翻译成 Infer 内部中间表示存放在结果目录infer-out/可用-o修改。值得注意的是若没有文件被编译也就没有文件会被分析。Analysis 阶段对infer-out/中的文件逐个函数/方法进行分析报告输出到标准输出与infer-out/report.txt。完整的背景可参考 01-infer-workflow.md其中详细介绍了全局global与差异化differential两种工作流的适用场景。通用差异化工作流Differential Workflow假设项目使用 Gitfeature是待分析的功能分支main是主干分支项目用make构建。官方推荐按以下步骤在 CI 中对比两个分支的分析结果# go to feature branch if not there already git checkout feature # get list of changed files git diff --name-only origin/feature..origin/main index.txt ## first run: feature branch # run infer on the feature branch infer capture -- make -j 4 # assuming a machine with 4 cores infer analyze --changed-files-index index.txt # store the infer report cp infer-out/report.json report-feature.json ## second run: main branch git checkout main # run capture in reactive mode so that previously-captured source files are kept if they are up-to-date infer capture --reactive --mark-if-unchanged -- make -j 4 infer analyze --incremental-analysis --changed-files-index index.txt # compare reports infer reportdiff --report-current report-feature.json --report-previous infer-out/report.json步骤一提取变更文件清单git diff --name-only origin/feature..origin/main index.txt利用 Git 本身的能力而不是 Infer 自己推断找出两个分支之间的全部变更文件写入index.txt。该文件随后通过--changed-files-index传给 Infer。从 infer/src/base/Config.ml 的选项定义可以看到它的语义Specify the file containing the list of source files from which reactive analysis should start. Source files should be specified relative to project root or be absolute即文件路径要么相对项目根目录要么使用绝对路径分析将从这些文件开始并通过依赖关系波及到受影响的调用方。这里 reactive analysis should start 中的 reactive 一词并非巧合——该选项正是为反应式分析服务的它定义分析的种子文件集而不是让分析器对全部捕获文件做一遍完整扫描。步骤二Feature 分支——先 capture 再 analyze第一次运行拆成两条命令而非一条infer run原因在于分离 capture 阶段以便复用infer capture -- make -j 4-j 4假设机器有 4 核让 make 并行编译Infer 拦截编译调用完成翻译。此时只做翻译不进行分析开销相对可控。infer analyze --changed-files-index index.txt分析从index.txt列出的文件出发。由于这是全新构建的infer-out/分析结果即为 feature 分支的完整报告。之后cp infer-out/report.json report-feature.json把 feature 分支的报告另存下来供最后比对使用。步骤三Main 分支——反应式捕获 增量分析切回main后两条命令出现了三个关键参数--reactive短选项-r告诉 Infer不要删除已有的infer-out/。默认情况下重新运行 Infer 会清空旧的结果目录这也是全局工作流每次全量分析的来源而反应式模式保留之前捕获的、内容未变的源文件翻译结果只有发生变化的文件才需要重新捕获。对于大项目这能显著缩短第二次运行的时间。--mark-if-unchanged即手册中的--mark-unchanged-procs在捕获阶段对新捕获过程做结构等价性比对——若新过程与旧版本结构等价则标记为未变更同时该选项还阻止捕获阶段删除结果数据库使未变更的结果能在后续增量分析中被复用。从 infer/man/man1/infer-capture.txt 的描述看它正是为重跑时尽量保留旧结果服务的。--incremental-analysis只对变更文件执行增量分析它会自动打开--mark-unchanged-procs。手册infer/man/man1/infer-analyze.txt同时注明它不兼容--reanalyze与--continue-analysis使用时需注意。三者配合的逻辑是capture 阶段尽量保留未变文件的中间产物analysis 阶段只重算真正受影响的函数从而让第二次运行只付出变更带来的代价。步骤四生成差异化报告infer reportdiff --report-current report-feature.json --report-previous infer-out/report.jsoninfer reportdiff接收两份标准 JSON 报告--report-current是最新版本此处为 feature 分支--report-previous是基线版本此处为 main 分支。它会在结果目录下的infer-out/differential/中生成三个文件格式与普通 Infer JSON 报告完全一致文件内容introduced.json在 feature 分支中出现、main 中不存在的问题新增fixed.json在 main 中存在、feature 分支中已消失的问题已修复preexisting.json两个分支中都存在的问题既有语义与 man 页infer/man/man1/infer-reportdiff.txt中introduced/fixed/preexisting的定义一一对应。此外infer reportdiff还支持--file-renamings提供文件重命名映射避免因文件改名被误判为新增 修复、--costs-current/--costs-previous对比成本分析报告等选项。这一输出契约在测试基建中也有体现仓库的 infer/tests/diff.make 定义了默认构建目标即$(INFER_OUT)/differential/introduced.json并把introduced.json、fixed.json、preexisting.json三个文件逐一用infer report --from-json-report转成文本期望文件*.exp.test再与基准比对验证差异化报告的正确性。实战示例Android Gradle 多分析器以下 CI 脚本同时运行默认分析与eradicate空安全分析器。假设feature为功能分支main为主干分支git diff --name-only origin/feature..origin/main index.txt infer capture -- ./gradlew --offline assembleDebug infer analyze --fail-on-issue --eradicate --changed-files-index ./index.txt这条脚本浓缩了官方推荐的四个要点用 Git 找出变更文件git diff --name-only不依赖 Infer 自行比对capture 只跑一次输出复用后续所有分析器共享同一份infer-out/叠加额外分析器--eradicate与默认分析器并行运行。eradicate是 Infer 的 Java/Kotlin 空安全分析器检查Nullable/NonNull注解是否被正确传播只分析变更文件--changed-files-index ./index.txt把分析范围限定在变更文件及其依赖闭包内大幅缩短 CI 关键路径。--fail-on-issue让 Infer 在发现问题时以非零退出码结束这是接入 CI 的必要条件——构建门禁build gate据此判定是否阻止合并。需要注意的是若把infer analyze改为infer run则--fail-on-issue需要在 capture 之前的全局参数位置传入分离式写法天然规避了该问题。为什么不直接infer run很多人会问既然infer run -- gradle build一行就能完成为什么 CI 脚本要拆成 capture 与 analyze 两步原因有二多分析器复用infer run的 capture 产物在一次运行结束后仍在infer-out/中保留若想跑第二个分析器只需再次infer analyze --新分析器而不必重跑gradle build。对 Gradle 这类增量构建系统这省去的往往是构建本身的数分钟开销。reactive 语义更清晰infer analyze单独执行时不会清空infer-out/它分析的文件就在那里配合--reactive捕获的既有产物天然契合只分析增量的差异化场景。结合源码理解背后的机制--changed-files-index的定位在 infer/src/base/Config.ml 中定义于Analyze命令的通用参数区说明它专属于分析阶段。分析器以索引文件中的源文件为根沿过程间依赖图Analysis Dependency Graph展开相关实现可追溯至 infer/src/backend/AnalysisDependencyGraph.ml 与 infer/src/base/SourceFile.ml。reactive 捕获的两种推进方式infer capture --reactive适合一批变更一次分析若在多次编辑之间连续运行可加--continue让多次捕获累积成一次分析--continue的语义是保留之前标记为变更的文件/过程并叠加本次新增的变更。官方工作流文档 01-infer-workflow.md 给出了完整示例且提示分析当前变更的隔离结果可以简写为infer run --reactive --continue -- analyze。差异化输出是受测试保护的契约infer/tests/diff.make 把introduced/fixed/preexisting三份 JSON 直接作为测试目标说明这三类文件是 Infer 差分能力对外承诺的稳定接口CI 脚本可以放心依赖其格式。落地建议与注意事项首次运行建议从干净项目开始首次全量 capture 前先make clean/gradle clean确保所有编译命令都被捕获见 01-infer-workflow.md 的 tl;dr。之后的运行才适合叠加--reactive。index.txt路径规范文件内路径应相对项目根目录或为绝对路径否则--changed-files-index可能解析不到目标源文件。多分析器并行需要多个分析器时保持一次 capture 多次 analyze的写法每个infer analyze用对应开关如--eradicate、--pulse、--starvation扩展分析器集合或用--checker-only只跑指定分析器。报告比较infer reportdiff的三个输出文件与普通报告同格式可直接接入后续的告警聚合、PR 评论或看板文件重命名较多时用--file-renamings提供映射以减少误报。CI 门禁用--fail-on-issue结合introduced.json而非全量报告决定是否阻断合并能避免历史遗留问题阻塞新变更的困境。将上述脚本嵌入 Git 钩子、Jenkins/GitHub Actions 或任意 CI 平台即可获得变更驱动、增量分析、前后对比的完整静态分析闭环。赞分享静态分析代码质量开发工具【免费下载链接】inferA static analyzer for Java, C, C, and Objective-C项目地址https://gitcode.com/gh_mirrors/infer/infer点击查看免费下载相关推荐Infer 静态分析器 CI 集成指南reactive 增量分析与差分报告工作流Infer 静态分析器 CI 集成指南reactive 增量分析与差分报告工作流 导读 本文基于 Infer 官方文档《Recommended flow fo静态分析代码质量开发工具Infer 差分报告全解析使用 infer reportdiff 计算两次静态分析结果差异Infer 差分报告全解析使用 infer reportdiff 计算两次静态分析结果差异 infer reportdiff 是 Meta 开源静态分析工具静态分析代码质量开发工具Node.js文件系统增量构建使用node-fs-extra优化构建流程Node.js文件系统增量构建使用node fs extra优化构建流程 你是否还在为Node.js项目构建时的文件复制、清理和同步问题烦恼每次构建都要手动开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表