#go #go-modules #go-toolchain
#Вперед #go-модули #go-toolchain
Вопрос:
Я хочу перечислить модули (и их версии), которые скомпилированы в конечном исполняемом файле (а не в других зависимостях).
Я могу сделать это с:
$ 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
Но в нем перечислены многие транзитивные зависимости, которые, например, используются только в наборах тестов.
Я не понимаю, как я мог бы отфильтровать эти зависимости.
Вот пример проекта, чтобы увидеть проблему (доступен на 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
Комментарии:
1. Что вы подразумеваете под «а не другими зависимостями»?
2. Но вы, вероятно, хотите
Module
, чтобы поле пакета было задокументировано .3. Как подробно описано в отмеченном дубликате, шаблон
{{if not .Indirect}}{{.}}{{end}}
включает только прямые зависимости.4. @icza
.Indirect
не исключает модули, которые используются в тестах. В моем примереgithub.com/google/go-cmp@v0.5.2
указан вgo list
, но не используется в двоичном файле.5. @dolmen Это соответствует вашим потребностям?
go list -deps -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}'
Ответ №1:
Вот ответ:
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/^tdept([^t]*)t([^t]*).*$/$1@$2/ amp;amp; 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