4 回答

TA貢獻(xiàn)1831條經(jīng)驗 獲得超9個贊
理想情況下,發(fā)行版應(yīng)將已安裝的依賴項打包在與 GOPROXY
協(xié)議兼容的布局中。然后,您將能夠進(jìn)行適當(dāng)?shù)脑O(shè)置并運行以使用已安裝的依賴項。GOPROXY
go mod tidy
但是,據(jù)我所知,在這一點上,沒有發(fā)行版實際上提供了一棵樹。您可能需要一個解決方法。GOPROXY
下一個最好的選擇是使用指令自己連接替換件。 已經(jīng)知道更喜歡指令中的版本而不是其他版本,所以做這樣的事情就足夠了:replace
go mod tidy
replace
go mod init github.com/gsauthof/gonzofilter go mod edit -replace go.etcd.io/bbolt=/usr/share/gocode/src/go.etcd.io/bbolt go mod edit -replace golang.org/x/sys=/usr/share/gocode/src/golang.org/x/sys go mod edit -replace golang.org/x/text=/usr/share/gocode/src/golang.org/x/text go mod tidy
但是,請注意,該指令要求目標(biāo)包含顯式文件,因此,僅當(dāng)依賴項已具有顯式文件或發(fā)行版打包程序已將它們添加為修補(bǔ)程序以支持此用例時,此操作才有效。replace
go.mod
go.mod
請注意,有了這些指令,您的構(gòu)建將不會隨著時間的推移而重現(xiàn)或可重復(fù):如果您更改依賴項的發(fā)行版安裝版本,那么的含義將靜默地更改為使用這些不同的(并且可能不兼容!)版本。replace
go build
因此,我建議您不要這樣做,而是使用和/或從上游或公共模塊代理(例如)獲取所需的特定模塊版本。go get
go mod tidy
proxy.golang.org
如果您擔(dān)心上游篡改,請注意,默認(rèn)情況下,Go項目的官方二進(jìn)制命令分發(fā) - 以及從原始源代碼構(gòu)建的命令 - 會自動根據(jù) https://sum.golang.org 的可審計公共數(shù)據(jù)庫驗證已下載模塊的校驗和;但是,默認(rèn)情況下,該命令的 Fedora 發(fā)行版禁止使用校驗和數(shù)據(jù)庫。go
go
go

TA貢獻(xiàn)1852條經(jīng)驗 獲得超7個贊
您可以在生成的 mod 文件中使用 replace 關(guān)鍵字顯式定義,以引用本地模塊。
replace packagename => /usr/share/gcode

TA貢獻(xiàn)2016條經(jīng)驗 獲得超9個贊
將這樣的 GOPATH 項目遷移到感知 Go 模塊的一種方法是:
首先,使用直接依賴項手動創(chuàng)建 :go.mod
module github.com/gsauthof/gonzofilter
go 1.15
require (
go.etcd.io/bbolt v1.3.5
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7
golang.org/x/text v0.3.5
)
我從我的系統(tǒng)上當(dāng)前的內(nèi)容中獲得了最低版本:
$ rpm -q golang-etcd-bbolt-devel golang-x-sys-devel golang-x-text-devel golang-bin
golang-etcd-bbolt-devel-1.3.5-2.fc33.noarch
golang-x-sys-devel-0-0.39.20210123git9b0068b.fc33.noarch
golang-x-text-devel-0.3.5-1.fc33.noarch
golang-bin-1.15.8-1.fc33.x86_64
現(xiàn)在的問題是,人們不能簡單地告訴模塊感知的Go工具在它們所在的文件系統(tǒng)路徑下查找這些模塊。/usr/share/gocode/src
有一個指令可以添加到我們的文件中,以設(shè)置單個依賴項的查找路徑,例如:replacego.mod
replace (
go.etcd.io/bbolt => /usr/share/gocode/src/go.etcd.io/bbolt
golang.org/x/sys => /usr/share/gocode/src/golang.org/x/sys
golang.org/x/text => /usr/share/gocode/src/golang.org/x/text
)
但是,靜止不使用 來自 的間接依賴項,例如,包提供的依賴項依賴于。在此示例中,確實找到了,但該文件不包含任何指令。go build/usr/share/gocodegolang-x-text-develgo build/usr/share/gocode/src/golang.org/x/text/go.modreplace
因此,這將失?。?/p>
$ GOPROXY=off go build -mod=readonly
go: golang.org/x/text@v0.3.6 requires
golang.org/x/tools@v0.0.0-20180917221912-90fa682c2a6e: module lookup disabled
by GOPROXY=off
為了解決這個問題,我們必須為所有間接依賴項添加替換指令行。
當(dāng)然,手動執(zhí)行此操作既繁瑣又容易出錯。
因此,我們可以使用一個小的shell單行線來自動化:
我們從這個文件開始:go.mod
module github.com/gsauthof/gonzofilter
go 1.15
require (
go.etcd.io/bbolt v1.3.5
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7
golang.org/x/text v0.3.6
)
replace (
//replace-this
)
然后,以下固定點迭代添加依賴項,直到構(gòu)建成功:
while true; do
GOPROXY=off go build -mod readonly 2> t
if [ $? -eq 1 ] && grep 'module lookup disabled' t >/dev/null; then
x=$(grep disabled t | tr ' \t' '\n' | grep '@' | cut -d'@' -f1 )
echo "Adding $x"
sed -i "s@^\(//replace-this\)@\t$x => /usr/share/gocode/src/$x\n\1@" go.mod
continue
fi
break
done
這導(dǎo)致此示例項目的以下 require 指令:
replace (
go.etcd.io/bbolt => /usr/share/gocode/src/go.etcd.io/bbolt
golang.org/x/sys => /usr/share/gocode/src/golang.org/x/sys
golang.org/x/text => /usr/share/gocode/src/golang.org/x/text
golang.org/x/tools => /usr/share/gocode/src/golang.org/x/tools
github.com/yuin/goldmark => /usr/share/gocode/src/github.com/yuin/goldmark
golang.org/x/mod => /usr/share/gocode/src/golang.org/x/mod
golang.org/x/net => /usr/share/gocode/src/golang.org/x/net
golang.org/x/sync => /usr/share/gocode/src/golang.org/x/sync
golang.org/x/xerrors => /usr/share/gocode/src/golang.org/x/xerrors
golang.org/x/crypto => /usr/share/gocode/src/golang.org/x/crypto
golang.org/x/term => /usr/share/gocode/src/golang.org/x/term
//replace-this
)

TA貢獻(xiàn)1818條經(jīng)驗 獲得超7個贊
將 Go 指向系統(tǒng)范圍的可用依賴項的另一種方法是利用 Go 的模塊供應(yīng)商支持:這意味著通過符號化地鏈接模塊文件路徑,創(chuàng)建最小值并使用 進(jìn)行編譯。vendor/modules.txt-mod vendor
因此,使用Go構(gòu)建不會嘗試下載任何所需的模塊,而是在目錄中查找它們。-mod vendorvendor/
人們可能試圖創(chuàng)建一個指向的符號鏈接(所有分發(fā)包都安裝在那里),但這不起作用,因為還需要另一個模塊描述文件,即.vendor//usr/share/gocode/srcgolang-...-devel-mod vendorvendor/modules.txt
因此,除了一些更具體的符號鏈接之外,我們在使用供應(yīng)商功能時還必須創(chuàng)建一個適當(dāng)?shù)姆栨溄樱簃odules.txt
首先,創(chuàng)建所有子級別符號鏈接:
awk -vvd=wendor 'BEGIN {
PROCINFO["sorted_in"]="@ind_str_asc";
system("mkdir -p "vd)
}
func push_mod(pkg) {
if (!seen[pkg]) {
ARGV[ARGC++]="/usr/share/gocode/src/"pkg"/go.mod";
seen[pkg]=1;
}
sub("/.+$", "", pkg);
xs[pkg]=1;
}
/^require[^(]+$/ {
push_mod($2);
next
}
/^require/ {
inb=1;
next
}
/^\)/ {
inb=0;
next
}
inb {
push_mod($1);
}
END {
for (i in xs) {
print i;
system("ln -sfn /usr/share/gocode/src/"i" "vd"/"i)
}
}' go.mod
然后,要創(chuàng)建:vendor/modules.txt
awk -vvd=wendor 'BEGIN {
fn=vd"/modules.txt"
}
/^require/ {
inb=1;
next
}
/^\)/ {
inb=0;
next
}
inb {
printf("# %s %s\n## explicit\n%s\n", $1, $2, $1) > fn
}' go.mod
在這些命令之后,對于我們的示例項目,供應(yīng)商目錄如下所示:
$ ls -l vendor
total 16
lrwxrwxrwx. 1 juser juser 32 2021-04-25 11:12 github.com -> /usr/share/gocode/src/github.com
lrwxrwxrwx. 1 juser juser 32 2021-04-25 11:12 go.etcd.io -> /usr/share/gocode/src/go.etcd.io
lrwxrwxrwx. 1 juser juser 32 2021-04-25 11:12 golang.org -> /usr/share/gocode/src/golang.org
-rw-r--r--. 1 juser juser 195 2021-04-25 11:13 modules.txt
$ cat vendor/modules.txt
# go.etcd.io/bbolt v1.3.5
## explicit
go.etcd.io/bbolt
# golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7
## explicit
golang.org/x/sys
# golang.org/x/text v0.3.5
## explicit
golang.org/x/text
而 是相當(dāng)小的,即它不包含任何替換指令:go.mod
module github.com/gsauthof/gonzofilter
go 1.15
require (
go.etcd.io/bbolt v1.3.5
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7
golang.org/x/text v0.3.5
)
這足以讓
GOPROXY=off go build -mod vendor
成功。
請注意,間接依賴項(如)未在 中列出,但是,它們?nèi)匀豢梢酝ㄟ^,因為我們在創(chuàng)建指向頂級目錄的符號鏈接時,以傳遞方式遍歷了從所需模塊開始的所有文件。golang.org/x/toolsmodules.txtvendor/go.mod
此方案的離散魅力在于不必弄亂文件中的指令。這意味著可以保持相當(dāng)通用,基本上只需要將開關(guān)添加到構(gòu)建命令中即可。replacego.modgo.mod-mod vendor
- 4 回答
- 0 關(guān)注
- 194 瀏覽
添加回答
舉報