☰
ktlint 快速上手:零配置的 Kotlin 代码风格检查与自动格式化指南
2026/10/7 2:00:36 网站建设 项目流程
  • 开发工具
  • 代码质量
  • Lint
  • 格式化

【免费下载链接】ktlint

An anti-bikeshedding Kotlin linter with built-in formatter

项目地址:https://gitcode.com/gh_mirrors/kt/ktlint
点击查看免费下载

ktlint 是一款遵循 "anti-bikeshedding"(反无休止风格争论)理念的 Kotlin 静态代码检查工具,内置格式化器,其设计灵感源自 JavaScript 生态的standard与 Go 生态的gofmt。本指南以当前仓库的 README.md 为主线,带你完成从安装、默认扫描到自动修复的完整实践闭环,并深入仓库源码说明其"零配置"背后的实现原理,帮助你快速掌握在 Kotlin 项目中使用 ktlint 的日常操作与扩展方式。

ktlint 的核心特性

ktlint 的目标是让团队无需在代码风格上反复争论,用一套开箱即用的约定即可完成风格统一。根据仓库 README.md 的归纳,其关键特性包括:

  • 无需配置即可使用(No configuration required):开箱即用,默认扫描规则覆盖绝大多数 Kotlin 风格约定;
  • 内置规则集(Built-in Rule sets):标准规则集由 100+ 条规则组成,详见下文"内置标准规则集"一节;
  • 内置格式化器(Built-in formatter):大部分风格违规可以被自动修复;
  • 支持.editorconfig:规则可通过.editorconfig进行细粒度调整与开关;
  • 多种内置报告器(reporters):plain、json、html、checkstyle等;
  • 可执行 JAR 与原生二进制:既可在 JVM 上运行,也可通过 GraalVM 原生镜像直接执行;
  • 可扩展自定义规则集与报告器:通过 JAR 加载第三方规则与输出格式。

快速开始

第一步:安装

在 macOS 或 Linux 上,最简单的方式是通过 Homebrew 安装:

brew install ktlint

除 Homebrew 外,ktlint 还支持多种安装渠道:

  • 原生二进制与可执行 JAR:每个 release 均提供 Linux x86-64、macOS Apple Silicon、Windows x86-64 三种原生可执行文件(GraalVM 原生镜像),以及需要 JVM 的ktlint可执行 JAR 和供 Windows 使用的ktlint.bat,详见 安装与下载校验;
  • 其他包管理器:如 MacPorts(port install ktlint)等;
  • 构建工具集成:通过 Maven / Gradle 插件接入构建生命周期,详见 集成方式。

注意:原生可执行文件由 GraalVMnative-image预编译,运行时无法通过命令行加载第三方规则集/报告器 JAR,只能使用内置规则与报告器;需要自定义扩展时请使用可执行 JAR(ktlint)。

第二步:检查并格式化代码

ktlint 会递归扫描当前目录及其子目录下所有.kt与.kts文件,并对能够自动修复的违规进行修正:

# 自动修复代码风格违规(两种写法等价) ktlint --format # 或 ktlint -F

在仓库的 KtlintCommandLine.kt 中可以确认--format与-F为同一选项的两个名称。更完整的命令行用法(globs、报告器、baseline、git hooks 等)参见 CLI 使用文档。

零配置背后的实现:默认扫描模式与内置标准规则集

为什么直接运行ktlint就能检查整个项目?源码给出了答案。

默认匹配模式

在 FileUtils.kt 中定义了默认的文件扩展名与默认 glob 模式:

private val DEFAULT_KOTLIN_FILE_EXTENSIONS = setOf("kt", "kts") internal val DEFAULT_PATTERNS = DEFAULT_KOTLIN_FILE_EXTENSIONS.map { "**/*.$it" }

即默认情况下匹配所有递归路径下的**/*.kt与**/*.kts。当命令行未提供任何文件参数时,KtlintCommandLine.kt 会启用DEFAULT_PATTERNS,随后通过Files.walkFileTree遍历目录树;隐藏目录(如.git)会被跳过,见 FileUtils.kt。

内置标准规则集

标准规则集在 StandardRuleSetProvider.kt 中注册了 100+ 条规则,覆盖命名、间距、换行、KDoc、导入排序、缩进等方方面面。几个有代表性的规则:

规则 ID(standard:前缀)职责源码位置
filename文件名必须与顶层类一致FilenameRule.kt
final-newline文件末尾必须有换行FinalNewlineRule.kt
indent缩进风格(配合indent_size/indent_style)IndentationRule.kt
import-ordering导入语句排序ImportOrderingRule.kt
max-line-length最大行长度MaxLineLengthRule.kt
no-unused-imports/no-wildcard-imports未使用与通配符导入NoUnusedImportsRule.kt / NoWildcardImportsRule.kt
no-semi/no-trailing-spaces禁止分号与行尾空格NoSemicolonsRule.kt / NoTrailingSpacesRule.kt
spacing-*(如op-spacing、comma-spacing、paren-spacing)各类符号周围空格对应 SpacingAroundOperatorsRule.kt 等
trailing-comma-on-declaration-site/-call-site尾随逗号策略TrailingCommaOnDeclarationSiteRule.kt 等

部分规则之间存在执行顺序依赖(例如max-line-length需要依赖某些换行规则先执行),规则的依赖关系图见 规则依赖说明(示意图rule-dependencies.png位于 documentation/release-latest/docs/assets/images/rule-dependencies.png)。

另外,标准规则集中标记为experimental(实验性)的规则默认不执行,必须在.editorconfig中设置ktlint_experimental = enabled才会启用。

通过 .editorconfig 配置规则

ktlint 使用有限的.editorconfig属性进行额外配置。每个属性在未显式定义时都有合理的默认值;属性需要在[*.{kt,kts}]分段下设置才能生效。详细参考 配置文档。

注意:IntelliJ IDEA 存在一个与.editorconfig相关的自动格式化问题,会在 glob 语句中额外加入空格,把[*{kt,kts}]变成[*{kt, kts}],导致 ktlint 忽略该分段。应始终写作[*.{kt,kts}]且中间无空格。

代码风格

默认采用ktlint_official风格,也可切换为intellij_idea或android_studio:

[*.{kt,kts}] ktlint_code_style = ktlint_official

启用 / 禁用规则

规则集与单条规则分别通过ktlint_前缀的属性进行开关:

[*.{kt,kts}] ktlint_standard = disabled # 禁用 standard 规则集全部规则 ktlint_experimental = enabled # 启用所有规则集中的实验性规则 ktlint_custom-rule-set = enabled # 启用自定义规则集(非 ktlint 提供) ktlint_standard_final-newline = disabled # 禁用单条规则 final-newline ktlint_standard_some-experimental-rule = enabled # 启用标准规则集中的某条实验性规则

规则属性的优先级高于规则集属性:例如即使整个规则集被禁用,只要某条规则被单独启用,该规则仍会执行。

规则专属配置项

一些规则支持专属配置属性,仅在该规则启用时生效:

配置项对应规则
ij_kotlin_allow_trailing_comma/ij_kotlin_allow_trailing_comma_on_call_site尾随逗号相关规则
ij_kotlin_imports_layout/ij_kotlin_packages_to_use_import_on_demandimport-ordering/no-wildcard-imports
indent_size/indent_styleindent
insert_final_newlinefinal-newline
ktlint_chain_method_rule_force_multiline_when_chain_operator_count_greater_or_equal_thanchain-method-continuation
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_thanclass-signature
ktlint_ignore_back_ticked_identifiermax-line-length
ktlint_function_naming_ignore_when_annotated_withfunction-naming
ktlint_function_signature_body_expression_wrapping/ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_thanfunction-signature
max_line_lengthmax-line-length及若干其他规则

按目录覆盖配置

.editorconfig天然支持按目录分段覆盖属性,例如:

[*.{kt,kts}] ktlint_standard_import-ordering = disabled [api/*.{kt,kts}] ktlint_standard_indent = disabled

上述配置中import-ordering在所有包(含api子包)被禁用,而indent仅在api包及其子包被禁用。

常用命令行操作

下面命令均可在 CLI 使用文档 找到完整说明,其参数解析与执行逻辑位于 KtlintCommandLine.kt。

使用 glob 精确指定扫描范围

glob 采用.gitignore风格语法,从左到右处理,!前缀表示取反(排除);隐藏文件夹会被跳过:

# 检查 src/ 下所有 .kt 文件,但排除以 Test.kt 结尾的文件 ktlint 'src/**/*.kt' '!src/**/*Test.kt' # 检查 src/ 下所有 .kt 文件,但排除 generated 目录及其子目录 ktlint 'src/**/*.kt' '!src/**/generated/**'

若只给出排除模式而没有包含模式,ktlint 会自动使用默认包含模式(**/*.kt、**/*.kts)作为兜底,见 FileUtils.kt。

加载自定义规则集

ktlint --ruleset=/path/to/custom-ruleset.jar # 或 ktlint -R /path/to/custom-ruleset.jar

--ruleset选项在源码中定义为可逗号分隔、可多次指定的参数(KtlintCommandLine.kt),即一次可以加载多个自定义规则集 JAR。若规则集中含实验性规则,同样需要ktlint_experimental = enabled才会运行。

违规报告与多报告器

未指定报告器时默认使用plain报告器。可按文件分组、按规则统计,或输出多种格式:

# 按文件分组显示违规 ktlint --reporter=plain?group_by_file # 按规则统计违规数量(适合存量项目分析规则分布) ktlint --reporter=plain-summary # 同时输出到控制台与文件(多个 reporter 可叠加) ktlint --reporter=plain --reporter=checkstyle,output=ktlint-report-in-checkstyle-format.xml

内置报告器包括plain、plain-summary、json、sarif、checkstyle、html,其实现分布在 ktlint-cli-reporter-json、ktlint-cli-reporter-checkstyle、ktlint-cli-reporter-html 等独立模块中。第三方报告器可通过--reporter=<id>,artifact=/path/to/reporter.jar,output=...方式加载。

使用 baseline 渐进式清理存量问题

存量项目违规较多时,可先建立 baseline,后续运行会静默忽略 baseline 中已登记的违规:

ktlint --baseline=ktlint-baseline.xml # 文件不存在时会自动创建

读取 stdin 与输出到 stdout

# 从 stdin 读取代码并检查,违规输出到 stderr ktlint --stdin # 从 stdin 读取并格式化,格式化结果写到 stdout,违规输出到 stderr ktlint --stdin -F

配合--stdin-path /path/to/file/Foo.kt可为 stdin 内容提供一个虚拟文件路径,供依赖文件名的规则(如filename)使用;此时--format不会改写该真实文件。从源码看,当从 stdin 读取时 ktlint 会自动禁用filename规则(KtlintCommandLine.kt),因为该规则无法与 stdin 配合使用。

生成 .editorconfig 脚手架

# 按指定代码风格生成 .editorconfig ktlint generateEditorConfig --code-style ktlint_official # 生成时同时考虑自定义规则集的规则 ktlint --ruleset=/path/to/custom-ruleset.jar generateEditorConfig --code-style android_studio

生成的配置文件只包含当前已加载规则实际使用到的配置项。该功能由 GenerateEditorConfigSubCommand.kt 实现。

安装 Git 钩子

在提交或推送前自动执行检查:

ktlint installGitPreCommitHook ktlint installGitPrePushHook

退出码约定

与 CI 或工具链集成时需关注退出码(定义于 KtlintCommandLine.kt):

退出码含义
0执行成功;若含格式化选项,则无违规或全部违规已被自动修复
1已成功格式化但仍有至少一条违规需手动修复(通常不可自动修复)
2发生 IO 异常,检查日志
3stdin 输入不是合法的 Kotlin(脚本)代码
4stdin 输入执行期间发生异常,开启日志查看堆栈
5命令行选项指向无效路径
6提供的规则集 JAR 不受支持
7报告器配置无效
123使用--force-lint-after-format时格式化结果无法通过再解析(仅用于回归测试)

其他常用选项

  • --color/--color-name=<colorName>:彩色输出并自定义颜色;
  • -h/--help:打印帮助信息;
  • --limit=<n>:限制最多显示的错误数(默认显示全部);
  • --relative:以相对于工作目录的路径输出(dir/file.kt而非绝对路径);
  • --patterns-from-stdin[=<分隔符>]:从 stdin 读取额外的匹配模式(默认以换行分隔,空字符串表示使用 NUL 字节);与--stdin互斥;
  • -V/--version:打印版本信息;
  • --log-level/-l:设置最小日志级别(trace、debug、info、warn、error、none),默认info;
  • --ignore-autocorrect-failures:忽略所有无法自动修复的违规(源码过滤逻辑见 KtlintCommandLine.kt)。

扩展 ktlint:自定义规则集

ktlint 依赖 JavaServiceLoader机制发现 classpath 上的规则集。仓库中的 ktlint-ruleset-template 是一个可直接克隆的最小示例工程(Gradle 构建),完整的开发说明见 自定义规则集文档。

编写一条规则

规则继承RuleV2,并在 AST 遍历钩子中实现检查逻辑。以模板中的 NoVarRule.kt 为例:

public class NoVarRule : RuleV2( ruleId = RuleId("$CUSTOM_RULE_SET_ID:no-var"), about = RuleV2.About( maintainer = "Your name", repositoryUrl = "https://github.com/your/project/", issueTrackerUrl = "https://github.com/your/project/issues", ), ) { override fun beforeVisitChildNodes( node: ASTNode, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> AutocorrectDecision, ) { if (node.elementType == VAR_KEYWORD) { emit(node.startOffset, "Unexpected var, use val instead", false) } } }

一条规则需要实现以下钩子中的一个或多个:

  • Rule.beforeFirstNode;
  • RuleAutocorrectApproveHandler.beforeVisitChildNodes;
  • RuleAutocorrectApproveHandler.afterVisitChildNodes;
  • Rule.afterLastNode。

在 AST 遍历过程中,这些钩子按名称所示顺序被调用;可以用 IntelliJ IDEA 的 PsiViewer 插件查看任意代码的 AST 结构辅助开发(截图 psi-viewer.png)。

注册规则集

规则集通过 CustomRuleSetProvider.kt 暴露规则实例,并需要在resources/META-INF/services/io.github.ktlint.core.cli.ruleset.core.api.RuleSetV2Provider文件中注册提供者全限定名,ktlint 才能通过ServiceLoader发现它。

构建并运行

cd ktlint-ruleset-template/ ../gradlew build

然后使用-R加载构建出的 JAR 并检查示例代码:

echo 'var v = 0' > test.kt ktlint -R build/libs/ktlint-ruleset-template.jar --log-level=debug --relative test.kt

从--log-level=debug输出可以看到,自定义规则custom:no-var会被合并进规则执行顺序中(与标准规则集规则一起按依赖关系排序),并输出违规信息。如果你只想集成到既有项目而不必逐条手写规则,也可以直接使用社区 Gradle/Maven 插件(如 jlleitschuh/ktlint-gradle、jeremymailen/kotlinter-gradle、diffplug/spotless 等,参见 集成文档)。

结语

从零配置扫描、-F一键格式化,到.editorconfig细粒度调优,再到自定义规则集扩展,ktlint 为 Kotlin 项目的代码风格治理提供了一条完整路径。日常使用中记住三个核心动作即可:直接运行ktlint做检查、用ktlint -F自动修复、用ktlint --baseline=...处理存量项目。更细致的用法可随时查阅仓库内的 CLI 文档 与 规则配置文档。

  • 开发工具
  • 代码质量
  • Lint
  • 格式化

【免费下载链接】ktlint

An anti-bikeshedding Kotlin linter with built-in formatter

项目地址:https://gitcode.com/gh_mirrors/kt/ktlint
点击查看免费下载

相关推荐

上一篇:如何3步搭建你的私有知识库:AnythingLLM终极指南
下一篇:FridaBypassKit 实战:在 agentic-awesome-skills 的 apk-reverse 工作流中一键绕过 Android 四大检测

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询