ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Infer 静态分析器 CI 集成指南:基于差分分析(Differential Workflow)的增量与反应式工作流

Infer 静态分析器 CI 集成指南:基于差分分析(Differential Workflow)的增量与反应式工作流 Infer 静态分析器 CI 集成指南基于差分分析Differential Workflow的增量与反应式工作流【免费下载链接】inferA static analyzer for Java, C, C, and Objective-C项目地址: https://gitcode.com/gh_mirrors/infer/infer本文以 Infer 1.3.0 官方版本文档《Recommended flow for CI》为核心系统讲解如何把 Infer 静态分析器接入持续集成流水线通过git diff定位变更文件、以反应式reactive与增量incremental模式分析、用infer reportdiff对比两个版本的报告最终输出新增/修复/存量三类问题的差分结果。读完本文你将掌握一套可直接复制到 Jenkins、GitHub Actions 或任意 CI 平台的最小可运行脚本并理解每个关键选项在 infer/src/base/Config.ml 与 infer/src/integration/ReportDiff.ml 中的底层实现。CI 集成的推荐总体流程Infer 官方在 CI 场景下推荐的工作流包含两个关键决策先确定变更文件用版本控制工具如 git找出本次代码变更涉及的文件列表从变更文件出发做反应式分析让分析器只以这些文件为起点而不是重新分析整个代码库从而大幅缩短单次 CI 分析耗时。此外若同一个 CI 任务需要运行多个分析器例如默认分析器加上eradicate官方建议把 capture捕获阶段与 analyze分析阶段分离只捕获一次编译产物让所有分析器复用同一份捕获结果避免每个分析器重复编译、重复捕获。差分工作流Differential Workflow两份报告的比较差分分析是 Infer CI 集成的核心模式分别分析 feature 分支代码变更与 main 分支基线再比较两份 JSON 报告得到变更引入了哪些问题、修复了哪些问题。前提约定假设项目使用 gitfeature为功能分支要分析的代码变更main为主分支基线make是项目的构建命令机器有 4 个核示例中-j 4与此对应。完整命令演练# 切到 feature 分支如果尚未切换 git checkout feature # 获取变更文件列表 git diff --name-only origin/feature..origin/main index.txt ## 第一轮分析 feature 分支 # 在 feature 分支上运行 infer 捕获4 核并行构建 infer capture -- make -j 4 # 从变更文件出发进行分析 infer analyze --changed-files-index index.txt # 保存本次报告 cp infer-out/report.json report-feature.json ## 第二轮分析 main 分支 git checkout main # 以反应式模式捕获已捕获且未变化的源文件会保留不重复处理 infer capture --reactive --mark-if-unchanged -- make -j 4 # 对变更文件做增量分析 infer analyze --incremental-analysis --changed-files-index index.txt # 比较两份报告 infer reportdiff --report-current report-feature.json --report-previous infer-out/report.json每一步的作用与设计意图git diff --name-only origin/feature..origin/main index.txt生成变更文件的清单文件供--changed-files-index使用。该清单中每个源文件路径需要相对于项目根目录或使用绝对路径——这正是 Config.ml 中--changed-files-index选项的注释要求Source files should be specified relative to project root or be absolute该清单是反应式分析的起点文件集合。infer capture -- make -j 4捕获阶段截获构建过程中的真实编译命令make/gradle/javac/clang 等为每个编译单元生成中间表示并存入结果数据库。示例中-j 4对应 4 核机器可按 CI 机器配置调整并行度。infer analyze --changed-files-index index.txt只分析变更文件及其受影响的闭包而不是全量重跑分析。其对应实现位于 AnalysisDependencyGraph.ml先为变更文件建立过程集合哈希表再基于磁盘上已有的过程摘要元数据SummaryMetadata.dependencies构建反向分析调用图callee → successor与类型环境tenv依赖映射从而精确识别哪些摘要会受变更影响、需要重算或失效。infer capture --reactive --mark-if-unchanged -- make -j 4--reactive短选项-r反应式模式分析从infer命令启动后捕获的文件开始。其定义见 Config.mlReactive mode: the analysis starts from the files captured since the infer command started--mark-if-unchanged对每个新捕获的过程做结构同一性检查——若与之前捕获的版本等价则标记为 unchanged并且在捕获期间保留 results 数据库不被删除以便后续增量分析复用未变化的分析结果。实现见 Config.ml。infer analyze --incremental-analysis --changed-files-index index.txt对变更文件启用增量分析。该选项与--reanalyze、--continue-analysis不兼容并且会连带开启--mark-unchanged-procs见 Config.ml。配合上一轮--mark-if-unchanged保留的结果数据库分析器只重算真正变化的函数摘要其余直接复用缓存显著加快第二次分析。infer reportdiff --report-current report-feature.json --report-previous infer-out/report.json对两份报告做差分。--report-current是最新修订的报告此处为 feature 分支--report-previous是用于比较的基础修订报告此处为 main 分支参数定义见 Config.ml。reportdiff子命令的完整用法在 CommandDoc.ml 中有描述Given two infer reports previous and current, compute the following three reports and store them inside the differential/ subdirectory。差分结果infer-out/differential/ 下的三个文件整个过程结束后infer-out/differential/目录下会生成三个 JSON 文件格式与普通 Infer JSON 报告一致文件含义introduced.jsonfeature 分支中出现、但 main 分支没有的问题新增问题fixed.jsonmain 分支中存在、但 feature 分支已消失的问题被修复的问题preexisting.json两个分支都存在的问题存量问题这三个文件由 Differential.ml 的to_files函数写入输出目录对应 ResultsDirEntryName.ml 中定义的Differential - directory differential。差分原理基于 issue hash 的集合运算差分算法的核心不是文本 diff而是按 issue 的 hash 值做集合运算。每个 Infer issue 都有一个稳定 hash见 Differential.mllet key_func (issue : Jsonbug_t.jsonbug) issue.hash用于跨版本识别同一个问题。introduced current 中有而 previous 中没有的 hashfixed previous 中有而 current 中没有的 hashpreexisting 两边都有的 hash。值得注意的细节是集合运算会保留 hash 完全相同重复出现的 issue。这一点由单元测试 DifferentialTests.ml 明确验证——test_diff_keeps_duplicated_hashes断言重复 hash 的 issue 全部保留在 introduced 中test_set_operations则验证 introduced/fixed/preexisting 三个集合的元素划分完全正确。此外reportdiff不止支持普通 issue 报告还支持成本cost与配置影响config impact报告的差分当--costs-current/--costs-previous或--config-impact-current/--config-impact-previous同时给出时也会纳入计算若四对参数全部缺失则直接报用户错误见 InferCommandImplementation.ml。成本差分基于复杂度多项式次数degree比较DB DA fixed成本下降视为修复、DB DA introduced成本上升视为新增且从零成本到零成本这类明显过渡会被过滤见 Differential.ml。reportdiff还支持可选过滤通过--differential-filter-files限定只关心某些源文件的问题、用--file-renamings提供文件重命名映射以应对文件改名场景见 ReportDiff.ml。实战示例Android Gradle 项目的 CI 脚本针对 Android 项目官方给出如下 CI 脚本同时运行默认分析器和eradicate空值安全分析器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生成变更清单capture 只跑一次捕获输出保留供默认分析与eradicate分析共同复用——这正是文档开头分离 capture 阶段建议的直接落地附加 eradicate 分析--eradicate让分析器在默认 issue 之外额外运行空值安全相关检查只分析变更文件--changed-files-index ./index.txt限定分析范围缩短 CI 耗时。其中--fail-on-issue是 CI 门禁的关键一旦 Infer 发现任何需要报告的问题进程就以退出码 2结束见 Config.ml 的fail_on_issue_exit_code 2以及 Driver.ml 中if not (List.is_empty issues) then L.exit Config.fail_on_issue_exit_code的实现。CI 系统检测到非零退出码即可中断构建、阻止合入从而把静态分析变成强制的质量关卡。常用配套选项增量失效与分步续跑除了文档中的核心选项以下关联选项可进一步优化 CI 场景下的分析行为--invalidate-only不做实际分析仅从结果数据库中移除所有传递依赖某个已变更过程的摘要后退出Config.ml。适合在大型流水线中先清理缓存、延迟到后续步骤再真正分析--continue在反应式分析的 capture 阶段继续追加捕获扩充变更文件/过程集合同时保留之前的 changed 标记Config.ml--continue-analysis在使用--continue捕获了更多目标后继续分析但要求与其他分析选项保持一致且不能与--reanalyze、--incremental-analysis混用Config.ml--stats-dir-current/--stats-dir-previous对两个版本的分析统计目录做对比输出到infer-out/differential/stats_*.json文件对应实现见 StatsDiff.ml适合需要度量分析耗时等指标变化的场景。小结与最佳实践清单把上面的流程归纳为可复用的 CI 最佳实践用版本控制定位变更git diff --name-only生成index.txt配合--changed-files-index让分析从变更文件出发避免全量重跑分离 capture 与 analyze一次捕获、多次分析默认 --eradicate等显著节省编译成本善用反应式与增量模式--reactive --mark-if-unchanged保留未变化文件的捕获结果--incremental-analysis复用未变化过程的摘要让二次分析更快差分报告驱动代码评审infer reportdiff生成的introduced.json新增问题是评审重点fixed.json可验证修复效果preexisting.json用于跟踪技术债用退出码做门禁--fail-on-issue以退出码 2 中断构建确保新引入的问题不会合入主分支。如需深入了解相关命令的完整参数可继续查阅仓库内的 infer-analyze 手册、infer-capture 手册 与 infer reportdiff 手册以及 infer-report 手册差分算法与过滤器的单元测试见 DifferentialTests.ml 与 DifferentialFiltersTests.ml可作为理解差分语义的第一手资料。【免费下载链接】inferA static analyzer for Java, C, C, and Objective-C项目地址: https://gitcode.com/gh_mirrors/infer/infer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表