3、Detekt基础:Detekt检查类型、内置规则、命令行运行方式
说实话,刚接手团队代码质量时,我第一反应就是找工具能自动揪出那些“坏味道”。Detekt 就是我最常用的 Kotlin 静态分析工具之一。它不是那种一上来就给你报几百个错误的“暴君”,而是分成不同的检查类型,让你可以按需开启。这一章我会把 Detekt 的检查体系、内置规则怎么配置、以及最实用的命令行跑法都掰开跟你讲。
3.1 Detekt 的检查类型
Detekt 把检查项归为几大类,每类关注不同的代码问题。我用个表格帮你快速过一遍,后面我会拿实际案例说明。
| 检查类型 | 英文标识 | 典型目标 |
|---|---|---|
| 代码坏味道 | code-smell | 过长函数、过多参数、上帝类等 |
| 风格 | style | 命名约定、缩进、空行规范等 |
| 复杂度 | complexity | 圈复杂度、嵌套深度、方法长度 |
| 性能 | performance | 不必要的对象创建、低效集合操作 |
| 潜在 bug | potential-bug | 可能的空指针、未使用变量、错误类型转换 |
| 异常处理 | exceptions | 吞异常、过于宽泛的 catch、错误传播 |
| 多平台 | multiplatform | 针对 Kotlin Multiplatform 的特殊检查 |
你可能会问:这些类型是平级的还是有优先级?我个人习惯把 潜在 bug 和 复杂度 放在最高优先级。为什么?因为在项目里,这两类问题最容易导致线上故障或者代码难以维护。我见过一个同事写的 200 行函数,圈复杂度 37,里面藏着 3 个空指针隐患。想想都后怕。
3.2 内置规则集——开箱即用的“安检员”
Detekt 自带 60+ 条规则,按规则集(RuleSet)分组。你可以在配置文件中启用/禁用整个规则集或单条规则。下面是最常用的几个规则集:
| 规则集名称 | 包含规则数 | 典型规则举例 |
|---|---|---|
| comments | 3 | CommentOverPrivateFunction, UndocumentedPublicClass |
| complexity | 8 | ComplexCondition, LargeClass, LongMethod |
| exceptions | 4 | TooGenericExceptionCaught, SwallowedException |
| naming | 10 | FunctionNaming, VariableNaming, TopLevelPropertyNaming |
| performance | 6 | UnnecessaryTemporary, SpreadOperator |
| potential-bug | 7 | UnreachableCode, LateinitUse, UnsafeCast |
| style | 18 | MaxLineLength, WildcardImport, UnusedImports |
一个小技巧: 刚上手时别一股脑全开。我建议先启用 potential-bug 和 complexity 两个规则集,等团队适应了再逐步加 style 和 naming。否则几百个警告会直接把新人劝退。
3.3 命令行运行方式——让 CI 跑起来
Detekt 的核心运行方式就一条命令。但你得知道怎么指定配置、输出格式、过滤文件。我们直接看实战。
3.3.1 基本命令
detekt --input src/ --config detekt.yml --report xml:build/reports/detekt.xml
--input 指定源码路径,--config 指定配置文件(默认找 detekt.yml),--report 可以输出多种格式。我一般同时输出 HTML 和 XML,HTML 方便本地看,XML 给 CI 工具解析。
3.3.2 常用参数一览
| 参数 | 作用 | 示例 |
|---|---|---|
--input | 分析目录或文件 | --input app/src/main/kotlin |
--config | 配置文件路径 | --config config/detekt/detekt.yml |
--report | 输出报告(格式:路径) | --report html:reports/detekt.html |
--baseline | 基线文件,忽略已有问题 | --baseline baseline.xml |
--parallel | 启用并行分析(推荐) | 默认 false,加 --parallel |
--all-rules | 运行所有规则(慎用) | --all-rules |
--exclude | 排除路径模式 | --exclude "**/test/**" |
我曾经踩过的坑: 在 CI 里直接不加 --parallel,项目代码量一大(比如 2000+ Kotlin 文件),执行时间直接飙到 5 分钟。加了 --parallel 后,时间降到 1 分钟以内。所以 CI 脚本里一定要加上这个参数。
3.3.3 快速运行示例
假设你有一个标准 Android 项目,源码在 app/src/main/java。你想先用默认规则跑一遍看看有哪些问题:
detekt --input app/src/main/java \
--config config/detekt/detekt.yml \
--report html:build/reports/detekt.html \
--parallel
如果只想检查某个模块,用 --exclude 排除测试目录:
detekt --input app/src/main/java \
--exclude "**/test/**" \
--config config/detekt/detekt.yml
3.4 整体知识脉络
为了让你更直观地理解 Detekt 的检查体系与命令行之间的关系,我画了一张结构图。你看完就能明白:配置怎么驱动规则集,规则集又怎么落地到具体检查。
总结一下核心要点:
- Detekt 的检查分 7 种类型,最值得优先关注的是 potential-bug 和 complexity。
- 内置 60+ 条规则,按规则集分组,可通过
detekt.yml精细控制。 - 命令行运行推荐加
--parallel加速,结合--report输出多格式报告。 - 别企图一次开启所有规则——先在 CI 里用 “潜在 bug + 复杂度” 两个规则集跑起来,效果立竿见影。
我自己的团队在 CI 里就是这样一步步引入的。刚开始只检查 potential-bug,两周后加上 complexity,等大家习惯了再开 style。你要是也想平滑落地,这个节奏值得一试。好了,Detekt 基础这部分就聊到这,可以动手在你的项目里敲敲命令了。