预兆
](https://www.rust-lang.org/)    
你的AI在不知道地雷在哪里的情况下编写代码。
Omen为AI助手提供了他们所需的环境:复杂性热点、隐藏的依赖关系、易出现缺陷的文件和自认的债务。一个命令显示不可见的内容。
为什么是“预兆”? 预兆是即将发生的事情的征兆,无论是好是坏。你的代码库充满了预兆:低复杂性和干净的架构预示着未来的顺利发展,而高流失率、技术债务和代码克隆则预示着麻烦的酝酿。Omen会显示这些信号,这样你就可以在“临时修复”庆祝生产三周年之前采取行动。
______________________________________________________________________
特性
Complexity Analysis - How hard your code is to understand and test
复杂性有两种类型:
- 圈复杂度 计算代码中不同路径的数量。每
if,for,while,或switch创建了一条新路径。圈复杂度为10的函数意味着有10种不同的方式来运行它。数字越高,你需要覆盖所有场景的测试用例就越多。
- 认知复杂度 衡量人类阅读代码的难度。它惩罚深度嵌套的代码(如
if内部afor在另一个if)不仅仅是简单的代码。两个函数可以具有相同的圈复杂度,但嵌套更深的函数将具有更高的认知复杂度,因为它更难跟踪。
为什么重要: 研究表明,复杂的代码有更多的错误,需要更长的时间来修复。 麦卡贝1976年的原始论文 发现复杂度超过10的函数更难维护。 SonarSource的认知复杂性 在此基础上,通过衡量真正让开发人员困惑的东西来构建。
\[!提示\] 每个函数的圈复杂度应控制在10以下,认知复杂度应保持在15以下。
Self-Admitted Technical Debt (SATD) - Comments where developers admit they took shortcuts
当开发者写 TODO: fix this later 或 HACK: this is terrible but works,他们正在制造技术债务并承认这一点。Omen找到了这些评论,并按类型对其进行了分组:
| 类别 | 标记 | 这意味着什么 |
|---|---|---|
| 设计 | HACK、KLUDGE、SMELL | 需要重新思考的架构捷径 |
| 缺陷 | BUG、FIXME、BROKEN | 尚未修复的已知错误 |
| 需求 | TODO、FEAT | 缺少功能或实现不完整 |
| 测试 | 失败、打滑、禁用 | 损坏或关闭的测试 |
| 性能 | 慢、优化、性能 | 代码可以工作,但需要更快 |
| 安全 | 安全、VULN、UNSAFE | 已知安全问题 |
为什么重要: Potdar和Shihab 2014年的研究 发现SATD注释通常会在代码库中保留多年。他们呆的时间越长,就越难修复,因为人们忘记了背景。 马尔多纳多和谢哈布(2015) 表明设计债是最常见、最危险的类型。
\[!提示\] 每周复习SATD。如果TODO超过6个月,请修复或删除它。
Dead Code Detection - Code that exists but never runs
死代码包括:
- 从未被调用的函数
- 已分配但从未使用的变量
- 从未实例化的类
- 代码后a
return永远无法执行的语句
为什么重要: 死代码不仅仅是杂乱。它让那些认为它一定很重要的新开发人员感到困惑。它增加了构建时间和二进制大小。最糟糕的是,它可以隐藏错误——如果有人“修复”了认为它可以运行的死代码,他们就浪费了时间。 Romano等人(2020) 发现死代码是其他代码质量问题的强预测因素。
\[!提示\] 删除死代码。版本控制意味着如果需要,您可以随时取回它。
Git Churn Analysis - How often files change over time
Churn查看您的git历史记录并计数:
- 每个文件被修改了多少次
- 添加和删除了多少行
- 哪些文件一起更改
高流失率的文件是“热点”——它们经常被触碰,这可能意味着它们:
- 系统的核心(每个人都需要修改它们)
- 设计不佳(不断修复错误)
- 缺少良好的抽象(功能不断被添加)
为什么重要: Nagappan和Ball 2005年在微软的研究 发现代码流失是bug的最佳预测因素之一。变化很大的文件往往有更多的缺陷。结合复杂性数据,流失可以帮助您找到既复杂又经常修改的文件,这是风险最高的代码。
\[!提示\] 如果一个文件具有高流失率和高复杂性,请优先对其进行重构。
Code Clone Detection - Duplicated code that appears in multiple places
有三种类型的克隆:
| 类型 | 描述 | 示例 |
|---|---|---|
| Type-1 | 精确副本(可能是不同的空格/注释) | 复制粘贴的代码 |
| Type-2 | 相同的结构,不同的名称 | 具有重命名变量的相同函数 |
| Type-3 | 经过一些修改的类似代码 | 执行几乎相同功能的函数 |
为什么重要: 当你修复一个副本中的错误时,你必须记住也修复所有其他副本。 Juergens等人(2009) 发现克隆代码有更多的错误,因为修复没有得到一致的应用。你拥有的克隆越多,在更新过程中就越有可能错过一个。
\[!提示\] 复制两次以上的任何内容都应该是共享函数。目标是复制率低于5%。
Defect Prediction - The likelihood that a file contains bugs
Omen结合多个信号,使用PMAT加权指标预测缺陷概率:
- 过程 指标(流失频率、所有权扩散)
- 指标 (圈/认知复杂性)
- 年龄 (代码年龄和稳定性)
- 总计 大小(代码行数)
每个文件都会得到0%到100%的风险评分。
为什么重要: 你不可能对每件事都一视同仁。 孟席斯等人(2007) 表明缺陷预测有助于团队将测试和代码审查重点放在最有可能出现问题的文件上。 Rahman等人(2014年) 发现即使是简单的模型在发现bug方面也优于随机文件选择。
\[!提示\] 优先考虑缺陷概率>70%的文件的代码审查。
Change Risk Analysis (JIT) - Predict which commits are likely to introduce bugs
准时制(JIT)缺陷预测分析最近的提交,以在导致问题之前识别有风险的更改。与文件级预测不同,JIT在提交级使用以下更改范围因子进行操作 Kamei等人(2013),并辅以软件工程研究文献中的文件级风险信号。
更改范围因素(得分的75%):
使用Kamei的中值逻辑回归系数加权(项目间的相对排序):
| 因素 | 名称 | 重量 | 测量内容 |
|---|---|---|---|
| LA | 增加的行数 | 0.16 | 增加的越多=风险越大(最强预测因素) |
| 熵 | 变化熵 | 0.14 | 分散的变化=更难审查 |
| FIX | Bug FIX | 0.12 | Bug修复提交表明存在问题的区域 |
| LD | 已删除行 | 0.08 | 删除通常更安全 |
| NF | 文件数量 | 0.08 | 文件越多=协调风险越大 |
| NUC | 唯一更改 | 0.07 | 文件上更独特的先前提交 |
| NDEV | 开发人员数量 | 0.05 | 文件上的开发人员越多=风险越大 |
| EXP | 开发人员经验 | 0.05 | 经验越少=风险越大 |
文件级风险信号(得分的25%):
| 信号 | 权重 | 来源 |
|---|---|---|
| 文件流失 | 0.10 | 纳加潘与鲍尔(2005) -历史变化频率预测缺陷 |
| 文件复杂性 | 0.08 | 齐默尔曼和纳加潘(2008) -圈复杂度具有预测性,但比变化指标弱 |
| 所有权扩散 | 0.07 | Bird等人(2011) -有许多次要贡献者(没有明确的所有者)的文件有更多的缺陷 |
所有权扩散是 1 - max_author_percentage:没有单一作者占主导地位的文件风险更高。Bird等人的研究发现,集中所有权(明确的主要作者)与 *较少* 缺陷,而分散的所有权与更多相关。
基于百分位数的风险分类:
风险水平使用基于百分比的阈值,遵循JIT缺陷预测最佳实践。提交不是固定阈值,而是相对于存储库自己的分布进行排名:
| 级别 | 百分位数 | 含义 |
|---|---|---|
| 高 | 前5% | P95+-值得额外审查 |
| 中等 | 前20% | P80-P95-值得额外关注 |
| 低 | 底部80% | 低于P80-标准审查流程 |
这种方法符合缺陷预测研究中的80/20规则:约20%的代码更改包含约80%的缺陷。它确保了可操作的结果,而不管存储库的特征如何——纪律严明的存储库将有较低的阈值,而高流失的存储库则有较高的阈值。
为什么重要: Kamei等人(2013) 证明了JIT预测在bug传播之前的提交时捕获了有风险的更改。他们的努力意识方法使用排名而不是固定阈值,将有限的审查资源集中在风险最高的约20%的提交上。 曾等(2021) 结果表明,简单的JIT模型与深度学习的准确率(~65%)相匹配,具有更好的可解释性。
\[!提示\] 跑 omen changes 在合并PR以识别需要额外审查的提交之前。PR/Branch Diff Risk Analysis - Assess overall risk of a branch before merging
JIT分析检查单个提交,而差异分析则评估整个分支相对于目标分支的累积更改。这为审阅者在深入代码审阅之前提供了快速的风险评估。
用途:
# Compare current branch against main
omen diff --target main
# Compare against a specific commit
omen diff --target abc123
# Output as markdown for PR comments
omen diff --target main -f markdown风险因素:
差异分析仪使用与 omen changes (见上文),将更改范围因素与文件级信号相结合:
| 因素 | 衡量标准 | 类别 |
|---|---|---|
| 新增行数 | 引入的新代码总数 | 更改范围 |
| 删除行 | 删除代码 | 更改范围 |
| 文件已修改 | 更改的传播 | 更改范围 |
| 提交 | 分支中的提交数 | 更改范围 |
| 熵 | 变化的分散程度 | 变化范围 |
| 文件流失 | 被触摸文件的历史变化频率 | 文件级别 |
| 文件复杂性 | 被触摸文件的最大圈复杂度 | 文件级 |
| 所有权扩散 | 被触摸文件的所有权扩散程度 | 文件级别 |
风险评分解释:
| 分数 | 级别 | 建议行动 |
|---|---|---|
| \0.5 | 高 | 彻底审查,确保全面的测试覆盖率 |
输出示例:
Branch Diff Risk Analysis
==========================
Source: feature/new-api
Target: main
Base: abc123def
Risk Score: 0.31 (MEDIUM)
Changes:
Lines Added: 530
Lines Deleted: 39
Files Modified: 3
Commits: 1
Risk Factors:
entropy: 0.023
lines_added: 0.140
lines_deleted: 0.008
num_files: 0.014
commits: 0.007
file_churn: 0.080
file_complexity: 0.045
ownership_diffusion: 0.000
File Risk:
max_complexity: 6.78
max_churn: 1.00
ownership_diffusion: 0.00寻找什么:
- 添加高行,删除低行 -新功能,需要彻底审查
- 平衡添加/删除 -重构,验证行为不变
- 净代码减少 -清理/简化,总体上是积极的
- 高熵 -零散的更改,检查是否有无关的修改
- 许多文件 -影响广泛,确保集成测试
- 高文件_churn -触摸历史上经常变化的不稳定文件
- 所有权高度分散 -被触碰的文件没有明确的所有者;确保有人负责审查
CI/CD集成:
# Add to GitHub Actions workflow
- name: PR Risk Assessment
run: |
omen diff --target ${{ github.base_ref }} -f markdown >> $GITHUB_STEP_SUMMARY为什么重要: 代码审查时间有限。差异分析有助于审阅者优先考虑他们的注意力——与涉及17个文件的中等风险PR相比,更改了10行的低风险PR需要更少的审查。熵度量对于捕获捆绑不相关更改的PR特别有用,这些更改更难审查,也更有可能引入错误。
\[!提示\] 跑 omen diff 在创建PR之前,了解审阅者将如何看待您的更改。考虑将高风险PR拆分为更小、更集中的更改。Technical Debt Gradient (TDG) - A composite "health score" for each file
TDG将多个指标组合成一个分数(0-100分,越高越好):
| 组件 | 最大点数 | 它测量什么 |
|---|---|---|
| 结构复杂性 | 20 | 圈复杂度和嵌套深度 |
| 语义复杂性 | 15 | 认知复杂性 |
| 复制 | 15 | 克隆代码量 |
| 耦合 | 15 | 与其他模块的依赖关系 |
| 热点 | 10 | 流失x复杂性交互 |
| 时间耦合 | 10 | 与其他文件共同改变模式 |
| 一致性 | 10 | 代码风格和模式遵循 |
| 熵 | 10 | 模式熵与编码均匀性 |
| 文档 | 5 | 评论覆盖率 |
为什么重要: 技术债务就像金融债务一样——一点点就好,太多就死定了。 坎宁安在1992年创造了这个词,以及 Kruchten等人(2012) TDG为您提供了一个随时间跟踪和跨文件比较的单一数字。
\[!提示\] 在添加新功能之前,先修复得分低于70的文件。随着时间的推移,追踪平均TDG——它应该上升,而不是下降。
Dependency Graph - How your modules connect to each other
Omen构建了一个图表,显示哪些文件导入了哪些其他文件,然后计算:
- 网页排名:哪些文件是最“中心”的(许多事情都取决于它们)
- 中介性:哪些文件是代码库不同部分之间的“桥梁”
- 耦合:模块之间的相互连接方式
为什么重要: 高度耦合的代码是脆弱的——更改一个文件会破坏许多其他文件。 Parnas 1972年关于模块化的论文 建立了良好的软件设计可以最大限度地减少模块之间的依赖关系。依赖关系图显示了你的架构在哪里是干净的,在哪里是混乱的。
\[!提示\] 具有高PageRank的文件应该特别稳定并且经过良好测试。考虑拆分随处可见的“桥接”文件。
Hotspot Analysis - High-risk files where complexity meets frequent changes
热点是复杂且经常修改的文件。一个经常更改的简单文件可能很好——它很容易使用。一个很少更改的复杂文件也是可以管理的——你可以不去管它。但是一个不断变化的复杂文件呢?这就是虫子滋生的地方。
Omen使用以下公式计算热点得分 几何平均数 标准化的流失和复杂性:
hotspot = sqrt(churn_percentile * complexity_percentile)这两个因素都使用经验CDF根据行业基准进行了归一化,因此各个项目的得分是可比的:
- 流失百分比 -此文件的提交计数与典型的OSS项目相比排名如何
- 复杂性百分比 -平均认知复杂性与行业基准相比
| 热点评分 | 严重性 | 行动 |
|---|---|---|
| >=0.6 | 关键 | 立即确定优先级 |
| >=0.4 | 高 | 审查时间表 |
| >=0.25 | 中等 | 监视器 |
| \ \[!提示\] |
从你的前三个热点开始重构。降低高流失文件的复杂性具有最高的投资回报率。
Temporal Coupling - Files that change together reveal hidden dependencies
当两个文件在相同的提交中持续变化时,它们在时间上是耦合的。这常常揭示:
- 隐藏的依赖关系 在导入语句中不可见
- 逻辑耦合 其中一个文件中的更改需要另一个文件的更改
- 意外耦合 来自复制粘贴或不一致的抽象
Omen分析你的git历史记录,找出一起更改的文件对:
| 联接强度 | 含义 |
|---|---|
| >80% | 几乎总是一起变化——可能是紧密依赖 |
| 50-80% | 经常耦合-调查关系 |
| 20-50% | 中度结合-可能是巧合 |
| \ \[!提示\] |
如果两个文件的时间耦合度大于50%,但没有导入关系,请考虑提取共享模块或合并它们。
Code Ownership/Bus Factor - Knowledge concentration and team risk
总线系数问:“在这个代码变得无法维护之前,需要有多少人被总线撞到?”总线系数低意味着知识集中在太少的人身上。
Omen使用git责备来计算:
- 主要所有者 -谁写了大部分代码
- 股权比例 -一个人拥有多少百分比
- 贡献者计数 -有多少人碰过这个文件
- 公共要素 -主要贡献者数量(超过代码的5%)
| 所有权比率 | 风险水平 | 这意味着什么 |
|---|---|---|
| >90% | 高风险 | 单点故障 |
| 70-90% | 中等风险 | 知识共享有限 |
| 50-70% | 低风险 | 健康分布 |
| \ \[!提示\] |
单一所有权超过80%的文件应记录知识转移。关键文件应至少有2人理解。
CK Metrics - Object-oriented design quality measurements
Chidamber Kemerer(CK)度量套件衡量面向对象的设计质量:
| 度量 | 名称 | 度量内容 | 阈值 |
|---|---|---|---|
| WMC | 每类加权方法 | 方法复杂性之和 | \ \[!提示\] |
违反多个CK阈值的类是重构的候选者。高WMC+高LCOM通常表示应该拆分的“上帝类”。
Repository Map - PageRank-ranked symbol index for LLM context
存储库映射提供了代码库重要符号的简洁摘要,使用PageRank按结构重要性进行排序。这是为LLM上下文窗口设计的,您首先会得到最重要的函数和类型。
对于每个符号,地图包括:
- 名称和种类 (函数、类、方法、接口)
- 文件位置 以及行号
- 签名 为了快速理解
- PageRank得分 基于有多少其他符号依赖于它
- 入/出度 显示依赖关系连接
为什么重要: LLM的上下文窗口有限。用整个文件填充它们会浪费不太重要的代码上的令牌。PageRank, 布林和佩奇(1998)开发,标识图中结构上重要的节点。应用于代码时,它会显示对理解代码库最重要的符号。
可扩展性: Omen使用稀疏幂迭代算法进行PageRank计算,随边数O(E)线性缩放,而不是随节点数O(V^2)二次缩放。这使得在30秒内快速分析25000多个符号的大型monorepos成为可能。
输出示例:
# Repository Map (Top 20 symbols by PageRank)
## parser.ParseFile (function) - pkg/parser/parser.go:45
PageRank: 0.0823 | In: 12 | Out: 5
func ParseFile(path string) (*Result, error)
## models.TdgScore (struct) - pkg/models/tdg.go:28
PageRank: 0.0651 | In: 8 | Out: 3
type TdgScore struct\[!提示\] 使用 omen context --repo-map --top 50 为LLM提示生成上下文。前50个符号通常捕捉到基本的架构。Feature Flag Detection - Find and track feature flags across your codebase
功能标志很强大,但很危险。它们允许您在不启用代码的情况下发布代码,运行A/B测试,并逐步推出功能。但它们在积累。2019年的“临时”国旗仍在生产中。您为一周的实验添加的标志现在是承重基础设施。
Omen检测流行提供商的功能标志使用情况:
| 提供者 | 语言 | 它发现了什么 |
|---|---|---|
| 暗启动 | JS/TS | variation(), boolVariation() 电话 |
| 拆分 | JS/TS | getTreatment() 电话 |
| 释放 | JS/TS、Python | isEnabled(), is_enabled() 电话 |
| Flipper | Ruby | Flipper[:flag], enabled?() 电话 |
| 基于ENV的 | Ruby、JS/TS、Python | ENV["FEATURE_*"], process.env.FEATURE_* |
您可以通过自定义树保姆查询添加其他提供者 omen.toml 配置。
对于每个标志,Omen报告:
- 标志键 -代码中使用的标识符
- 提供者 -正在使用哪个SDK
- 参考文献 -检查旗帜的所有位置
- 陈旧 -标志第一次和最后一次修改的时间(带git历史记录)
自定义提供商: 对于内部特征标志系统,请在您的 omen.toml:
[[feature_flags.custom_providers]]
name = "feature"
languages = ["ruby"]
query = '''
(call
receiver: (constant) @receiver
(#eq? @receiver "Feature")
method: (identifier) @method
(#match? @method "^(enabled\\?|get_feature_flag)$")
arguments: (argument_list
.
(simple_symbol) @flag_key))
'''为什么重要: Meinicke等人(2020) 研究了开源项目中的功能标志,发现标志所有权(引入标志的开发人员也会删除它)与较短的标志寿命相关,有助于控制技术债务。 Rahman等人(2018年) 研究了谷歌Chrome浏览器的12000多个功能切换,发现虽然它们能够实现快速发布和灵活部署,但它们也带来了技术债务和额外的维护负担。定期的标志审核可以防止你的代码库变成一个未使用的开关迷宫。
\[!提示\] 审计功能每月标记一次。对于实验,删除超过90天的标志,对于发布标志,删除超过14天的标志。跟踪CI管道中的标志过期情况。
Repository Score - Composite health score (0-100)
Omen计算一个组合了多个分析维度的复合存储库健康评分(0-100)。这提供了代码库质量的快速概述,并在CI/CD中启用了质量门。
分数构成:
| 组件 | 重量 | 测量内容 |
|---|---|---|
| 复杂性 | 25% | %的函数超过复杂性阈值 |
| 重复 | 20% | 非线性惩罚曲线的代码克隆率 |
| SATD | 10% | 每1K LOC的严重性加权TODO/FIXME密度 |
| TDG | 15% | 技术债务梯度综合得分 |
| 耦合 | 10% | 循环deps、SDP违规和不稳定性 |
| 气味 | 5% | 相对于代码库大小的架构气味 |
| 内聚性 | 15% | 面向对象代码库的类内聚性(LCOM) |
规范化理念:
每个组件指标都被标准化为0-100的范围,其中越高越好。归一化函数的设计如下:
- 公平的 -具有相似严重程度的不同指标会产生相似的分数
- 校准的 -基于SonarQube、CodeClimate和CISQ的行业基准
- 非线性的 -轻微问题处罚轻微,严重问题处罚严厉
- 严重性意识 -按影响对物品进行称重,而不仅仅是计数
例如,SATD(自认技术债务)使用严重性加权评分:
- 关键(安全、脆弱):4倍重量
- 高(FIXME,BUG):2倍重量
- 介质(HACK、REFACTOR):1倍重量
- 低(TODO,注):0.25倍重量
这可以防止低严重性项目(如文档TODO)不公平地降低分数。
TDG(技术债务梯度)通过分析每个文件中的结构复杂性、语义复杂性、复制模式和耦合性,提供了一个互补的视图。
用途:
# Compute repository score
omen score
# JSON output for CI integration
omen -f json score调整阈值:
对于现实世界的代码库来说,达到100分几乎是不可能的。在中设置现实的阈值 omen.toml 基于你的代码库:
[score.thresholds]
score = 80 # Overall score minimum
complexity = 85 # Function complexity
duplication = 65 # Code clone ratio (often the hardest to improve)
defect = 80 # Defect probability
debt = 75 # Technical debt density
coupling = 70 # Module coupling
smells = 90 # Architectural smells跑 omen score 要查看您当前的分数,请将阈值设置为略低于这些值。随着时间的推移逐渐增加。
执行承诺 左撇子:
添加 lefthook.yml:
pre-push:
commands:
omen-score:
run: omen score这可以防止推送不符合质量阈值的代码。
为什么重要: 单一健康评分可实现质量门,跟踪随时间变化的趋势,并提供快速的代码库评估。加权复合确保关键问题(缺陷、复杂性)比外观问题具有更大的影响。
\[!提示\] 从可实现的阈值开始,并在改进代码库时增加它们。重复性通常是遗留代码中最难改进的指标。
Semantic Search - Natural language code discovery
按含义搜索代码库,而不仅仅是关键字。Omen使用带有子线性TF、平滑IDF和二元组标记化的TF-IDF引擎,从自然语言查询中查找语义相似的代码。无需外部模型,无需API密钥,无需GPU。
# Build the search index
omen search index
# Search for code
omen search query "database connection pooling"
omen search query "error handling middleware" --top-k 20
omen search query "authentication" --files src/auth/,src/middleware/
# Cross-repo search
omen search query "retry logic" --include-project /path/to/other-repo
# Filter by complexity
# (via MCP: semantic_search with max_complexity parameter)它是如何工作的:
- 符号提取 -使用树形图从代码库中提取函数
- AST感知分块 -在语句边界分割长函数,使每个块都是集中的和自包含的。父类型上下文(类、结构、impl)被保留。
- TF-IDF索引 -使用L2归一化余弦相似度构建稀疏向量索引。典型代码库的索引时间约为1-2秒。
- 增量更新 -仅重新索引自上次运行以来更改的文件
- 去重 -每个符号在结果中出现一次(得分最高的块获胜)
特征:
- HyDE搜索 -编写一个假设的代码片段作为查询,以获得更好的匹配(可通过MCP获得
semantic_search_hyde工具) - 复杂性过滤 -从结果中排除高复杂度函数(
max_complexityMCP工具上的参数) - 多回购搜索 -使用统一的IDF评分跨多个项目索引查询(
--include-project) - 每个功能指标 -结果包括圈复杂度和认知复杂度(如有)
演出
| 度量 | 值 |
|---|---|
| 索引时间 | ~1-2s(1400个符号) |
| 查询时间 | ~250ms |
| 存储 | SQLite .omen/search.db |
| 依赖关系 | 零外部(纯Rust TF-IDF) |
为什么重要: 传统的grep/ripgrep会找到精确匹配。语义搜索可以找到以下代码 *手段* 即使命名不同,也是一样的。询问“我们如何验证用户输入”,并找到名为 sanitize_params, check_request,或 validate_form.
\[!提示\] 跑 omen search index 在重大重构之后或在新代码库上线时。索引会在后续运行中逐步更新。Mutation Testing - Test suite effectiveness through code mutation
突变测试通过向代码引入小的更改(突变)并检查测试是否失败来衡量测试套件捕获错误的程度。“杀死”突变体意味着测试发现了病毒;一个“幸存”的突变体意味着一只虫子可能会溜走。
21位突变操作员:
| 类别 | 运算符 | 它们变异了什么 |
|---|---|---|
| 核心 | CRR、ROR、AOR、COR、UOR | 文字、关系运算、算术、条件、一元 |
| 高级 | SDL、RVR、BVO、BOR、ASR | 语句删除、返回值、边界、位、赋值 |
| Rust | 借用运算符、选项运算符、结果运算符 | 借用语义、选项/结果处理 |
| Go | GoErrorOperator,GoNilOperator | 错误处理,nil检查 |
| TypeScript | TSEquality运算符、TSOptional运算符 | ===/==,可选链接 |
| Python | Python身份运算符、Python综合运算符 | is/==,列表理解 |
| Ruby | RubyNilOperator,RubySymbolOperator | nil处理,符号/字符串转换 |
特征:
- 并行执行 -异步工作池,带有工作窃取功能,用于高效的突变测试
- 等效突变检测 -基于机器学习的评分,用于识别语义上等效的突变
- 覆盖整合 -解析LLVM-cov、Istanbul、coverage.py和Go覆盖率以跳过未测试的代码
- 增量模式 -仅测试更改文件中的突变
- CI/CD集成 -质量门和GitHub集成
用途:
# Generate mutants (dry run) with default operators (CRR, ROR, AOR)
omen mutation --dry-run
# Run mutation testing with all operators
omen mutation --mode thorough
# Fast mode (excludes operators that produce more equivalent mutants)
omen mutation --mode fast
# Run with coverage data to skip untested code
omen mutation --coverage coverage.json
# Incremental mode for CI - only test changed files
omen mutation --incremental
# Control parallelism
omen mutation --jobs 8
# Output surviving mutants for investigation
omen mutation --output-survivors survivors.json
# Filter to specific files
omen mutation --glob "src/analyzers/*.rs"基于ML的预测:
Omen包括一个ML模型,该模型从您的突变测试历史中学习,以预测哪些突变体将存活。这实现了两个优化:
- 跳过明显的杀戮 -不要浪费时间测试变种人,模型有信心会被抓住
- 更好的等效检测 -了解代码库中的哪些模式会产生等效的突变体
# Record results to history file for later training
omen mutation --record
# Train the model from accumulated history
omen mutation train
# Use trained model to skip high-confidence kills (saves time)
omen mutation --skip-predicted 0.95
# Use a custom model path
omen mutation --model path/to/model.json培训工作流程:
- 收集数据:运行
omen mutation --record在你的代码库上。每个突变体的结果(死亡/存活)附加到.omen/mutation-history.jsonl随着:
- 突变详细信息(操作员、位置、原始/突变代码) - 源上下文(突变前后5行) - 执行时间
- 训练模型:运行
omen mutation train训练预测器。模型学习:
- 特定于操作员的代码库终止率 - 将代码模式与生存率相关的特征权重
- 使用预测:未来运行会自动加载
.omen/mutation-model.json.使用--skip-predicted 0.9跳过预测致死概率>90%的突变体。
CI工作流示例:
# Weekly: full run with recording
omen mutation --record --mode thorough
# After accumulating history: train model
omen mutation train
# Daily CI: fast run using predictions
omen mutation --incremental --skip-predicted 0.95\[!注意\] 这.omen/默认情况下,目录为gitignore。如果你想在团队中共享训练好的模型,请删除.omen/mutation-model.json从你的.gitignore.
突变评分:
突变评分衡量测试套件的有效性:
mutation_score = killed_mutants / (total_mutants - equivalent_mutants)| 分数 | 质量 | 含义 |
|---|---|---|
| >80% | 优秀 | 强大的测试套件,可捕获大多数错误 |
| 60-80% | 良好 | 覆盖范围合理,需要解决一些差距 |
| 40-60% | 中等 | 显著的测试差距 |
| \ \[!提示\] |
从...开始--mode fast在CI上快速反馈,并运行--mode thorough定期进行全面分析。使用--coverage以避免在未经测试的代码上浪费时间。
MCP Server - LLM tool integration via Model Context Protocol
Omen包括一个模型上下文协议(MCP)服务器,该服务器将所有分析器作为Claude等LLM的工具公开。这使得AI助手能够通过标准化的工具调用直接分析代码库。
可用工具:
complexity-圈和认知复杂性satd-自认技术债务检测deadcode-未使用的函数和变量churn-Git文件更改频率clones-代码克隆检测defect-文件级缺陷概率(PMAT)changes-提交级别变更风险(JIT)diff-分行差异风险分析tdg-技术债务梯度得分graph-依赖图生成hotspot-高流失率+复杂度文件temporal-一起更改的文件ownership-代码所有权和总线因素cohesion-CK OO指标repomap-PageRank排名符号图smells-建筑气味检测flags-特征标志检测和陈旧性score-综合健康评分(0-100)semantic_search-自然语言代码搜索semantic_search_hyde-HyDE风格的搜索(使用假设代码片段进行查询)
每个工具都包括详细的描述和解释指南,帮助LLM理解指标的含义以及何时使用每个分析器。
工具输出默认为 TOON(面向令牌的对象表示法) format是一种为LLM工作流设计的紧凑序列化,与JSON相比,它将令牌使用量减少了30-60%,同时保持了较高的理解准确性。JSON和Markdown格式也可用。
为什么重要: LLM在能够访问结构化工具而不是解析非结构化输出时效果最佳。MCP是LLM工具集成的新兴标准,由Claude Desktop和其他AI助手支持。TOON输出使上下文窗口内的信息密度最大化。
\[!提示\] 在您的AI助手中将omen配置为MCP服务器,以启用自然语言查询,如“查找最复杂的函数”或“显示技术债务热点”
支持的语言
Go、Rust、Python、TypeScript、JavaScript、TSX/JSX、Java、C、C++、C#、Ruby、PHP、Bash(以及树形图支持的其他语言)
安装
自制(macOS/Linux)
brew install panbanda/brews/omen货物安装
cargo install omen-cli码头工人
# Pull the latest image
docker pull ghcr.io/panbanda/omen:latest
# Run analysis on current directory
docker run --rm -v "$(pwd):/repo" ghcr.io/panbanda/omen:latest analyze /repo
# Run specific analyzer
docker run --rm -v "$(pwd):/repo" ghcr.io/panbanda/omen:latest complexity /repo
# Get repository score
docker run --rm -v "$(pwd):/repo" ghcr.io/panbanda/omen:latest score /repo多拱形图像可用于 linux/amd64 和 linux/arm64.
下载二进制文件
从下载预构建的二进制文件 发布页面.
从源代码构建
git clone https://github.com/panbanda/omen.git
cd omen
cargo build --release
# Binary at target/release/omen快速开始
# Run all analyzers
omen all
# Check out the analyzers
omen --help远程存储库扫描
分析任何公共GitHub存储库,而无需手动克隆:
# GitHub shorthand
omen -p facebook/react complexity
omen -p kubernetes/kubernetes satd
# With specific ref (branch, tag, or commit SHA)
omen -p agentgateway/agentgateway --ref v0.1.0 all
omen -p owner/repo --ref feature-branch all
# Full URLs
omen -p github.com/golang/go all
omen -p https://github.com/vercel/next.js all
# Shallow clone for faster analysis (static analyzers only)
omen -p facebook/react --shallow allOmen克隆到临时目录,运行分析并自动清理。这 --shallow 旗帜用途 git clone --depth 1 用于更快的克隆,但禁用基于git历史的分析器(流失、所有权、热点、时间耦合、更改)。
配置
创建 omen.toml 或 .omen/omen.toml (支持 yaml, json 和 toml):
omen init看 omen.example.toml 对于所有选项。
\[!提示\] 使用克劳德代码?跑吧setup-config分析存储库并生成omen.toml为您的技术栈设置智能默认值,包括检测到的功能标志提供者和特定语言的排除模式。
GitHub行动
Omen提供了一个用于自动PR分析的GitHub Action。它对每个拉取请求进行不同的风险分析和健康评分。
基本用法
name: Omen Analysis
on: [pull_request]
permissions:
contents: read
jobs:
omen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: panbanda/omen@omen-v4.21.2
id: omen
- name: Print results
run: |
echo "Risk: ${{ steps.omen.outputs.risk-level }} (${{ steps.omen.outputs.risk-score }})"
echo "Health: ${{ steps.omen.outputs.health-grade }} (${{ steps.omen.outputs.health-score }})"\[!重要\] fetch-depth: 0 是必需的。Omen需要完整的git历史记录才能进行准确分析。带有PR评论和标签
- uses: panbanda/omen@omen-v4.21.2
id: omen
with:
comment: true
label: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}需要额外权限:
permissions:
contents: read
pull-requests: write
issues: write输入
| 输入 | 默认值 | 描述 |
|---|---|---|
version | latest | 要安装的Omen版本 |
path | . | 要分析的存储库路径 |
comment | false | 发布/更新粘性公关评论 |
label | false | 添加风险等级标签 |
label-template | risk: {{level}} | 标签名称模板({{level}} 被替换为 low, medium,或 high) |
check | false | 如果风险达到阈值,则失败 |
check-threshold | high | 失败的风险等级(low, medium, high) |
输出
所有输出均可链接到下游步骤:
| 输出 | 示例 | 描述 |
|---|---|---|
risk-score | 0.42 | 差异风险评分(0.0-1.0) |
risk-level | medium | 风险等级(low, medium, high) |
health-score | 76.9 | 健康评分(0-100) |
health-grade | C | 健康等级(A-F) |
diff-json | {...} | 满 omen diff JSON |
score-json | {...} | 满 omen score JSON |
质量门
如果风险过高,则工作流失败:
- uses: panbanda/omen@omen-v4.21.2
with:
check: true
check-threshold: high # fail on high risk PRs自定义工作流
使用输出构建自定义集成:
- uses: panbanda/omen@omen-v4.21.2
id: omen
- name: Block high-risk PRs
if: steps.omen.outputs.risk-level == 'high'
run: |
gh pr edit ${{ github.event.pull_request.number }} --add-label "needs-review"
exit 1
- name: Notify on health drop
if: fromJSON(steps.omen.outputs.health-score) 0.5)
- **熵** -变化有多分散(0=集中,1=无处不在)
- **行添加/删除比率** -净代码减少通常是一个好兆头
- **文件已修改** -更多文件=级联问题的可能性更大
**5.CI/CD集成**
报告包括GitHub Actions质量门和公关风险评估的工作流程示例。
### 生成自己的报告
对任何存储库进行全面分析:
Local repository
omen score omen hotspot omen tdg
Remote repository
omen -p facebook/react score omen -p kubernetes/kubernetes hotspot
PR risk before merging
omen diff --target main
Track score trends over time
omen score trend --period monthly --since 6m
## 贡献
1. 分叉存储库
1. 创建功能分支(`git checkout -b feature/amazing-feature`)
1. 提交您的更改(`git commit -am 'Add amazing feature'`)
1. 推到分支(`git push origin feature/amazing-feature`)
1. 创建拉取请求
## 致谢
Omen从中汲取了丰富的灵感 [paiml-mcp代理工具包](https://github.com/paiml/paiml-mcp-agent-toolkit/) -一个出色的CLI和一套全面的LLM工作流代码分析工具。如果你正在进行严肃的人工智能辅助开发,那么值得一试。Omen是一种简化的替代方案,适用于那些想要一个专注的分析器子集而不需要额外依赖的团队。如果你正在寻找一个以Rust为中心的MCP/代理生成器作为Python的替代品,那么它绝对值得一试。
## 许可证
Apache许可证2.0-请参阅 [许可证](LICENSE) 了解详情。