Go 包管理機制深入分析

JFrog傑蛙科技發表於2020-06-12


前言

隨著 Go 語言的深入使用,其依賴管理機制也一直是各位 Gopher 熱衷於探討的話題。Go 語言的原始碼依賴可透過 go get 命令來獲取,但自動化程度不高,於是官方提供了 Dep 這樣的自動化批次管理依賴的工具。雖然 Go 語言的依賴管理在很多方面還是不如人意,但整個體系正在日趨完善,本篇就將從最基本的依賴管理場景出發,一同探討 Go 語言依賴管理的一些最佳實踐。

Go 依賴管理的基本思路

在 Go 語言中,我們透過 go get 命令將 GitHub 或者 Google Code 上的程式碼下載到本地指定目錄,然後在開發程式碼中透過 import 的形式引用本地的程式碼。

Go 包管理機制深入分析

Go 語言可以透過直接分析程式碼中的 import 語句來查詢依賴關係。go get 命令在執行時,就會自動解析 import 來安裝所有的依賴。那麼下載的依賴在本地是如何儲存的呢?

這裡就涉及到 Go 語言的 WORKSPACE 概念,簡單來說就是透過 GOPATH 環境變數來設定 Go 程式碼的位置。一般來說,GOPATH 目錄下會包含 pkg、src 和 bin 三個子目錄,這三個目錄各有用處。

bin 目錄用來放置編譯好的可執行檔案,為了使得這裡的可執行檔案可以方便的執行,在 shell 中設定PATH變數。

src 目錄用來放置程式碼原始檔,在進行 import 時,是使用這個位置作為根目錄的。自己編寫的程式碼也應該放在這下面,不同的專案放在不同的目錄下進行管理。

pkg 用來放置安裝的包的連結物件(Object)的。這個概念有點類似於連結庫,Go 會將編譯出的可連線庫放在這裡,方便編譯時連結。不同的系統和處理器架構的物件會在 pkg 存放在不同的資料夾中。

當專案在 src 目錄下管理時,多個專案可能都會使用相同的依賴,如果每個專案都存一份依賴顯然會帶來大量的冗餘,這裡我們推薦一個設定 GOPATH 環境變數時的小技巧。

Go 包管理機制深入分析

這樣第三方包就會預設放置在第一個路徑中,而你可以在第二個路徑下編寫自己的程式碼,多個專案共享一份依賴。


dep - 官方 Go 依賴管理工具

dep 是 Go 語言官方提供的依賴管理工具,跟其他依賴管理工具類似,都是透過一個檔案描述依賴的座標資訊,然後批次管理(下載、升級等)依賴包(原始碼)。dep 是一個開源專案, 大家可以在 瞭解詳細資訊,其安裝方式大家可以參考官方說明,這裡我們主要介紹其使用。

基本操作

透過 dep init 命令來初始化,會建立Gopkg.lock,Gopkg.toml檔案和一個空的vendor目錄。

我們在程式碼中透過 import 命令新增依賴後,透過 dep ensure 就可以下載依賴到本地 $GOPATH/src 目錄下。

main.go

Go 包管理機制深入分析

Gopkg.lock

Go 包管理機制深入分析

透過 dep status 我們可以檢視當前依賴引用的情況

Go 包管理機制深入分析

另外有一個 dep check 命令來檢查是否存在依賴被引用,但是程式碼中並沒有使用的情況,Go 語言對於依賴的引用比較嚴格,不允許引用了但是沒使用的情況。從軟體安全的角度考慮,這是一個很好的實踐,避免引入一些安全風險。

Go 包管理機制深入分析

當然,這種時候我們就需要移除本地依賴,最好不要手動刪除vendor中的內容,而是透過 dep ensure -update 命令來移除。

從 dep 的目錄結構,我們可以分析出 dep 的基本工作思路:

這裡面有兩個關鍵的步驟:

解析依賴

從當前專案的 import 檔案中解析出整個工程的依賴情況,並結合 Gopkg.toml 定義的規則,然後將依賴關係輸出給 Gopkg.lock,注意這個 lock 檔案最好不要手動修改。

獲取依賴

透過 Gopkg.lock 瞭解整個依賴關係之後,將依賴的具體內容拉取下來放到 vendor 目錄中,然後執行 Go build 時從本地的 vendor 讀取依賴並完成構建。

這一些都是在 dep ensure 時完成的,其實在執行這個命令時還可以傳引數,最主要的是 -no-vendor 和 -vendor-only 這兩個引數。

-no-vendor 引數只會導致執行 resolve 函式,結果是建立一個新的Gopkg.lock 檔案,不會更新 vendor;而 -vendor-only 引數將跳過 resolve 並僅執行 vendoring 函式,導致 vendor/ 從已存在的Gopkg.lock 重新更新。

關於 dep 更多深入內容,可以參考 

總結

Go dep 目前是一款比較好用的依賴管理工具,很多比較大型的專案都在使用,從中可以學習到依賴管理的一些基本思路,對於理解其他語言,比如 NPM 的依賴管理模型也是比較有好處的。

更多精彩內容可以專注我們的線上課堂

微信搜尋公眾號:jfrogchina 獲取課程通知


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69954434/viewspace-2698096/,如需轉載,請註明出處,否則將追究法律責任。

相關文章