Я использую конвейер GitHub, который (помимо других тестов) гарантирует правильное форматирование кода. Я делаю это, запуская go fmt ./... в своем исходном коде, а затем проверяя, что это ничего не меняет с помощью git diff -q. Кроме того, я запускаю конвейер, используя разные версии Go (от 1.20 до 1.22), чтобы обеспечить совместимость. Пожалуйста, учтите, что я могу неправильно понять содержание файла go.mod и не использую его должным образом для выражения своих намерений.
В любом случае, раньше проверка формата работала нормально, но сейчас у меня с ней проблемы. Я не могу заставить это работать, не вызывая нежелательных изменений в go.mod. Помимо реальных зависимостей, у меня есть это в go.mod:
module my-module
go 1.20
require (
....
)
Я намерен с помощью go 1.20 отметить это как совместимое с версией 1.20. Если я запускаю go fmt ./... с Go 1.22, он терпит неудачу и говорит мне сначала запустить go mod tidy. При этом go.mod изменится на это:
module my-module
go 1.22
toolchain go1.22.4
require (
....
)
Это противоречит моим намерениям, потому что Go 1.20 не распознает toolchain и тогда терпит неудачу.
go в go.mod правильным способом сказать, что модуль совместим с этой версией Go?go fmt с разными версиями, как описано выше?go mod tidy или go get в Go 1.22 ошибкой? В конце концов, он активно игнорирует директиву go 1.20 и нарушает код старых версий.В качестве обходного пути я мог бы исключить изменения go.mod из своих проверок в конвейере. ИМХО, это не правильное решение, а скорее хак. В любом случае, у меня такое ощущение, что я еще не до конца понимаю инфраструктуру управления зависимостями Go, поэтому, если вы думаете, что я этого не понимаю, подтолкните меня в правильном направлении! :)
go-version-test.go mod init go-version-test, используя Go 1.20.main.go, как показано ниже.go get -u -v, используя Go 1.20.go mod tidy -go=1.20, используя Go 1.22.Содержание main.go:
package main
import (
"go.mongodb.org/mongo-driver/mongo"
)
func main() {
// Note: This won't compile, but that doesn't matter!
_, _ := mongo.Connect(ctx, opts)
}
Последняя команда выдаст ошибку:
go: github.com/youmark/[email protected] requires [email protected], but 1.20 is requested
Насколько я понимаю, пакет драйверов MongoDB включает пакет pkcs8. Оба хорошо работают с Go 1.20, но в файле go 1.22 пакета pkcs8 есть директива go.mod. Другие уже тоже сообщили об этом как о проблеме.
Это может произойти, если вы зафиксируете go.mod, который не синхронизирован с вашим кодом. Правильный способ исправить это — выполнить локальную модификацию перед фиксацией. Также может быть, что ваш код несовместим с версией 1.20, и в этом случае утверждение «это» не работает. На вопросы: 1. Да. 2. NA, 3 вероятно Нет.
Если go mod tidy перезаписывает go.mod с использованием новой версии, в коде есть что-то, вызывающее изменение этой версии. Однако мы не можем сказать, что это может быть, без минимально воспроизводимого примера. Я предполагаю, что вам действительно требуется go1.22, но набор инструментов go1.20, очевидно, не может обновиться до этого и строит код с максимальной отдачей, пока он не сталкивается с функциями, которые он не может использовать. ручка. Вы не можете использовать разные версии набора инструментов, не столкнувшись с проблемами совместимости, поэтому была введена директива toolchain.

Это изменение , появившееся в go 1.21 :
Я предполагаю, что у вас есть какой-то модуль, требующий версии 1.22. Он может работать, а может и не работать с go 1.20, но, например, имейте в виду эксперимент с циклической переменной — программы, написанные для go 1.22, могут скомпилироваться с go 1.20, но работать неправильно.
Чтобы найти зависимость, требующую Go 1.22, вы можете запустить go mod tidy -go=1.20, используя Go 1.22. Это выдаст вам ошибку в форме go: some/dependent/package requires [email protected], but 1.20 is requested.
Он говорит
go: updates to go.mod needed, disabled by -mod=readonly; to update it: go mod tidyи терпит неудачу.