ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Ktlint 2.x 迁移指南:从 `com.pinterest.ktlint` 到 `io.github.ktlint.core` 的完整升级路径

Ktlint 2.x 迁移指南:从 `com.pinterest.ktlint` 到 `io.github.ktlint.core` 的完整升级路径 开发工具代码质量Lint格式化【免费下载链接】ktlintAn anti-bikeshedding Kotlin linter with built-in formatter项目地址https://gitcode.com/gh_mirrors/kt/ktlint点击查看免费下载Ktlint 从 Pinterest 组织迁移至独立的 Ktlint GitHub 组织后2.x 版本在 Maven 坐标、包名、规则 API 与自动纠错机制上引入了多项破坏性变更。本文以官方迁移文档documentation/snapshot/docs/api/migrate-to-ktlint-2.x.md为主线结合仓库源码与示例完整梳理从 1.x 自定义规则集升级到 2.x 的每一步坐标替换、包名迁移、RuleV2签名改造、RuleSetV2Provider重写以及com.pinterest.ktlint后向兼容模块的正确用法。读完本文你将能够系统性地迁移自己的 Ktlint 集成或自定义规则集并避免把后向兼容当作永久解决方案的常见陷阱。迁移背景与兼容性约定Ktlint 已从 Pinterest GitHub 组织迁移至其自有组织Ktlint GitHub organization这一归属变化带来了文档中记录的若干破坏性变更。官方强烈建议 Ktlint Integrators集成方包括 CLI、IntelliJ Plugin、Gradle Plugin 等 API 消费者尽快升级到 Ktlint2.x同时在相关场景下尽量保留对 Ktlint1.x规则集的后向兼容。在编写本指南时Ktlint CLI2.x 及更高版本、Ktlint IntelliJ Plugin0.31.0 及更高版本均兼容Ktlint1.3.x 及更高版本提供的规则集实现了com.pinterest.ktlint.rule.engine.core.api.RuleAutocorrectApproveHandler接口的自定义规则。从源码结构看这一兼容能力正是通过独立模块ktlint-com-pinterest-backward-compatibility提供的该模块保留了1.8.0版本的Rule、RuleProvider、RuleSetProviderV3、RuleAutocorrectApproveHandler等类见 ktlint-com-pinterest-backward-compatibility/src/main/kotlin/com/pinterest/ktlint供 CLI 动态加载旧规则集时使用。迁移准备先升到 1.8.0 并清零弃用告警正式动手迁移到 2.x 之前官方建议先升级到 Ktlint1.8.0并解决所有 deprecation 告警。原因非常具体大量通过ASTNodeExtensions文件提供的扩展函数会在 2.x 中被移除。如果先在1.8.0中把已弃用的扩展函数迁移到新版本对应物那么后续的包名替换工作会顺利得多——因为你依赖的 API 形态已经与新版本对齐剩下的只是命名空间层面的机械替换。换句话说这是一条两步走的平滑路径在 1.x 时代消除 API 用法差异处理弃用告警再执行命名空间迁移包名、坐标替换此时编译错误只剩文档下文列出的少数类型替换点。修改 Maven 坐标Ktlint 2.x 发布时使用了新的 Maven 坐标。groupId 从com.pinterest.ktlint改为io.github.ktlint.core而各模块的 artifactId 保持不变。官方给出的两个示例com.pinterest.ktlint:ktlint-rule-engine→io.github.ktlint.core:ktlint-rule-enginecom.pinterest.ktlint:ktlint-cli-ruleset-core→io.github.ktlint.core:ktlint-cli-ruleset-core注意官方文档第二条例子存在笔误正确的新坐标应为io.github.ktlint.core:ktlint-cli-ruleset-coreartifactIdktlint-cli-ruleset-core不变。在 Gradle 依赖块中对应改动形如// Ktlint 1.x implementation(com.pinterest.ktlint:ktlint-rule-engine:1.8.0) // Ktlint 2.x implementation(io.github.ktlint.core:ktlint-rule-engine:2.x.y)新坐标下规则引擎的核心 API 位于 ktlint-rule-engine-core/src/main/kotlin/io/github/ktlint/core/rule/engine/core/apiCLI 规则集 API 位于 ktlint-cli-ruleset-core/src/main/kotlin/io/github/ktlint/core/cli/ruleset/core/api仓库内模块名与包名完全一一对应。修改包名全局替换com.pinterest.ktlint前缀所有以com.pinterest.ktlint开头的包名都已改为以io.github.ktlint.core开头。官方指出一次简单的搜索替换就能解决大多数问题。例如com.pinterest.ktlint.rule.engine.core.api.RuleId→io.github.ktlint.core.rule.engine.core.api.RuleIdcom.pinterest.ktlint.rule.engine.core.api.AutocorrectDecision→io.github.ktlint.core.rule.engine.core.api.AutocorrectDecisioncom.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3→io.github.ktlint.core.cli.ruleset.core.api.RuleSetV2Provider不过替换后仍会出现若干编译错误因为部分类在io.github.ktlint.core命名空间中并不存在它们被新类型取代或语义发生了变化。下文逐一说明如何解决。解决编译错误一Rule 基类与自动纠错签名Rule被RuleV2取代com.pinterest.ktlint.rule.engine.core.api.Rule已被替换为io.github.ktlint.core.rule.engine.core.api.RuleV2。查看源码Rule.kt可见RuleV2是一个open class构造参数包括ruleId: RuleId规则标识遵循rule-set-id:rule-id约定standard前缀保留给 Ktlint 官方规则自定义规则应使用其他前缀about: About规则的维护者、仓库地址、问题跟踪地址等背景信息usesEditorConfigProperties: SetEditorConfigProperty*规则实际使用的.editorconfig属性集合默认为空。RuleV2还提供了完整的生命周期钩子beforeFirstNode、beforeVisitChildNodes、afterVisitChildNodes、afterLastNode以及用于控制 AST 遍历的startTraversalOfAST()/shouldContinueTraversalOfAST()/stopTraversalOfAST()方法。移除RuleAutocorrectApproveHandler接口如果自定义规则实现了com.pinterest.ktlint.rule.engine.core.api.RuleAutocorrectApproveHandler接口迁移时直接从类签名中移除该接口——该接口提供的函数已由RuleV2直接提供无需再单独实现。如果自定义规则没有实现该接口则需要更新beforeVisitChildNodes和afterVisitChildNodes的方法签名。新旧签名对比如下维度旧签名Ktlint 2.x 不再支持新签名方法修饰public open funpublic fun参数node: ASTNode, autoCorrect: Boolean, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) - Unitnode: ASTNode, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) - AutocorrectDecisionautoCorrect参数显式传入不再传入旧签名代码public open fun beforeVisitChildNodes( node: ASTNode, autoCorrect: Boolean, emit: ( offset: Int, errorMessage: String, canBeAutoCorrected: Boolean ) - Unit, )新签名代码public fun beforeVisitChildNodes( node: ASTNode, emit: ( offset: Int, errorMessage: String, canBeAutoCorrected: Boolean ) - AutocorrectDecision, )emit返回AutocorrectDecision把自动纠错决策权交给集成方迁移最核心的变化在于autoCorrect参数不再传入规则方法而是由emit函数返回AutocorrectDecision决策。每次发现违规时规则调用emit由 Ktlint 集成方提供的 lambda 决定该条违规是否允许自动纠错AutocorrectDecision.ALLOW_AUTOCORRECT允许自动纠错AutocorrectDecision.NO_AUTOCORRECT不自动纠错。集成方返回的AutocorrectDecision会传回给规则规则只有在被允许时才执行自动纠错。这个枚举与辅助扩展函数在 AutocorrectDecision.kt 中定义public enum class AutocorrectDecision { ALLOW_AUTOCORRECT, NO_AUTOCORRECT, } public inline fun T AutocorrectDecision.ifAutocorrectAllowed(function: () - T): T? takeIf { this ALLOW_AUTOCORRECT } ?.let { function() }当检测到可自动纠错的LintError时按如下方式处理emit(node.startOffset, some detail message, true) .ifAutocorrectAllowed { // Autocorrect the LintError }当LintError不可自动纠错时只需发出违规即可emit(node.startOffset, some detail message, false)仓库内的真实示例与此完全一致例如 ktlint-api-consumer 的 NoVarRule 中当节点类型为VAR_KEYWORD时调用emit(node.startOffset, Unexpected var, use val instead, false)并在注释中说明了可自动纠错场景下的.ifAutocorrectAllowed { ... }用法ktlint-ruleset-template 的 NoVarRule 则是可直接用作新规则模板的完整示例包含About元数据填写。解决编译错误二RuleSetProviderV3 换成 RuleSetV2Providercom.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3已被替换为io.github.ktlint.core.cli.ruleset.core.api.RuleSetV2Provider。其getRuleProviders函数现在应返回一组io.github.ktlint.core.rule.engine.core.api.RuleV2Provider。从源码看RuleSetV2Provider 通过 JavaServiceLoader机制发现 classpath 上的所有RuleSetV2Provider因此每个 provider 必须注册在META-INF/services/io.github.ktlint.core.cli.ruleset.core.api.RuleSetV2Provider文件中。RuleV2ProviderRuleV2Provider.kt接收一个每次调用都返回新实例的工厂 lambda以保证规则可以持有状态且多文件处理是线程安全的。官方给出的新式 provider 示例import io.github.ktlint.core.cli.ruleset.core.api.RuleSetV2Provider import io.github.ktlint.core.rule.engine.core.api.RuleV2Provider import io.github.ktlint.core.rule.engine.core.api.RuleSetId internal val CUSTOM_RULE_SET_ID custom-rule-set-id class CustomRuleSetProvider : RuleSetV2Provider(RuleSetId(CUSTOM_RULE_SET_ID)) { override fun getRuleProviders(): SetRuleV2Provider setOf( RuleV2Provider { NoVarRule() }, RuleV2Provider { EmptyCollectionInitializationRule() }, ) }仓库中 ktlint-api-consumer 的 CustomRuleSetProvider 采用同一写法并额外说明了若规则集在编译期引入也可直接把RuleV2Provider { IndentationRule() }等加入集合。com.pinterest.ktlint后向兼容动态加载旧规则集的过渡方案以上方案并不完全适用于所有场景Ktlint API 集成方如果还需要支持动态加载继承自com.pinterest.ktlint命名空间类的规则集则无法完全采用前文的新式写法。此时应使用专门的后向兼容模块com.pinterest.ktlint:ktlint-com-pinterest-backward-compatibility它包含加载继承自RuleSetProviderV3的规则集所需的1.8.0版本类。工作流程是通过ServiceLoader发现旧的RuleSetProviderV3注册文件路径为META-INF/services/com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3将其中返回的RuleProvider通过com.pinterest.ktlint.rule.engine.core.api.RuleProvider.toRuleV2Provider转换为 Ktlint 2.x 格式。源码中该方法的具体实现RuleProvider.kt为public fun toRuleV2Provider(): RuleV2Provider RuleV2Provider { provider().toRuleV2() }即把旧的 1.xRule工厂包装成新的RuleV2工厂。同时该模块中的RuleProvider、RuleSetProviderV3类均标注了Deprecated明确仅用于Ktlint 1.x 自定义规则集 JAR 的后向兼容。⚠️官方特别警告不要为了逃避迁移自己的自定义规则集而使用后向兼容模块。该模块将在未来的 Ktlint 版本中不经另行通知直接移除。一旦被移除未迁移的规则集将无法再在较新版本的 Ktlint CLI、Ktlint IntelliJ Plugin、Ktlint Gradle Plugin 等工具中工作。迁移检查清单综合官方文档与仓库源码可将整个迁移过程收敛为以下可执行的检查清单升级到 Ktlint1.8.0解决全部弃用告警特别是ASTNodeExtensions中的扩展函数将依赖坐标的 groupId 从com.pinterest.ktlint改为io.github.ktlint.coreartifactId 不变全局替换包名前缀com.pinterest.ktlint→io.github.ktlint.core将规则基类从Rule改为RuleV2移除RuleAutocorrectApproveHandler接口重写beforeVisitChildNodes/afterVisitChildNodes去掉autoCorrect参数emit返回AutocorrectDecision并用.ifAutocorrectAllowed { ... }包裹自动纠错逻辑将RuleSetProviderV3替换为RuleSetV2ProvidergetRuleProviders返回SetRuleV2Provider更新META-INF/services注册文件为io.github.ktlint.core.cli.ruleset.core.api.RuleSetV2Provider若必须动态加载旧规则集使用ktlint-com-pinterest-backward-compatibility模块并通过RuleProvider.toRuleV2Provider()转换同时制定后续迁移计划以摆脱该模块。按照上述步骤操作后你的自定义规则集即可在 Ktlint2.x的 CLI、IntelliJ Plugin、Gradle Plugin 等集成环境中正常运行同时通过后向兼容模块Ktlint 2.x 仍能继续加载基于1.3.x 及更高版本构建的旧规则集为渐进式迁移留出充足时间。赞分享开发工具代码质量Lint格式化【免费下载链接】ktlintAn anti-bikeshedding Kotlin linter with built-in formatter项目地址https://gitcode.com/gh_mirrors/kt/ktlint点击查看免费下载相关推荐Ktlint 2.x 迁移指南从 com.pinterest.ktlint 到 io.github.ktlint.core 的规则集与 API 改造全解Ktlint 2.x 迁移指南从 com.pinterest.ktlint 到 io.github.ktlint.core 的规则集与 API 改造全解 本文开发工具代码质量Lint格式化PermissionsDispatcher 迁移指南从 2.x 到 4.x 与 Maven Central 的完整升级路径PermissionsDispatcher 迁移指南从 2.x 到 4.x 与 Maven Central 的完整升级路径 本文是面向 Permissions移动开发原生移动VoltAgent 迁移指南从 0.1.x 到 1.x 再到 2.x 的完整升级路径与源码级解析VoltAgent 迁移指南从 0.1.x 到 1.x 再到 2.x 的完整升级路径与源码级解析 本文基于 VoltAgent 仓库中的官方迁移文档 migr人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音上一篇Work Sans字体安装三大系统3步搞定附验证方法下一篇零基础上手 T3 实时运动图形用节点拼出你的第一个 3D 动画创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进