本文首發於 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 可以獲得你們的關注,而且收到反饋。