如何用 GVM 管理 Go 項目

使用 Go 版本管理器管理多個版本的 Go 語言環境及其模塊。linux

正在編程的女人
Woman programming

Go 語言版本管理器(GVM)是管理 Go 語言環境的開源工具。GVM 「pkgsets」 支持安裝多個版本的 Go 並管理每一個項目的模塊。它最初由 Josh Bussdieker 開發,GVM(像它的對手 Ruby RVM 同樣)容許你爲每一個項目或一組項目建立一個開發環境,分離不一樣的 Go 版本和包依賴關係,以提供更大的靈活性,防止不一樣版本形成的問題。git

有幾種管理 Go 包的方式,包括內置於 Go 中的 Go 1.11 的 Modules。我發現 GVM 簡單直觀,即便我不用它來管理包,我仍是會用它來管理 Go 不一樣的版本的。github

安裝 GVM

安裝 GVM 很簡單。GVM 存儲庫安裝文檔指示你下載安裝程序腳本並將其傳送到 Bash 來安裝:golang

bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
複製代碼

儘管愈來愈多的人採用這種安裝方法,可是在安裝以前先看看安裝程序在作什麼仍然是一個很好的想法。以 GVM 爲例,該安裝程序腳本:web

  1. 檢查一些相關依賴性
  2. 克隆 GVM 存儲庫
  3. 使用 shell 腳本:
    • 安裝 Go 語言
    • 管理 GOPATH 環境變量
    • bashrczshrc 或配置文件中添加一行內容

若是你想確認它在作什麼,你能夠克隆該存儲庫並查看 shell 腳本,而後運行 ./binscripts/gvm-installer 這個本地腳本進行設置。shell

注意: 由於 GVM 能夠用來下載和編譯新的 Go 版本,因此有一些預期的依賴關係,如 Make、Git 和 Curl。你能夠在 GVM 的自述文件中找到完整的發行版列表。編程

使用 GVM 安裝和管理 GO 版本

一旦安裝了 GVM,你就可使用它來安裝和管理不一樣版本的 Go。gvm listall 命令顯示可下載和編譯的可用版本的 Go:bash

[chris@marvin ]$ gvm listall

gvm gos (available)

   go1
   go1.0.1
   go1.0.2
   go1.0.3

<輸出截斷>
複製代碼

安裝特定的 Go 版本就像 gvm install <版本> 同樣簡單,其中 <版本>gvm listall 命令返回的版本之一。cors

假設你正在進行一個使用 Go1.12.8 版本的項目。你可使用 gvm install go1.12.8 安裝這個版本:curl

[chris@marvin]$ gvm install go1.12.8
Installing go1.12.8...
 * Compiling...
go1.12.8 successfully installed!
複製代碼

輸入 gvm list,你會看到 Go 版本 1.12.8 與系統 Go 版本(使用操做系統的軟件包管理器打包的版本)一塊兒並存:

[chris@marvin]$ gvm list

gvm gos (installed)

   go1.12.8
=> system
複製代碼

GVM 仍在使用系統版本的 Go ,由 => 符號表示。你可使用 gvm use 命令切換你的環境以使用新安裝的 go1.12.8:

[chris@marvin]$ gvm use go1.12.8
Now using version go1.12.8

[chris@marvin]$ go version
go version go1.12.8 linux/amd64
複製代碼

GVM 使管理已安裝版本的 Go 變得極其簡單,但它不止於此!

使用 GVM pkgset

開箱即用,Go 有一種出色而使人沮喪的管理包和模塊的方式。默認狀況下,若是你 go get 獲取一個包,它將被下載到 $GOPATH 目錄中的 srcpkg 目錄下,而後可使用 import 將其包含在你的 Go 程序中。這使得得到軟件包變得很容易,特別是對於非特權用戶,而不須要 sudo 或 root 特權(很像 Python 中的 pip install --user)。然而,在不一樣的項目中管理相同包的不一樣版本是很是困難的。

有許多方法能夠嘗試修復或緩解這個問題,包括實驗性 Go Modules(Go 1.11 版中增長了初步支持)和 Go dep(Go Modules 的「官方實驗」而且持續迭代)。在我發現 GVM 以前,我會在一個 Go 項目本身的 Docker 容器中構建和測試它,以確保分離。

GVM 經過使用 「pkgsets」 將項目的新目錄附加到安裝的 Go 版本的默認 $GOPATH 上,很好地實現了項目之間包的管理和隔離,就像 $PATH 在 Unix/Linux 系統上工做同樣。

想象它如何運行的。首先,安裝新版 Go 1.12.9:

[chris@marvin]$ echo $GOPATH
/home/chris/.gvm/pkgsets/go1.12.8/global

[chris@marvin]$ gvm install go1.12.9
Installing go1.12.9...
 * Compiling...
go1.12.9 successfully installed

[chris@marvin]$ gvm use go1.12.9
Now using version go1.12.9
複製代碼

當 GVM 被告知使用新版本時,它會更改成新的 $GOPATH,默認 gloabl pkgset 應用於該版本:

[chris@marvin]$ echo $GOPATH
/home/chris/.gvm/pkgsets/go1.12.9/global

[chris@marvin]$ gvm pkgset list

gvm go package sets (go1.12.9)

=>  global
複製代碼

儘管默認狀況下沒有安裝額外的包,可是全局 pkgset 中的包對於使用該特定版本的 Go 的任何項目都是可用的。

如今,假設你正在啓用一個新項目,它須要一個特定的包。首先,使用 GVM 建立一個新的 pkgset,名爲 introToGvm:

[chris@marvin]$ gvm pkgset create introToGvm

[chris@marvin]$ gvm pkgset use introToGvm
Now using version go1.12.9@introToGvm

[chris@marvin]$ gvm pkgset list

gvm go package sets (go1.12.9)

    global
=>  introToGvm
複製代碼

如上所述,pkgset 的一個新目錄被添加到 $GOPATH

[chris@marvin]$ echo $GOPATH
/home/chris/.gvm/pkgsets/go1.12.9/introToGvm:/home/chris/.gvm/pkgsets/go1.12.9/global
複製代碼

將目錄更改成預先設置的 introToGvm 路徑,檢查目錄結構,這裏使用 awkbash 完成。

[chris@marvin]$ cd $( awk -F':' '{print $1}' <<< $GOPATH )
[chris@marvin]$ pwd
/home/chris/.gvm/pkgsets/go1.12.9/introToGvm

[chris@marvin]$ ls
overlay  pkg  src
複製代碼

請注意,新目錄看起來很像普通的 $GOPATH。新的 Go 包使用一樣的 go get 命令下載並正常使用,且添加到 pkgset 中。

例如,使用如下命令獲取 gorilla/mux 包,而後檢查 pkgset 的目錄結構:

[chris@marvin]$ go get github.com/gorilla/mux
[chris@marvin]$ tree
[chris@marvin introToGvm ]$ tree
.
├── overlay
│   ├── bin
│   └── lib
│       └── pkgconfig
├── pkg
│   └── linux_amd64
│       └── github.com
│           └── gorilla
│               └── mux.a
src/
└── github.com
    └── gorilla
        └── mux
            ├── AUTHORS
            ├── bench_test.go
            ├── context.go
            ├── context_test.go
            ├── doc.go
            ├── example_authentication_middleware_test.go
            ├── example_cors_method_middleware_test.go
            ├── example_route_test.go
            ├── go.mod
            ├── LICENSE
            ├── middleware.go
            ├── middleware_test.go
            ├── mux.go
            ├── mux_test.go
            ├── old_test.go
            ├── README.md
            ├── regexp.go
            ├── route.go
            └── test_helpers.go
複製代碼

如你所見,gorilla/mux 已按預期添加到 pkgset $GOPATH 目錄中,如今可用於使用此 pkgset 項目了。

GVM 讓 Go 管理變得垂手可得

GVM 是一種直觀且非侵入性的管理 Go 版本和包的方式。它能夠單獨使用,也能夠與其餘 Go 模塊管理技術結合使用並利用 GVM Go 版本管理功能。按 Go 版本和包依賴來分離項目使得開發更加容易,而且減小了管理版本衝突的複雜性,GVM 讓這變得垂手可得。


via: opensource.com/article/19/…

做者:Chris Collins 選題:lujun9972 譯者:heguangzhi 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關文章
相關標籤/搜索