[Kotlin翻译]我们如何构建Localazy CLI:Kotlin MPP和Github Actions

556 阅读8分钟

本文由 简悦SimpRead 转码,原文地址 vaclavhodek.com

我们是如何建立Localazy CLI,为我们的开发人员提供友好的软件本地化工具,用于智能和懒人开发......。

我们是如何建立Localazy CLI,为聪明和懒惰的开发者提供友好的软件本地化工具的:-).

最初,Localazy只支持Android,通过我们简单易用但功能强大的Gradle插件,自动为开发者处理一切。事实证明,我们的愿景是_对开发者友好的软件本地化_是正确的方向。我们也开始收到很多支持其他平台的请求。

我们准确的共享内存ShareTM主动审查和直观的界面是令人信服的理由,让Android生态系统以外的开发者也使用Localazy,即使集成度不如Gradle插件那么复杂。

我们考虑了正确的解决方案,使其他开发者能够在所有平台上使用Localazy。我们希望保持对开发者友好/以开发者为中心的方法,CLI,也就是命令行界面,是一个合理的答案。

Kotlin多平台

我们希望Localazy CLI能在所有主要平台上得到支持。理想情况下,我们希望不依赖Java或Node,因为这些通常意味着一个巨大的二进制文件或巨大的虚拟机。对于一个特定的操作系统来说,小而快的二进制文件看起来是一个完美的解决方案。

Kotlin在Localazy已经被大量使用,它为整个后端提供动力。因此,Kotlin Multiplatform是这项任务的一个合理选择。它允许我们用一种我们熟悉的编程语言为原生的Linux、macOS、Windows和Java编写一个代码库。

几乎所有的代码都是在平台之间共享的,并且是用纯Kotlin编写的。只有两个依赖平台的功能--文件系统访问和HTTP通信。

文件系统访问非常简单,我们只是为Java(使用java.io.File和流)、Linux/MacOS(使用POSIX)和Windows(略微修改了POSIX,因为Windows上有小的差异)创建一个实际的实现。

对于HTTP通信,良好的老式 HTTPUrlConnection 用于Java,ktor client 用于Linux、macOS和Windows。

CLI的原型在几天内就准备好了,经过一些微调,我们能够把它编译成Java的JAR和Linux、macOS和Windows的本地二进制。

一切似乎都很好,但事实并非如此...

迁移到WinInet

嗯,一切都很好,但是ktor客户端引入了对libcurl的依赖。这在Linux或macOS上不是什么大问题,因为你要么已经安装了libcurl,要么你可以通过APT、YUM或Brew单线安装它。

然而,在Windows上,有必要在放置CLI二进制文件的同一目录下包含近20个DLL文件。Ough,这可不好,我们肯定不希望这样。

可能的解决方案是什么?

  • 创建一个安装程序,将DLL文件安装到系统文件夹中。不! 这似乎不是一个简单的对开发者友好的解决方案,在精神上下载就走,而且我不喜欢在系统层面上安装任何东西的想法。

  • 静态链接libcurl到二进制文件。为了实现这个目标,我们花了好几天时间。部分地,我们能够做到,但是产生的二进制文件是巨大的,而且它仍然需要一些依赖性。我们甚至从源代码重新编译了libcurl,所以它不依赖于OpenSSL和其他库,而是使用Windows本地子系统。毫无收获。

  • 重写整个HTTP连接部分,使用 WinInet --Windows本地通信栈。嗯,这意味着大量的工作和另一个实现,但这是值得的,因为产生的二进制文件很小,没有依赖性。于是我们就这样做了。

强大的Gradle构建

我们调整了Gradle构建脚本,使其在两种不同的模式下工作--当IntelliJ处于活动状态和最终构建过程运行时。

IntelliJ激活时,只使用基于主机操作系统的选定平台。这种设置允许我们轻松地开发CLI,而且只有一个编译目标,没有额外的操作。

当完全构建运行时,各平台的二进制文件被编译、打包、重命名并放置到正确的文件夹中。额外的操作是为了优化二进制文件的大小。对于Linux主机,不仅要编译本地二进制文件,还要编译Java版本,为Docker镜像准备一个二进制文件,并生成DEB和RPM包。

交叉编译

Kotlin MPP的最大缺点是交叉编译。目前只能在特定的主机平台上构建一些目标。Windows二进制只能在Windows主机上构建。这同样适用于macOS。

在那个时候,我们已经计划使用Github Actions进行编译,但由于我们有自己的基于Linux的运行器,我们想用它来尽可能地覆盖构建过程。即使没有我们自己的运行器,Linux的动作也更便宜。

交叉编译的第二个原因是我根本没有Windows,交叉编译允许我检查一切是否正常,我仍然可以用虚拟化的Windows测试二进制。从技术上讲,我可以在虚拟机中构建二进制文件,但由于上述原因,我对某种交叉编译更感兴趣。

对于macOS没有解决方案。它只是需要macOS主机。

然而,对于Windows来说,有一个解决方案。在基于Ubuntu的docker中安装Wine,并解压Windows版本的OpenJDK,这样它就可以从Wine中访问。确保也要设置JAVA_HOMEPATH。调用./gradlew.bat时由于缺少TTY而失败,但有一个简单的解决方法。

faketty () {
    script -qfec "$(printf "%q " "$@")"
}

faketty wine cmd /c gradlew.bat --no-daemon --console=plain clean buildWindows

就这样了! Windows二进制文件可以在Linux主机上构建。

分发

一旦所有平台的二进制文件被建立起来,我们需要使它们对你可用

Java JAR是可以简单地下载的。这是一个独立的应用,不是一个库,所以Maven意义不大。不过,这样可能更好。下载后可在任何有JVM的平台上使用。瞬间就能完成。 Docker镜像是通过Docker Hub分发的。简单。不需要考虑这个问题。 Windows二进制文件可在我们的网站上下载,在未来,我们可能会研究如何让它在更多地方可用。 MacOS二进制文件可在我们的网站上下载,并可通过Homebrew安装。 Linux二进制文件可在我们的网站上下载--作为一个本地二进制文件和DEB及RPM包。我们已经安装了Sonatype Nexus Repository,用于分发我们的Gradle插件,所以我们也把它作为APT和YUM仓库使用。还有bash自动完成脚本与二进制文件一起安装。

Github行动

我们有两个Action--一个在macOS上运行,一个在我们自带的Linux runner上运行。Actions与一个版本绑定,所以每当我们想发布一个新版本时,我们只需在Github上创建一个标签并发布。该版本的名称会自动作为版本标识符。

我们的Actions到底是做什么的?

*为Linux、macOS和Windows构建一个本地二进制文件

  • 构建CLI的Java版本
  • 构建一个有版本的Docker镜像,以及最新的Docker镜像
  • 将Linux版本打包成DEB和RPM
  • 将所有的二进制文件压缩、压缩成tar.gz并上传到我们的分发服务器上。
  • 上传DEB和RPM到Nexus仓库
  • 更新、提交和推送Brew的新版本的配置文件。
  • 改变CMS中CLI的版本
  • 重建我们网站的静态部分,包括文档。

因此,我们改变代码,测试它,提交,推送并在Github上创建一个版本。就这样了。其他的事情都是自动处理的,包括网站上的变化。更少的手工工作和重复性任务,更少的人为错误 :-) 。

就我个人而言,我喜欢在Github上创建一个版本的几分钟后,调用apt update && apt upgrade来确保你运行的是Localazy CLI的最新版本;-)。

JSON模式

即使我们不记得我们的配置文件localazy.json的所有细节,该文件被CLI使用。值得庆幸的是,我的同事Jan花了不少时间来调整该文件的JSON模式,所以你可以在支持的IDE中享受智能完成。我们在Visual Studio CodeIntelliJ IDEA上进行了测试,两者都运行得很好。

研究它、创建它和发布它需要一些时间,但它只是让我们的工具对开发者更友好,这很重要。我们真的努力为你带来一个伟大的工具,而不仅仅是为了填补一些缺失的空白。细节很重要。

下一步要做什么?

我们现在正在从Comodo获得一个证书,所以我们可以签署Windows二进制文件,并摆脱关于可能有危险的未签署应用程序的警告。

看起来我们可以在Linux上签署Windows二进制文件,所以一旦我们有了证书,它就会成为Github行动的一部分。

结果

Kotlin MPP是构建CLI应用程序的一个可行的解决方案--它只需要进行一些调整以支持所有的平台--并且通过Github Actions,可以实现一切自动化。

尽可能多的逻辑在通用模块中是很重要的。

对Kotlin MPP的一些建议

  • 交叉编译应该可以开箱即用
  • ktor客户端应该为Windows引入WinInet/WinHTTP实现

然而,感谢JetBrains的Kotlin,编写CLI很有趣,而且在所有平台上都能顺利运行。

本文最初以How we built Localazy CLI: Kotlin MPP and Github Actions发表在localazy.com上。


www.deepl.com 翻译