如何使用 Kotlin Multiplatform 编写命令行工具

2025-06-07

如何使用 Kotlin Multiplatform 编写命令行工具

能够编写自己的命令行工具是一项很棒的技能:可以自动化所有的事情!

不幸的是,编写 CLI 工具仍然主要使用 Bash。我强烈认为(虽然不太确定)只有两种好的 Bash 脚本:

  • 长度不超过五行
  • 由其他人编写和维护的

幸运的是,淘汰 Bash 非常简单:你只需要使用你最喜欢的编程语言即可!

我尝试过 Kotlin Multiplatform,不仅用它构建了一个很酷的 CLI 工具,而且还将它打包为一个模板项目,您可以利用它更快地开始使用!

GitHub 徽标 jmfayard / kotlin-cli-starter

人生苦短,不适合 Bash 编程

在 Kotlin Multiplatform 中构建命令行工具的启动项目

包含真实世界 CLI 工具的重新实现:git-standup

jmfayard_kotlin-cli-starter__生活对于 Bash 编程、Telegram 和 GitHub 桌面来说太短了

安装

您可以使用下面列出的选项之一进行安装

来源 命令
节点 npm install -g kotlin-cli-starter
安装程序 curl -L https://raw.githubusercontent.com/jmfayard/kotlin-cli-starter/main/installer.sh | sudo sh
测试 ./gradlew allTests
Kotlin 所有平台 跑步./gradlew allRun
Kotlin JVM 跑步./gradlew run
Kotlin 原生 ./gradlew install然后运行$ git standup
Kotlin Node.JS 跑步./gradlew jsNodeRun

为什么?

能够编写自己的命令行工具是一项很棒的技能。让所有事情自动化!

您可以使用 Kotlin 编写 CLI 工具,并享受使用的好处

  • 一种现代编程语言
  • 现代 IDE 支持
  • 单元测试和持续集成等现代实践
  • 利用 Kotlin 多平台库
  • 在 JVM 上运行代码并受益于丰富的 Java 库
  • 或者构建一个本机可执行文件,它启动非常快并且……

git-standup,Kotlin 多平台版本

git-standup是一款智能小工具,适合像我这样经常在站会前感到恐慌的人。我昨天到底做了什么?这个命令可以浏览所有 git 仓库并打印我昨天的提交,让我重新思考。试试看,它很可能会成为你工作流程的一部分。

克隆仓库:



git clone https://github.com/jmfayard/kotlin-cli-starter
cd kotlin-cli-starter
./gradlew install
git standup


Enter fullscreen mode Exit fullscreen mode

./gradlew install将会安装该工具作为本机可执行文件。

还有两个可用选项:

  • ./gradlew run将在 JVM 上运行它
  • ./gradlew jsNodeRun将在 Node.js 上运行它

相同的通用代码,多个平台。

git 站立

现代编程实践

传统的 Bash 脚本包含

  • 一种你记不住如何执行 for 循环的 if/else 语句的语法
  • 由于Code Golf导致代码无法读取:ztf -P -c -D -a
  • 没有依赖管理(除了错误消息ztf not found:)
  • 一个文件完成所有工作
  • 没有构建系统
  • 不支持 IDE(vim对每个人来说应该足够了)
  • 没有单元测试
  • 没有 CI/CD

通过选择 Kotlin 这样的现代编程语言,我们可以

  • 现代语法
  • 可读代码
  • 多个函数、文件、类和包中的关注点分离
  • 像 Gradle 这样的现代构建系统
  • 依赖管理(这里使用gradle refreshVersions
  • 像 JetBrains IntelliJ 这样的现代 IDE
  • 单元测试。在这里,它们在所有平台上运行,./gradlew allRun
  • CI-CD。单元测试在 GitHub Actions 上运行。参见工作流程

这听起来可能很明显,但人们仍然用 Bash 编写他们的 CLI 工具,所以值得重复。

为什么要支持多平台?

这三个平台具有不同的特点,通过使您的代码在所有平台上可用,您可以决定哪一个更适合您:

  • JVM 拥有大量可用的库和出色的工具支持;但它缺少包管理器,启动速度较慢
  • 本机独立可执行文件启动速度非常快,例如可以通过 Homebrew 分发 - 我制作了一个 Homebrew 配方
  • Node.js 上还有大量的库,使用npm-publish打包起来也很容易。我的 git-standup 版本可以在https://www.npmjs.com/package/kotlin-cli-starter找到,而且我发现不用写一行 JavaScript 代码就能完成打包,真是太神奇了。

但更重要的是,这是一个学习 Kotlin/Multiplatform 的好机会。Kotlin/Multiplatform 是一项引人入胜的技术,但也可能相当复杂。使用 Kotlin/Multiplatform 编写 CLI 工具,您可以从简单的事情入手。

编写 Kotlin Multiplatform 代码是什么样的?

一旦您有了所需的抽象,它就感觉像常规的 Kotlin 一样,而您所需要的只是修改commonMain

当您必须使用预期/实际机制连接到特定于平台的 API时,事情会变得有趣。

例如,我需要检查一个文件是否存在:



// commonMain
expect fun fileIsReadable(filePath: String): Boolean


Enter fullscreen mode Exit fullscreen mode

在 JVM 上实现这一点很简单



// jvmMain
actual fun fileIsReadable(filePath: String): Boolean =
    File(filePath).canRead()


Enter fullscreen mode Exit fullscreen mode

但是如何使用 Kotlin Native 实现这一点?

由于 Kotlin Native 让我们可以访问底层 C API,那么问题是:他们如何在 C 中做到这一点?

让我们谷歌一下“如何检查一个文件是否可读 C”

第一个答案是关于访问系统调用。

我们用man access阅读友好的手册

man_access__Users_jmfayard_and_Untitled

这直接引导我们实现这个功能:



// nativeMain
actual fun fileIsReadable(filePath: String): Boolean =
    access(filePath, R_OK ) == 0


Enter fullscreen mode Exit fullscreen mode

有趣、奇怪的感觉,我们正在用 Kotlin 编写 C。

它有效,但是等等,还有更好的解决方案!

使用现有的 Kotlin Multiplatform 库

我后来发现okio已经实现了我处理文件所需的多平台原语。

我很高兴我可以删除我平台特定的代码:



// commonMain
expect val fileSystem: FileSystem

fun fileIsReadable(filePath: String): Boolean =
    fileSystem.exists(filePath.toPath())

fun readAllText(filePath: String): String =
    fileSystem.read(filePath.toPath()) {
        readUtf8()
    }

fun writeAllText(filePath: String, text: String): Unit =
    fileSystem.write(filePath.toPath()) {
        writeUtf8(text)
    }


Enter fullscreen mode Exit fullscreen mode

查看提交

我应该了解哪些多平台库?

Kotlin Multiplatform 库涵盖了最常见的用例:解析参数、JSON、数据库、IO、DI、协程和测试。

为这些库添加书签:

我特别喜欢用CliKt来解析参数。它有一个杀手级功能,不仅可以自动生成帮助信息,还可以自动生成 Bash、Zsh 和 Fish 的 shell 补全。

缺点:设置一切需要时间

构建这个项目很有趣,我学到了很多东西,但也花费了很多时间。

如果我没有那么多时间,下次我该怎么办?

回到 Bash?

kotlin-cli-starter:构建 CLI 工具的启动项目

真的不想回到 Bash。

这时我决定走另一条路,将我的实验转变为一个我和每个人都可以重复使用的启动项目。

单击“使用此模板”,您就可以开始编写自己的 CLI 工具。

jmfayard_kotlin-cli-starter__生活对于 Bash 编程、Telegram 和 GitHub 桌面来说太短了

我已在所有需要自定义的地方添加了以CUSTOMIZE_ME开头的评论

使用以下方式查找Edit > File > Find in Files

结论

使用命令行工具自动化您的工作流程。但在像上个世纪那样使用 Bash 之前,请三思。Kotlin 和其他现代编程语言可能是更优的解决方案。

使用 Kotlin Multiplatform 可以让您获得每个平台的优势,例如丰富的 JVM 库、本机可执行文件的快速启动以及 Node.js 的包管理器 (npm)。

这不是绝对必要的,但如果您想学习 Kotlin Multiplatform,这是一个很好的起点。

不过,从头开始设置可能需要一段时间。

这就是我将我的项目转换为可以重复使用的启动项目/ GitHub 模板的原因。

GitHub 徽标 jmfayard / kotlin-cli-starter

人生苦短,不适合 Bash 编程

在 Kotlin Multiplatform 中构建命令行工具的启动项目

包含真实世界 CLI 工具的重新实现:git-standup

jmfayard_kotlin-cli-starter__生活对于 Bash 编程、Telegram 和 GitHub 桌面来说太短了

安装

您可以使用下面列出的选项之一进行安装






































来源 命令
节点 npm install -g kotlin-cli-starter
安装程序 curl -L https://raw.githubusercontent.com/jmfayard/kotlin-cli-starter/main/installer.sh | sudo sh
测试 ./gradlew allTests
Kotlin 所有平台 跑步./gradlew allRun
Kotlin JVM 跑步./gradlew run
Kotlin 原生 ./gradlew install然后运行$ git standup
Kotlin Node.JS 跑步./gradlew jsNodeRun

为什么?

能够编写自己的命令行工具是一项很棒的技能。让所有事情自动化!

您可以使用 Kotlin 编写 CLI 工具,并享受使用的好处

  • 一种现代编程语言
  • 现代 IDE 支持
  • 单元测试和持续集成等现代实践
  • 利用 Kotlin 多平台库
  • 在 JVM 上运行代码并受益于丰富的 Java 库
  • 或者构建一个本机可执行文件,它启动非常快并且……




如果您使用 kotlin-cli-starter 构建了某些东西,我会很高兴地告诉了我!

文章来源:https://dev.to/jmfayard/how-to-write-a-command-line-tool-with-kotlin-multiplatform-45g2
PREV
保持冷静,拒绝编码挑战
NEXT
✔||🤢 提交或呕吐 | Switch(true)