使用 "go list" 如何仅列出二进制文件中使用的 Go 模块?
With "go list" how to list only Go modules used in the binary?
我想列出在最终可执行文件(而不是其他依赖项)中编译的模块(及其版本)。
我可以这样做:
$ go build -o a.out
$ go version -m a.out
但是我怎样才能使用 go list
(它有一个方便的 JSON 输出)呢?
我试过这个:
$ go list -m -f '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}' all
但是它列出了许多仅在测试套件中使用的传递依赖项。
我不知道如何过滤掉这些依赖项。
这里有一个示例工程可以看到问题(可用on The Go Playground):
main.go
:
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
main_test.go
:
package main
import (
"github.com/google/go-cmp/cmp"
"testing"
)
func TestHelloWorld(t *testing.T) {
if !cmp.Equal(1, 1) {
t.Fatal("FAIL")
}
}
go.mod
:
module play.ground
go 1.15
require github.com/google/go-cmp v0.5.2
$ go build -o hello ; go version -m hello
hello: go1.15
path play.ground
mod play.ground (devel)
$ go list -m -f '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}' all
github.com/google/go-cmp@v0.5.2
golang.org/x/xerrors@v0.0.0-20191204190536-9bdfabe68543
答案如下:
go list -deps -f '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}' | sort -u
注意:go list -deps
为每个包裹生成一行。因此,多次列出从中导入多个包的模块。 sort -u
排序并删除重复项。
可以与:
进行比较
go version -m hello | perl -ne 's/^\tdep\t([^\t]*)\t([^\t]*).*$/\@/ && print' | sort
这是一个包含更多详细信息的版本,其中列出了每个模块引用的每个包(也使用 jq
:
go list -deps -f '{{define "mod"}}{{.Path}}@{{.Version}}{{end}}{{if .Module}}{{if not .Module.Main}}{{if .Module.Replace}}{{template "mod" .Module.Replace}}{{else}}{{template "mod" .Module}}{{end}}{{"\t"}}{{.ImportPath}}{{end}}{{end}}' | sort
go list -deps -json | jq -r 'select(.Module and (.Module.Main | not)) | .Module.Path + "@" + .Module.Version + "\t" + .ImportPath' | sort
我想列出在最终可执行文件(而不是其他依赖项)中编译的模块(及其版本)。
我可以这样做:
$ go build -o a.out
$ go version -m a.out
但是我怎样才能使用 go list
(它有一个方便的 JSON 输出)呢?
我试过这个:
$ go list -m -f '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}' all
但是它列出了许多仅在测试套件中使用的传递依赖项。 我不知道如何过滤掉这些依赖项。
这里有一个示例工程可以看到问题(可用on The Go Playground):
main.go
:
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
main_test.go
:
package main
import (
"github.com/google/go-cmp/cmp"
"testing"
)
func TestHelloWorld(t *testing.T) {
if !cmp.Equal(1, 1) {
t.Fatal("FAIL")
}
}
go.mod
:
module play.ground
go 1.15
require github.com/google/go-cmp v0.5.2
$ go build -o hello ; go version -m hello
hello: go1.15
path play.ground
mod play.ground (devel)
$ go list -m -f '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}' all
github.com/google/go-cmp@v0.5.2
golang.org/x/xerrors@v0.0.0-20191204190536-9bdfabe68543
答案如下:
go list -deps -f '{{define "M"}}{{.Path}}@{{.Version}}{{end}}{{with .Module}}{{if not .Main}}{{if .Replace}}{{template "M" .Replace}}{{else}}{{template "M" .}}{{end}}{{end}}{{end}}' | sort -u
注意:go list -deps
为每个包裹生成一行。因此,多次列出从中导入多个包的模块。 sort -u
排序并删除重复项。
可以与:
进行比较go version -m hello | perl -ne 's/^\tdep\t([^\t]*)\t([^\t]*).*$/\@/ && print' | sort
这是一个包含更多详细信息的版本,其中列出了每个模块引用的每个包(也使用 jq
:
go list -deps -f '{{define "mod"}}{{.Path}}@{{.Version}}{{end}}{{if .Module}}{{if not .Module.Main}}{{if .Module.Replace}}{{template "mod" .Module.Replace}}{{else}}{{template "mod" .Module}}{{end}}{{"\t"}}{{.ImportPath}}{{end}}{{end}}' | sort
go list -deps -json | jq -r 'select(.Module and (.Module.Main | not)) | .Module.Path + "@" + .Module.Version + "\t" + .ImportPath' | sort