本文首发于 blog.befovy.com/2019/12/fvm…git
周末时间用 Go 语言完成了 Flutter 多版本管理工具的初个版本 fvm v0.1.0。我必须认可,这个版本彻底是在造轮子,并且仍是和 leoafarias fvm 如出一辙。github
简单说就是有需求:在开发 fijkplayer (一个 Flutter 的媒体播放器)的过程当中,我逐渐从开始只有 Android、iOS 的移动端版本,发展到 Flutter 桌面版本。在 fijkplayer 桌面版的开发中,我用的是 go-flutter 为 Flutter 提供桌面支持,go-flutter 默认用的是 flutter beta 版本,而移动端 fijkplayer 用的是 Flutter stable 版本。golang
最开始每次切换我都很痛苦,flutter 切换 channel 须要下载大量内容,channel 切换完成后再跑 flutter doctor 有须要大量的下载,并且还都是国外服务器,下载很是慢。shell
后来我发现了 leoafarias fvm,但这个工具安装第一次没成功,其实我对 dart native 也不太懂,确实没搞定安装问题。另外 dart native 是否是真的二进制我也没有研究,要是还须要 dart 才能跑起来(就像运行 jar 须要 jvm 同样),其实我是不喜欢桌面端这种带有运行时的东西的。我就须要一个小工具而已。缓存
因此干吗不本身造(chao)一个呢?服务器
恰好作 go-flutter 开发的时候对其自带工具 hover 进行过修改 并合并到了主分支。 hover 也是一个命令行小工具,并且能够直接经过 go get
安装, hover 使用库 spf13/cobra 实现命令行子命令以及参数解析等 “样板代码”,工程结构很简洁、清晰。app
另外一方面,我虽然很早就学习过 go 语言,而且也在不少小项目(对,主要是我上学时完成的大做业)中用过 go。用的挺多可是不够系统化,写的代码还仅仅是个 demo。最近打算让本身的 go 语言水平再上一个台阶,一个行动是加入了 GCTT - go 中文翻译组 ,翻译一些国外大牛的优质文章,同时我打算认真搞一个 go 项目开源出来。 可是从啥搞起呢, 就从作一个 fvm 开始吧。jvm
是的, 第一个版本 v0.1.0 彻底实现了 leoafarias fvm 中的全部逻辑,是个彻彻底底的轮子工程。可是后面的版本就从 leoafarias fvm 脱离了,我要开发中国特点的 fvm。ide
spf13/cobra 是一个可以帮咱们快速建立 go 命令行工具的 go 库,经过提供了一个生成 "样本代码" 的 go 工具。Go 世界中鼎鼎大名的 Docker、Kubernetes、Hugo 等都用了 cobra 来构建命令。工具
首先,安装 cobra 工具:
› go get -u github.com/spf13/cobra/cobra
复制代码
使用 cobra 建立项目 fvm ,并使用 github.com/befovy/fvm 做为包名:
› cobra init fvm --pkg-name github.com/befovy/fvm
复制代码
使用 cobra add 须要的子命令:
› cobra add list
› cobra add install
› cobra add remove
› cobra add flutter
› cobra add use
› cobra add config
复制代码
完成这些步骤后咱们有了这些文件:
› tree ./
./
├── LICENSE
├── cmd
│ ├── config.go
│ ├── flutter.go
│ ├── install.go
│ ├── list.go
│ ├── remove.go
│ ├── root.go
│ └── use.go
└── main.go
复制代码
而后咱们初始化 go modules ,下载依赖并编译fvm 。
› go mod init github.com/befovy/fvm
› go mod tidy
› go build
复制代码
编译好的 fvm 出现了,运行一下看看发生什么。
› ./fvm
A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.
Usage:
fvm [command]
Available Commands:
config A brief description of your command
flutter A brief description of your command
help Help about any command
install A brief description of your command
list A brief description of your command
remove A brief description of your command
use A brief description of your command
Flags:
--config string config file (default is $HOME/.fvm.yaml)
-h, --help help for fvm
-t, --toggle Help message for toggle
Use "fvm [command] --help" for more information about a command.
复制代码
cobra 已经构建好了 fvm 的雏形,而且添加好了子命令。接下来就该实现 fvm 的具体逻辑了。
fvm 做为一个 sdk 版本管理工具,让用户可以同时在本地安装并缓存多个 Flutter 版本,而且可以快速在各个版本间切换使用。
其核心逻辑就是在本地文件夹中缓存多个 Flutter 版本,并为项目建立指定 Flutter 版本的软连接。或者在全局环境建立指定版本的 Flutter 软连接。
内部主要功能实现都依赖于 go 语言标准库中的 os/exec
包。经过 os/exec
能够建立子进程执行命令,并管理子进程的输入输出。
fvm 的各个子命令,基本就是查找一些文件、文件夹,执行如下 git 命令并对其输出进行解析。
具体的实现都在 代码里,这里不啰嗦了。
实现中要注意检查各类可能的错误,输出错误提示给用户。若是错误影响业务逻辑继续执行,就主动退出程序。
在 fvm v0.1.0 版本中,这方便处理还不够细致。但仅这些我就感受到了 go 中烦人的 error。后续还要进行重构,用更优雅的代码对 error 进行处理。
经过实现一个 fvm 我获得了什么呢?
我给本身写了个工具,方便我切换 Fluter 版本。
fvm 才只是一个开始,其难度还比不上我之前完成的大做业。可是 fvm 开源了、发布了。刚好刚翻译一片文章,Go Modules : v2 及更高版本, 经过持续更新维护 fvm 我也能实践 Go Modules 背后的理念。
这个版本的 fvm 还太简单,用到的知识不多。可是若是之后遇到什么相关新的知识、牛逼 idea,我也能在 fvm 中快速试水。毕竟每次用 hello world 试水太乏味了。
最后,但愿 fvm 可以获得你们的关注,而且收到反馈。