新聞中心
大家好,我是 polarisxu。

有一個(gè)朋友咨詢一個(gè)問(wèn)題:
網(wǎng)友咨詢
實(shí)際項(xiàng)目中,使用 Go Module 難免會(huì)有一些自己的庫(kù)要引用,這些庫(kù)使用自建的 Git 服務(wù)管理,比如 GitLab 等。針對(duì)這樣的情況,不少教程都是讓設(shè)置 GOPRIVATE,即不走 GOPROXY。
然而,有些時(shí)候,不僅庫(kù)是私有的,而且地址很可能不是「合規(guī)」的。什么是「不合規(guī)」的?
- 不是 HTTPS
- 非 443 或 80 端口
- 直接使用 IP 地址
不是 HTTPS 問(wèn)題不大,主要是非 443 或 80,以及直接 IP 地址的問(wèn)題比較大。因?yàn)?Go 不支持下面的語(yǔ)法:
- import "studygolang.com:8081/polarisxu/util"
- import "192.168.1.1:80/polarisxu/util"
一般地,我們應(yīng)該避免出現(xiàn)這樣的情況,畢竟太惡心,而且沒(méi)必要自討苦吃。
但萬(wàn)一遇到了,怎么辦?本文就探討這個(gè)問(wèn)題。
01 模擬環(huán)境
因?yàn)橹皼](méi)遇到這樣的問(wèn)題,為了我更好的解決,這位朋友直接提供了他的環(huán)境供我試驗(yàn)。我注冊(cè)了賬號(hào),并創(chuàng)建了一個(gè)倉(cāng)庫(kù) testgo:http://vitogo.tpddns.cn:9000/polarisxu/testgo。(為了方便,這個(gè)倉(cāng)庫(kù)是 public)
提示:你想試驗(yàn),可以自己注冊(cè)一個(gè)賬號(hào)試試。當(dāng)然,也可以通過(guò) gitlab 本地搭建一個(gè)。
倉(cāng)庫(kù)中創(chuàng)建文件 testgo.go,內(nèi)容如下:
- package testgo
- func MyName() string {
- return "polarisxu"
- }
關(guān)鍵是這個(gè)庫(kù)的 go.mod 如何寫?
很顯然,我們不能直接用 vitogo.tpddns.cn:9000/polarisxu/testgo 這樣的 module 名稱。
02 module 名稱
那怎么辦?
我們可以借助 git 的功能,將 vitogo.tpddns.cn:9000 替換掉:(也可以直接修改 ~/.gitconfig 文件)
- git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://{{gitlab_url}}/"
這里有兩點(diǎn)需要注意:
1)url 后面的內(nèi)容,具體什么值,需要根據(jù)你的情況定。
可以通過(guò)你的自建倉(cāng)庫(kù)查看:
查看 clone
這里選擇 HTTP 方式(因?yàn)槲覄?chuàng)建了一個(gè) public 倉(cāng)庫(kù))。也可以選擇使用 ssh 方式,這樣即使私有倉(cāng)庫(kù),你配置上自己的 SSH KEY 也可正常 Pull。(如何配置 SSH KEY,網(wǎng)上很容易查到教程,GitHub 上就有)
我們這里使用了 http://vitogo.tpddns.cn:9000/,表示這個(gè)域名下所有的內(nèi)容。
2)insteadOf 后面的內(nèi)容,表示訪問(wèn)這個(gè)鏈接時(shí),將替換為上面 url 后的鏈接。
這個(gè)值寫什么?很顯然,必須是合規(guī)的域名。我們?nèi)我馐褂靡粋€(gè)域名試試,比如使用 https://studygolang.com/。
這時(shí),我們嘗試執(zhí)行如下命令:
- $ git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://studygolang.com/"
- # 讓 studygolang.com 不走 GOPROXY
- $ go env -w GOPRIVATE=studygolang.com
- $ go get -v studygolang.com/polarisxu/testgo
- go get: unrecognized import path "studygolang.com/polarisxu/testgo": parsing studygolang.com/polarisxu/testgo: XML syntax error on line 15: unescaped < inside quoted string
很好理解,go get 最終需要將代碼下載下來(lái),怎么下載?這張圖很好的說(shuō)明了:
go get 過(guò)程
那 go get 怎么知道當(dāng)前倉(cāng)庫(kù)使用 VCS 托管的呢?對(duì)于 studygolang.com 這種域名,它會(huì)嘗試請(qǐng)求,判斷 CVS 類型。很顯然,studygolang.com 沒(méi)有做任何處理,不是 CVS 類型,所以報(bào)錯(cuò)。
關(guān)于這個(gè)過(guò)程感興趣的,可以參考該文:https://studygolang.com/articles/35235
網(wǎng)友希望使用 vitogo.tpddns.cn 這個(gè)他的域名,但同樣有這個(gè)問(wèn)題。如果要讓它正常,需要做特殊處理,具體參考上面的文章。
所以,我們使用一個(gè)非常用的現(xiàn)成 Git 公開托管服務(wù),比如 gitea.com。(polarisxu/testgo 我打了一個(gè) tag:v0.0.1)
- $ git config --global url."http://vitogo.tpddns.cn:9000/".insteadof "https://gitea.com/"
- $ go env -w GOPRIVATE=gitea.com
- $ go get -v gitea.com/polarisxu/testgo
- get "gitea.com/polarisxu/testgo": found meta tag vcs.metaImport{Prefix:"gitea.com/polarisxu/testgo", VCS:"git", RepoRoot:"https://gitea.com/polarisxu/testgo.git"} at //gitea.com/polarisxu/testgo?go-get=1
- go: downloading gitea.com/polarisxu/testgo v0.0.1
- gitea.com/polarisxu/testgo
成功了!你可以到 $GOPATH/pkg/mod 下面看是否有對(duì)應(yīng)的包。
注意其中 ?go-get=1 這個(gè)參數(shù),你可以瀏覽器訪問(wèn) https://gitea.com/polarisxu/testgo?go-get=1,然后查看源碼,看看里面是什么內(nèi)容:
- go get gitea.com/polarisxu/testgo
因此,我們可以在 polarisxu/testgo 中增加 go.mod 文件:
- go mod init gitea.com/polarisxu/testgo
然后打上第二個(gè) tag:v0.0.2,再次獲?。?/p>
- $ go get -v gitea.com/polarisxu/testgo
- get "gitea.com/polarisxu/testgo": found meta tag vcs.metaImport{Prefix:"gitea.com/polarisxu/testgo", VCS:"git", RepoRoot:"https://gitea.com/polarisxu/testgo.git"} at //gitea.com/polarisxu/testgo?go-get=1
- go: downloading gitea.com/polarisxu/testgo v0.0.2
- gitea.com/polarisxu/testgo
03 使用該包
本地創(chuàng)建一個(gè)項(xiàng)目,引用上面定義的包:
- $ mkdir ~/testprivate
- $ cd ~/testprivate
- $ go mod init testprivate
- $ touch main.go
在 main.go 中輸入如下內(nèi)容:
- package main
- import (
- "fmt"
- "gitea.com/polarisxu/testgo"
- )
- func main() {
- fmt.Println("Hello", testgo.MyName())
- }
執(zhí)行 go mod tidy 后,運(yùn)行:
- $ go run main.go
- Hello polarisxu
正常輸出我們期望的結(jié)果。
04 總結(jié)
通過(guò)了解 go get 的基本原理,知曉 git 的一些處理方式,以及 GOPRIVATE 的作用。我相信遇到類似的問(wèn)題,你自己也能夠解決了。
注意,如果 gitea.com 你有實(shí)際使用,可以選擇 gitee.com、try.gogs.io 等。
另外,關(guān)于本文的問(wèn)題,Go 有幾個(gè)相關(guān) issue 討論:
https://github.com/golang/go/issues/34436
https://github.com/golang/go/issues/38213
本文標(biāo)題:GoModule:私有不合規(guī)庫(kù)怎么解決引用問(wèn)題
文章來(lái)源:http://www.dlmjj.cn/article/djidjgd.html


咨詢
建站咨詢
