亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

遷移到 Go 模塊,同時繼續使用分發包

遷移到 Go 模塊,同時繼續使用分發包

Go
蠱毒傳說 2022-08-24 18:55:45
我有一個基于GOPATH的項目,我目前在Fedora上構建如下:sudo dnf install golang-etcd-bbolt-devel golang-x-sys-devel golang-x-text-devel GOPATH=$HOME/go:/usr/share/gocode go build我的項目(gonzofilter)實現了一個命令行實用程序,因此源文件位于主包中(即它們具有聲明)。package main在 Fedora 34 及更高版本中,Go 似乎刪除了對構建 GOPATH 樣式項目的支持,人們真的必須使用 Go 模塊:go build go: cannot find main module; see 'go help modules'那篇Go博客文章涵蓋了我的情況(->“沒有依賴管理器”),但它沒有明確提到如何處理主包項目或分發提供的依賴關系。那么,如何遷移這樣的項目呢?我如何告訴Go/在?go mod tidy/usr/share/gocode編輯:確切地說:Fedora 34 附帶了 Go 1.16,它“剛剛”將默認值從 更改為 .因此,仍然可以通過設置來恢復舊行為。GO111MODULEautoonGO111MODULE=auto但是,Golang開發人員已經宣布他們希望放棄對Gopath樣式項目的Gopath 1.17的支持:我們計劃在 Go 1.17 中放棄對 GOPATH 模式的支持。換句話說,Go 1.17 將忽略 GO111MODULE。如果您的項目未在模塊感知模式下生成,那么現在是時候遷移了。
查看完整描述

4 回答

?
天涯盡頭無女友

TA貢獻1831條經驗 獲得超9個贊

理想情況下,發行版應將已安裝的依賴項打包在與 GOPROXY 協議兼容的布局中。然后,您將能夠進行適當的設置并運行以使用已安裝的依賴項。GOPROXYgo mod tidy

但是,據我所知,在這一點上,沒有發行版實際上提供了一棵樹。您可能需要一個解決方法。GOPROXY


下一個最好的選擇是使用指令自己連接替換件。 已經知道更喜歡指令中的版本而不是其他版本,所以做這樣的事情就足夠了:replacego mod tidyreplace

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

但是,請注意,該指令要求目標包含顯式文件,因此,僅當依賴項已具有顯式文件或發行版打包程序已將它們添加為修補程序以支持此用例時,此操作才有效。replacego.modgo.mod


請注意,有了這些指令,您的構建將不會隨著時間的推移而重現可重復:如果您更改依賴項的發行版安裝版本,那么的含義將靜默地更改為使用這些不同的(并且可能不兼容?。┌姹?。replacego build

因此,我建議您不要這樣做,而是使用和/或從上游或公共模塊代理(例如)獲取所需的特定模塊版本。go getgo mod tidyproxy.golang.org

如果您擔心上游篡改,請注意,默認情況下,Go項目的官方二進制命令分發 - 以及從原始源代碼構建的命令 - 會自動根據 https://sum.golang.org 的可審計公共數據庫驗證已下載模塊的校驗和;但是,默認情況下,該命令的 Fedora 發行版禁止使用校驗和數據庫。gogogo


查看完整回答
反對 回復 2022-08-24
?
慕姐4208626

TA貢獻1852條經驗 獲得超7個贊

您可以在生成的 mod 文件中使用 replace 關鍵字顯式定義,以引用本地模塊。

replace packagename => /usr/share/gcode


查看完整回答
反對 回復 2022-08-24
?
慕沐林林

TA貢獻2016條經驗 獲得超9個贊

將這樣的 GOPATH 項目遷移到感知 Go 模塊的一種方法是:


首先,使用直接依賴項手動創建 :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

)

我從我的系統上當前的內容中獲得了最低版本:


$ 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

現在的問題是,人們不能簡單地告訴模塊感知的Go工具在它們所在的文件系統路徑下查找這些模塊。/usr/share/gocode/src


有一個指令可以添加到我們的文件中,以設置單個依賴項的查找路徑,例如: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


因此,這將失敗:


$ GOPROXY=off go build -mod=readonly

go: golang.org/x/[email protected] requires

    golang.org/x/[email protected]: module lookup disabled

       by GOPROXY=off

為了解決這個問題,我們必須為所有間接依賴項添加替換指令行。


當然,手動執行此操作既繁瑣又容易出錯。


因此,我們可以使用一個小的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

)

然后,以下固定點迭代添加依賴項,直到構建成功:


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

這導致此示例項目的以下 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

)


查看完整回答
反對 回復 2022-08-24
?
qq_笑_17

TA貢獻1818條經驗 獲得超7個贊

將 Go 指向系統范圍的可用依賴項的另一種方法是利用 Go 的模塊供應商支持:這意味著通過符號化地鏈接模塊文件路徑,創建最小值并使用 進行編譯。vendor/modules.txt-mod vendor


因此,使用Go構建不會嘗試下載任何所需的模塊,而是在目錄中查找它們。-mod vendorvendor/


人們可能試圖創建一個指向的符號鏈接(所有分發包都安裝在那里),但這不起作用,因為還需要另一個模塊描述文件,即.vendor//usr/share/gocode/srcgolang-...-devel-mod vendorvendor/modules.txt


因此,除了一些更具體的符號鏈接之外,我們在使用供應商功能時還必須創建一個適當的符號鏈接:modules.txt


首先,創建所有子級別符號鏈接:


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

然后,要創建: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

在這些命令之后,對于我們的示例項目,供應商目錄如下所示:


$ 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

而 是相當小的,即它不包含任何替換指令: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

成功。


請注意,間接依賴項(如)未在 中列出,但是,它們仍然可以通過,因為我們在創建指向頂級目錄的符號鏈接時,以傳遞方式遍歷了從所需模塊開始的所有文件。golang.org/x/toolsmodules.txtvendor/go.mod


此方案的離散魅力在于不必弄亂文件中的指令。這意味著可以保持相當通用,基本上只需要將開關添加到構建命令中即可。replacego.modgo.mod-mod vendor


查看完整回答
反對 回復 2022-08-24
  • 4 回答
  • 0 關注
  • 200 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號