---
# System prepended metadata

title: Day19 Go-glide 套件管理工具

---

# Day19 Go-glide 套件管理工具


### ==== go glide管理方式已經過時了 ====

**這篇文章適合公司、機構內部使用 glide 來管理、或求知慾強到爆的同學**。  

> Oh My God!  
> 我才剛點進來 你就這樣跟我說，這樣對嗎？  
    

Go官方目前主推使用 `go module` 來管理套件，如果想學主流可以跳過這篇。  
不是說 glide 已經不能用了，絕大部分的套件沒有問題、仍然可以穩穩地使用。  
`go glide` 在一年多以前也是主流、一堆人用爆，只不過目前不再更新了。  
學習 glide 可以當作 Golang 歷史傳統遺留下來的一些足跡。  


[**glide**](https://github.com/Masterminds/glide) 套件的作者，在golang官方推gomod來管理之後，  
至今已經停止維護一年多了，一點要復活的意思與跡象都沒有。  
有些套件的最新版本（套件包名稱後面有`/v2 /v3`等等的）已經無法透過glide方式取得了。  

> 例如 ：
> [colly (最新版本v2)](https://github.com/gocolly/colly/tree/v2.1.0) => glide只能裝到**v1**
> [go-redis (最新版本v8)](https://github.com/go-redis/redis/tree/v8.0.0) => glide只能裝到**v6**
    
    $ go get github.com/go-redis/redis/v8
    $ go get github.com/gocolly/colly/v2

這種情況的解決辦法，只能透過`go get`、`go mod`方式安裝，  
或者降低套件版本，不使用最新版本(不要有`/v2`字樣的版本)。    


--- 

## Go glide 與 Vendor


`Vendor`中文是`供應商`。  

在`Go`專案資料夾底下的`Vendor`資料夾中，  
放著的是這個專案會用到的`lib`依賴，或稱作第三方的套件。  

我們可以透過**glide**這個工具來管理vendor包。

> 官方文件寫著以下這段：
> Please consider using that instead of Glide. Glide is now mostly unmaintained.
> 顯示現在 **[go-glide](https://github.com/Masterminds/glide)** 已經不再被更新、維護了。  
> 未來我會再介紹當前主流用法 `go module`方式  


## 下載、安裝glide套件管理工具

提供以下數種的安裝方式：  

#### 透過 MacOS Homebrew安裝

    $ brew install glide

#### 手動編譯安裝  

    $ go get github.com/Masterminds/glide
	$ cd ~/go/src/github.com/Masterminds/glide
	$ make install

#### 下載執行檔安裝  
[**Release點我下載**](https://github.com/Masterminds/glide/releases)

    直接下載編譯過後的可執行檔 (對`Windows`來說就是`.exe`檔)，  
    並加入系統環境變數 Path 中。  


---

## glide 初始化  
已經有glide了，接著到自己的開發專案目錄底下執行glide初始化  

    $ glide init

或

    $ glide create

會出現以下的對話訊息，依照給的提示來輸入y/N  

![glide create](https://i.imgur.com/YBOKIRl.png)

執行完畢後會產生出一個 `glide.yaml`檔案。  
如果程式還沒有任何依賴、用到任何第三方函式庫之前，glide.yaml會長這樣  

```yaml
package: .
import: []
```

> 因為在Go程式中第一行開頭是`package`，glide.yaml中第一行也是`package`，  
> **Go程式**中的package是**目前這隻`.go程式`隸屬哪個package包**，  
> **glide.yaml**的package則是專案的位置，表示**這個專案的絕對或相對路徑**  
> 兩者實際上是不同的東西，別搞混哩。  

---

## glide 執行原理

`glide套件`會先掃描你各位程式中的**每個程式import到的`Library套件`**，  
然後去幫你各位去下載回來。  
如果`glide.yaml`中有指定版本，則會幫你各位下載你所指定的版本的Library套件。  
如果沒指定、或專案有import套件卻跟本沒寫在glide.yaml中的話，那就只能乖乖下載最新版本。  


## glide.yaml 檔
檔案中指定了你各位要的`libiray函式庫、套件`的版本。  

使用的是`yaml`格式，是一種**前凸後翹、凹縮有緻的**編排格式。  
例如：  
```yaml
我:
    - 綽號:"茶哥"
    - 錢包:
      50元銅板
      被刷爆的信用卡
      借據
      
你:
    - 綽號:"富二"
    - 皮夾:
      藍色小朋友
      支票
      地契
```


#### glide.yaml **關鍵字**
通常只會用到這三種：  
* package 包
* import  引入
* version 版本


#### 【yaml 需注意的坑】
雖然沒有硬性規定要用空白或是Tab按鍵，但一份yaml文件內要統一，  
要嘛**全用兩格`Space空白`**、要嘛**全用四格`Space空白`**、或者是**全用`Tab鍵`**  
**嚴禁混搭使用**，違者記小過一支。  

以下是用到**gin**套件的一個小範例，  
第一行要改成**你的專案位置及名稱(相對於GOPATH的go/src目錄)**，或者改用**相對路徑(.)**  

否則會出現
`The name listed in the config file does not match the current location`  


glide.yaml  

```yaml
package: github.com/gjlmotea/golang/helloworld
import:
  - package: github.com/gin-gonic/gin
    version: 1.3.0
```


helloworld.go (import了gin套件)  

```go
package main

import "github.com/gin-gonic/gin"

func main() {

}
```

---

## glide 指令

    $ glide init
幫您產出`glide.yaml`檔案。  
如果您要自己用`Vim`或其他文字編輯器手刻一個glide.yaml也可以！  


#### 【$ glide up】

    $ glide up
    或
    $ glide update
**依照yaml檔寫好的規則升級**  

這會依照glide.yaml配置好規則載套件，下載`Library、套件`到當前目錄的 `vendor/` 底下。  

**可依照規則來升級版本**  

若此階段還無glide.lock檔的話，會自動產出`glide.lock`檔  

#### 【glide.lock】

可以用編輯器、或`cat`指令看一下 **glide.lock** 這份奇怪的檔案。  

這些奇形怪狀的文字是什麼鴨？豪可爬啊大大！  
細看的話，會發現是一堆**套件、版本、跟Sha256碼**。  

透過這些，讓glide管理工具 記住你現在這份專案所用到的套件版本資訊，  
`lock`有直接**釘死在這個狀態**、**做快照**的意思。  
如果未來用 `$ glide install` 安裝，就會直接下載變成這個狀態！  

> 哦，對於 glide.lock 中出現了 沒有看過的套件包感到疑惑？  
> 
> 這是因為你所用到的套件包，引用、依賴到了別人的套件包  
> 因為你用到的源頭套件 用到了其他源頭的套件，所以這些也一併被匯入進來  
> 
> （相同地，你今天開發這個專案也是用到 依賴到別人寫好的套件，  
> 待專案完成、開放出去後，其他人也有可能使用到你的這個專案，也會要下載你所用到的套件）  
    

#### 【$ glide install】 

依照glide.lock指定版本安裝    

    $ glide install

讓`Library、套件`變成glide.lock的形狀。  
在沒有`glide.lock`檔案的情況下運行`$ glide install`，則跟運行 `$ glide up` 結果相同。  


#### 【$ glide cc】

清除快取  

    $ glide cc

有時候莫名其妙遇到坑，可能就是因為**快取**的關係。  

---


## glide.yaml import多個套件

import數個套件的寫法  
```yaml
import:
  - package: github.com/gin-gonic/gin
    version: 1.3.0
  - package: github.com/spf13/viper
    version: ^1.6
```

## glide.yaml 版本、升版規則

glide.yaml  
```yaml
  - package: github.com/gin-gonic/gin
    version: 1.3.0
```

其中 version是指定`1.3.0`，這沒問題。    

但如果是 `~1.3.1` 或 `^1.3.2` 呢？  

`~`：**自動升版（次要版本）**，如果偵測到github有新的 `1.3.x` (fixed bug version) 會自動升上去  
	`ex: 1.3.1 -> 1.3.2 `

`^`：**自動升版（主要版本）**  
	`ex: 1.3.2 -> 1.4.0`

其中 `x` 或 `*` 可以被視作任意值。  

可參考[**版本規則**](https://glide.readthedocs.io/en/latest/versions/)


## 總結 Vendor優缺點  
glide工具 用以上的方式來管理Vendor，每個專案底下都會有一包套件，  
當要移除套件時，可以直接右鍵刪除 或 `rm -r vendor`。  

今天若開發**A**與**B**兩個專案，都使用、依賴到`gin`這個套件，
**優點**：
* A的gin 與 B的gin 版本可以不同，因為專案AB的依賴各有一份，彼此不會干擾，依賴的改動非常安全。  
* 上傳到github或雲端時，可以在`.gitignore`加入`vendor/`這行，**讓套件依賴關係可以只上傳glide.yaml及glide.lock這兩個小小文件檔**

**缺點**：
* 當 A的gin 與 B的gin 版本相同時，一份相同的Vendor佔據了兩個地方，變相造成檔案肥大。
* 當`clone`較大型的專案時，都得`$ glide install`下載vendor（可能好一段時間），才能執行程式。  

