ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ktlint 特性全解析:零配置 Kotlin 代码规范检查器与内置格式化器

Ktlint 特性全解析:零配置 Kotlin 代码规范检查器与内置格式化器 开发工具代码质量Lint格式化【免费下载链接】ktlintAn anti-bikeshedding Kotlin linter with built-in formatter项目地址https://gitcode.com/gh_mirrors/kt/ktlint点击查看免费下载本篇技术指南以 ktlint 官方文档首页为核心系统梳理这一 Kotlin Linter 与内置格式化器的核心能力零配置的代码风格检查、可插拔的规则集体系、基于.editorconfig的细粒度配置、一键自动修复的格式化能力、可定制的输出报告机制以及可执行 JAR 与原生二进制两种分发方式。读完本文你将掌握如何安装、运行、配置 ktlint如何禁用单个规则或整个规则集如何接入自定义规则集与自定义 reporter并能理解其规则引擎与源码模块的底层实现。项目定位对抗自行车棚争论的 Kotlin LinterKtlint 是An anti-bikeshedding Kotlin linter with built-in formatter——一个旨在终结代码风格争论bikeshedding的 Kotlin 代码检查工具并内置格式化能力。它在精神上借鉴了两个知名项目JavaScript 社区的 feross/standard零配置的 JS 规范与 Go 语言的 gofmt官方格式化工具。与这两者一致ktlint 的核心哲学是风格问题交给工具裁决开发者的精力留给业务逻辑。从项目首页声明的特性来看ktlint 的差异化价值集中在七点No configuration required无需配置开箱即用默认即对齐 Kotlin 官方编码规范Rule sets规则集内置standard规则集同时支持自定义规则集扩展.editorconfig配置文件通过.editorconfig做有限但充分的规则配置Disable rules规则禁用可按规则集或单条规则精确启用/禁用Built-in formatter内置格式化器绝大多数违规可被自动修复Customizable output可定制输出内置多种 reporter也支持自定义 reporterExecutable jar and native binaries分发形态既可执行 JAR也有 Linux/macOS/Windows 原生二进制。以下各节逐一深入剖析每一项特性并结合当前仓库源码给出底层实现证据。零配置默认对齐官方编码规范ktlint 的默认行为是无需任何配置即可运行在没有参数的情况下它会递归扫描当前目录下所有.kt与.kts文件隐藏文件夹会被跳过并使用standard规则集中的规则校验代码风格参见 CLI 用法文档。# 默认使用 standard 规则集校验当前目录递归下的所有 Kotlin 文件 ktlint默认规则的目标是捕获 Kotlin Coding Conventionsktlint_official默认融合 Kotlin Coding Conventions 与 Android Kotlin Style Guide 的优点并对规范未明确提及的主题提供了额外的格式化规则intellij_idea旧称official与 IntelliJ IDEA 默认格式化器保持兼容android_studio旧称android与 Android Studio 默认格式化器保持兼容。代码风格通过.editorconfig中的ktlint_code_style属性切换[*.{kt,kts}] ktlint_code_style ktlint_official # 或 intellij_idea、android_studio需要提醒的是ktlint_official风格在少数边界情况下可能与 IntelliJ IDEA / Android Studio 的内置格式化结果不一致这些 IDE 格式化器存在多年未修复的边缘 bug。官方建议使用该代码风格时关闭 IDE 的自动代码格式化仅依赖 ktlint 输出。这一取舍正是反 bikeshedding定位的体现——以 ktlint 单一权威输出替代多工具间的反复拉扯。规则集机制内置 standard 与自定义扩展standard 规则集standard规则集由 ktlint 项目官方维护其中包含文件命名、缩进、空格、换行、导入排序、注解格式、when 分支空行、类签名、函数签名等大量规则。每一条规则都有稳定的规则 ID格式为rule-set-id:rule-id例如standard:annotation、standard:final-newline、standard:max-line-length。完整规则说明与合规/不合规代码示例参见 standard 规则参考文档该文档按规则逐条给出允许与禁止的代码对照、默认配置值及启用/禁用方式。从源码看规则集与规则的命名约定被严格约束在 Rule.kt 中RuleId由rule-set-id:rule-id构成RuleSetId.STANDARD被保留给 ktlint 官方规则使用——自定义规则必须使用其他前缀作为规则集 ID这样当规则出问题时用户可以清晰地定位维护方。规则引擎方面KtLintRuleEngine 接收一组RuleV2Provider每个 provider 负责创建规则实例、editorConfigDefaults与editorConfigOverride分别对应.editorconfig的默认值与强制覆盖值并通过lint()/format()两个核心方法对外提供服务。编写自定义规则集ktlint 提供了一条标准化的自定义规则集扩展路径一个规则集就是一个包含一个或多个RuleV2的 JAR 包详见 自定义规则集文档。仓库中的 ktlint-ruleset-template 是一个可直接克隆的完整示例工程其目录结构即最佳实践样板。规则Rule一条规则承载 lint 与 format 的核心逻辑。规则通过重写RuleV2的若干生命周期钩子实现钩子定义见 Rule.ktbeforeFirstNode遍历开始前调用一次可初始化规则状态beforeVisitChildNodes深度优先遍历 AST 时在访问某节点的子节点之前调用通过emit(offset, errorMessage, canBeAutoCorrected)上报违规并获得是否允许自动修复的决策AutocorrectDecisionafterVisitChildNodes访问完某节点全部子节点后调用afterLastNode遍历结束后调用一次可用于状态清理。模板工程中的 NoVarRule.kt 是最精简的示例它只重写beforeVisitChildNodes当 AST 节点元素类型为VAR_KEYWORDvar关键字时报出一条Unexpected var, use val instead且不可自动修复的违规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) } } }规则集 Provider规则集需要提供创建规则实例的 Provider。CustomRuleSetProvider.kt 继承RuleSetV2Provider并返回规则 Provider 集合class CustomRuleSetProvider : RuleSetV2Provider(RuleSetId(CUSTOM_RULE_SET_ID)) { override fun getRuleProviders(): SetRuleV2Provider setOf(RuleV2Provider { NoVarRule() }) }ServiceLoader 注册ktlint 依赖 Java 的ServiceLoader机制发现 classpath 上的所有规则集因此必须把 Provider 注册到resources/META-INF/services/目录下的io.github.ktlint.core.cli.ruleset.core.api.RuleSetV2Provider文件中模板工程已包含该注册文件。基于同样的机制多个自定义规则集可以同时加载。提示ktlint-ruleset-standard模块提供了大量实现上述钩子的真实规则是学习规则编写的直接范本。由于规则是在 Kotlin PSI/AST 树上做节点遍历与匹配编写规则时经常需要查看任意代码对应的 AST 结构。官方推荐使用 JetBrains PsiViewer 插件IntelliJ IDEA 插件来辅助查看代码的 PSI 树结构构建与运行自定义规则集模板工程提供了完整的 Gradle 构建脚本包含向 Maven 发布规则集工件、以及通过ktlintCheck任务对工程自身运行规则dogfood 原则。构建与验证流程如下$ cd ktlint-ruleset-template/ $ ../gradlew build准备一个违反custom:no-var规则的样例文件并指定--ruleset加载自定义规则集$ echo var v 0 test.kt $ ktlint -R build/libs/ktlint-ruleset-template.jar --log-leveldebug --relative test.kt从 debug 日志可以看到ktlint 先加载了 JAR 规则集然后发现所有内置 reporterbaseline、checkstyle、json、html、plain、sarif并按规则依赖排序输出执行顺序——custom:no-var被插入到standard:indent之前执行最终报告text test.kt:1:1: Unexpected var, use val instead (cannot be auto-corrected).editorconfig规则配置的单一入口ktlint 只使用有限的一组.editorconfig属性做额外配置且每个属性都提供合理的默认值未显式配置时自动生效。属性必须在[*.{kt,kts}]段下声明才会被 ktlint 读取。它主要读取三类来源.editorconfig标准属性、IntelliJ IDEA 特定属性以及 ktlint 自定义属性详见 configuration-ktlint.md。配置生效范围与一个已知坑.editorconfig文件通常位于项目根目录若放在子目录则其设置只对该子目录及其子目录递归生效。ktlint 会自动探测并读取项目中所有.editorconfig文件。⚠️IntelliJ IDEA 的已知兼容性问题IntelliJ IDEA 存在一个.editorconfig自动格式化缺陷对应 JetBrains YouTrack 问题 IDEA-242506会在 glob 语句之间多加一个空格导致[*{kt, kts}]而非[*{kt,kts}]。而 ktlint 使用的.editorconfig库在遇到列表中的空格后会忽略后续段从而使规则无法作用于所有文件对应 ktlint issue #762。如果你的 IDE 会重排.editorconfig务必检查 glob 段是否被插入了空格。按目录覆盖属性.editorconfig支持针对项目内特定目录覆盖属性例如[*.{kt,kts}] ktlint_standard_import-ordering disabled [api/*.{kt,kts}] ktlint_standard_indent disabled上例中import-ordering规则对所有包包括api子包都禁用而indent规则只对api包及其子包禁用。各代码风格下的默认配置差异规则默认行为随代码风格而变。例如max_line_length的默认值在ktlint_official下为 140、intellij_idea下为off、android_studio下为 100insert_final_newline三种风格均为truektlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than在ktlint_official下为 1类参数默认全部换行在另外两种风格下为unset。各规则的默认值矩阵详见 standard.md 中每个规则下方的配置表格。规则特定配置项部分规则的行为由专用配置项控制仅在对应规则启用时生效。官方文档整理的关键映射如下节选配置项对应规则ij_kotlin_allow_trailing_commatrailing-comma-on-declaration-siteij_kotlin_allow_trailing_comma_on_call_sitetrailing-comma-on-call-siteij_kotlin_imports_layoutimport-orderingij_kotlin_packages_to_use_import_on_demandno-wildcard-importsindent_size/indent_styleindentationinsert_final_newlinefinal-newlinektlint_chain_method_rule_force_multiline_when_chain_operator_count_greater_or_equal_thanchain-method-continuationktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_thanclass-signaturektlint_ignore_back_ticked_identifiermax-line-lengthktlint_function_naming_ignore_when_annotated_withfunction-namingktlint_function_signature_body_expression_wrappingfunction-signaturektlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_thanfunction-signaturemax_line_lengthmax-line-length 及多个其他规则生成与覆盖 .editorconfigktlint 可以生成一份脚手架.editorconfig其中只包含当前已加载规则实际使用的配置项# 指定生成时使用的代码风格ktlint_official、intellij_idea 或 android_studio ktlint generateEditorConfig --code-style ktlint_official # 也支持结合自定义规则集生成 ktlint --ruleset/path/to/custom-ruleset.jar generateEditorConfig --code-style android_studio此外可用--editorconfig指定一份默认配置当被检查文件的路径上没有任何.editorconfig定义某属性时回退使用该文件的值。路径可以是文件或目录、相对或绝对ktlint --editorconfig/path/to/.editorconfig从 KtLintRuleEngine.kt 源码可以看到配置加载的完整链路EditorConfigLoaderEc4j基于 ec4j 库解析→EditorConfigLoader叠加 defaults 与 override→ 线程安全的.editorconfig缓存ThreadSafeEditorConfigCache。generateKotlinEditorConfigSection()则负责根据已加载规则与代码风格生成配置内容。禁用规则规则集级与规则级两级开关规则集级启停所有规则集与单条规则都可以通过.editorconfig独立启用/禁用。规则集属性的命名规则是ktlint_前缀 规则集 ID[*.{kt,kts}] ktlint_standard disabled # 禁用 standard 规则集中的全部规则 ktlint_experimental enabled # 启用所有规则集中标记为 experimental 的规则 ktlint_custom-rule-set enabled # 启用非 ktlint 提供的custom-rule-set 规则集实验性规则默认不运行被标记为experimental的规则默认不会运行除非显式启用。Ktlint 0.47 及之前版本将实验性规则放在独立的experimental规则集中自 0.48 起每个规则集都可以可选地包含实验性规则参见 experimental.md[*.{kt,kts}] ktlint_experimental enabled # 启用所有已启用规则集中的实验性规则从源码看规则通过实现RuleV2.Experimental标记接口声明自己为实验性见 Rule.kt另有OfficialCodeStyle标记仅ktlint_official代码风格下或显式启用时运行与OnlyWhenEnabledInEditorconfig标记仅显式启用时运行供 ktlint 内部及规则提供者使用。规则级启停与优先级单条规则的属性命名规则是ktlint_前缀 规则集 ID _ 规则 ID[*.{kt,kts}] ktlint_standard_final-newline disabled # 禁用 standard:final-newline ktlint_standard_some-experimental-rule enabled # 启用 standard 中的实验性规则 ktlint_custom-rule-set_custom-rule disabled # 禁用自定义规则关键优先级规则规则级属性在规则集级属性之后应用并优先生效——如果整个规则集被禁用但其中某条规则被显式启用则该规则仍会执行。此外代码中也可以使用Suppress(ktlint:standard:rule-id)注解对单条规则进行局部抑制详见 standard.md 中每条规则的 Suppress 说明。内置格式化器能自动修复的绝不手改ktlint 最大的实用价值在于内置格式化器绝大多数 lint 违规不需要手动修改运行--format简写-F即可自动修复只有少量无法以确定性方式修复的违规需要人工介入这些错误会打印到stderr。# 自动修复当前目录递归下所有 .kt/.kts 文件中的风格违规 ktlint --format # 或简写 ktlint -F从引擎源码看KtLintRuleEngine.ktlint()与format()共用同一套CodeFormatter核心区别在于lint()使用NoneAutocorrectHandler只报告违规不修改代码每个文件最多执行一轮格式化遍历format()使用LintErrorAutocorrectHandler并通过回调让 API 使用者逐条决定是否接受自动修复默认在自动修复后最多重跑 3 轮MAX_FORMAT_RUNS_PER_FILE 3在尽量修复更多错误与避免无限循环之间取得平衡。官方同时提醒由于修复一条规则可能引入新的违规ktlint 会自动重跑格式化若干次在集成时应注意日志输出避免出现规则 A 的修复被规则 B 在下一轮撤销的循环。可定制输出reporter 机制与报告输出内置 reportersktlint 开箱即提供多种 reporter未指定时默认使用plain# 按文件分组的违规报告 $ ktlint --reporterplain?group_by_file # 统计每条规则导致的违规数量适合存量项目盘点 $ ktlint --reporterplain-summary其他内置 reporter 包括json、sarif、checkstyle、html。也可以同时指定多个 reporter例如 plain 输出到控制台、checkstyle 写入文件ktlint --reporterplain --reportercheckstyle,outputktlint-report-in-checkstyle-format.xmlbaseline存量项目的渐进式治理如果不想一次性清空项目全部历史违规可以创建 baseline之后的运行将把违规与 baseline 对比已登记在 baseline 中的违规会被静默忽略删除 baseline 文件即可重置ktlint --baselinektlint-baseline.xml # 文件不存在时自动创建对应的实现位于 BaselineReporter.ktbaseline 的读取、比较、写入逻辑见 Baseline.kt。自定义 reporterreporter 接口非常薄实现即可接入详见 自定义 reporter 文档。核心工作只有三步实现 ReporterV2 接口——其生命周期方法为beforeAll/before(file)/onLintError(file, ktlintCliError)/after(file)/afterAll实现必须线程安全不同文件可能并行调用onLintError但同一文件的前后回调保证在同一线程实现ReporterProviderV2并在META-INF/services/io.github.ktlint.core.cli.reporter.core.api.ReporterProviderV2中注册打包为 JAR。加载第三方 reporter 的命令格式为ktlint --reportername,artifact/path/to/custom-ktlint-reporter.jar从仓库结构看ktlint-cli-reporter-core定义了 reporter 的 API 与KtlintCliError数据模型ktlint-cli-reporter-plain、-checkstyle、-json、-html、-sarif、-plain-summary、-baseline分别是各内置 reporter 的独立模块是编写自定义 reporter 时最直接的参考实现。分发形态可执行 JAR 与原生二进制ktlint 每个 release 同时提供多种运行形态详见 CLI 安装文档产物说明ktlint可执行 JAR包含全部依赖需要 JVMktlint_linux-x86-64Linux x86-64 原生可执行文件ktlint_darwin-arm64macOS Apple Silicon 原生可执行文件ktlint_windows-x86-64.exeWindows x86-64 原生可执行文件ktlint.batWindows 下启动可执行 JAR 的批处理脚本⚠️原生二进制的限制上述原生可执行文件使用 GraalVMnative-image做 ahead-of-time 编译无法在运行时通过命令行加载自定义规则集或 reporter JAR只能使用内置规则集与内置 reporter。需要第三方或自定义扩展时请使用可执行 JARktlint。安装方式多样macOS/Linux 可用 Homebrewbrew install ktlint、macOS 可用 MacPortsport install ktlint也可直接从 GitHub releases 页面手动下载对应平台产物并加入%PATH%Windows。下载后可对ktlint.asc进行 PGP 签名校验——注意 ktlint 2.x 已迁出 Pinterest 组织公钥可从 Ubuntu 密钥服务器获取。快速开始完整 CLI 使用速查安装brew install ktlint或使用集成方式Maven / Gradle 插件等参见 integrations.md。校验与格式化# 只检查不修改默认行为 ktlint # 检查并自动修复 ktlint --format # 或 ktlint -FGlobs 精确控制检查范围ktlint 的 glob 采用.gitignore模式语法从左到右处理可用!前缀取反隐藏文件夹自动跳过# 检查 src/ 下所有 .kt但排除以 Test.kt 结尾的文件 ktlint src/**/*.kt !src/**/*Test.kt # 排除 generated 目录及其子目录 ktlint src/**/*.kt !src/**/generated/**stdin / stdout 管道模式# 从 stdin 读入代码违规输出到 stderr ktlint --stdin # 结合 --format格式化结果写到 stdout违规输出到 stderr ktlint --stdin -F # 提供 stdin 内容的真实文件路径供规则使用--format 不会修改该文件 ktlint --stdin --stdin-path /path/to/file/Foo.kt日志stdout可用--log-levelnone抑制违规输出stderr可用2 /dev/null丢弃或通过 reporter 写入文件。Git hooks一键安装 git 钩子在 commit / push 前自动校验ktlint installGitPreCommitHook ktlint installGitPrePushHook其他常用选项--color/--color-namecolorName彩色输出并指定颜色名-h/--help帮助信息--limitlimit最多展示的错误数默认全部--relative按工作目录相对路径打印文件--patterns-from-stdin[delimiter]从 stdin 读取额外 glob 模式默认换行分隔空字符串时用 NUL 字节-V/--version版本信息-l/--log-level日志级别可取trace、debug、info、warn、error、none默认info。退出码语义与其他工具集成时退出码是必须对齐的契约退出码含义0命令执行成功若包含格式化选项则没有剩余违规或全部违规已被自动修复1输入已成功重新格式化但仍有至少一条违规待修复通常不可自动修复需要再次运行 ktlint2发生 IO 异常请检查日志3通过stdin提供的输入不是合法的 Kotlin (Script) 代码4通过stdin提供的输入引发异常请启用日志查看堆栈5命令行选项指向无效路径6提供的规则集 JAR 不受支持7reporter 配置无效123使用--force-lint-after-format时格式化输出出现解析异常仅用于回归测试源码模块地图快速定位所需代码从仓库结构可以清晰地看到 ktlint 的分层模块设计ktlint-rule-engine-core规则引擎核心 API包括RuleV2、RuleId/RuleSetId、RuleV2Provider、AutocorrectDecision与 editorconfig 属性注册表Rule.ktktlint-rule-engine引擎实现层负责.editorconfig加载/查找/生成、格式化器、suppression、线程安全缓存KtLintRuleEngine.ktktlint-ruleset-standard官方 standard 规则集的全部规则实现ktlint-ruleset-standard/src/main/kotlin/io/github/ktlint/core/ruleset/standard/rules/下每个文件对应一条规则ktlint-ruleset-template自定义规则集模板工程可直接克隆起步ktlint-cli命令行入口与子命令generateEditorConfig、installGitPreCommitHook、installGitPrePushHook等ktlint-cli-reporter-*core/plain/plain-summary/json/sarif/checkstyle/html/baselinereporter API 与各内置实现ktlint-api-consumer面向 API 使用者的示例工程KtLintRuleEngine的调用示例ktlint-com-pinterest-backward-compatibility对老版com.pinterest.ktlint包名的兼容层ktlint-bom依赖 BOM便于统一管理各模块版本。许可与法律声明本项目与 JetBrains 无隶属关系、亦未获得其背书。除特别注明外所有代码均以 MIT 许可证发布版权归 Ktlint、Pinterest, Inc. 与 Stanley Shyiko 所有详见 LICENSE。ktlint 2.x 已迁移至独立组织与 Pinterest 开源项目不再关联。总结ktlint 通过零配置默认值 .editorconfig细调 规则集/规则两级开关 内置格式化器 可插拔 reporter 多形态分发这套组合拳把 Kotlin 代码风格检查的成本降到最低新项目 clone 下来即可跑存量项目可以用 baseline 渐进治理团队可以借自定义规则集沉淀自身规范CI 侧则可挑选plain-summary、sarif、checkstyle等报告格式对接现有流水线。无论是作为本地开发工具、CI 门禁还是 IDE 插件后端理解上述七项特性及其背后的规则引擎实现都能帮助你更高效地把 ktlint 融入工程实践。赞分享开发工具代码质量Lint格式化【免费下载链接】ktlintAn anti-bikeshedding Kotlin linter with built-in formatter项目地址https://gitcode.com/gh_mirrors/kt/ktlint点击查看免费下载相关推荐Kotlin代码规范利器ktlint零配置自动格式化完整指南Kotlin代码规范利器ktlint零配置自动格式化完整指南 Kotlin代码规范利器ktlint是一款强大的 Kotlin代码格式化工具 能够帮助开发者自开发工具代码质量Lint格式化Bash Tab补全完全指南用bash-it的90补全脚本定制你的终端Bash Tab补全完全指南用bash it的90补全脚本定制你的终端 还在终端里一遍遍手敲冗长的命令和文件名吗 bash it 是一个广受欢迎的社区 B开发工具代码质量Lint格式化HuLa代码规范Biome代码检查与格式化配置HuLa代码规范Biome代码检查与格式化配置 引言 在大型跨平台即时通讯应用开发中代码质量的一致性至关重要。HuLa项目采用Biome作为代码检查和格式化即时通讯桌面应用前端上一篇推荐CoreOS Container Linux上的Kubernetes下一篇推荐一款创新的Android日期和时间选择库——BottomSheetPickers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表