воскресенье, 28 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go mod verify

Использование:

go mod verify

go mod verify проверяет, что зависимости основного модуля, хранящиеся в кеше модуля, не были изменены с момента их загрузки. Чтобы выполнить эту проверку, go mod verify хеширует каждый загруженный .zip файл модуля и извлеченного каталога, затем сравнивает эти хеши с хешем, записанным при первой загрузке модуля. go mod verify проверяет каждый модуль в списке сборки (который можно распечатать с помощью go list -m all).

Если все модули не изменены, go mod verify распечатывает "all modules verified" ("все модули проверены"). В противном случае он сообщает, какие модули были изменены, и выходит с ненулевым статусом.

Обратите внимание, что все команды, поддерживающие модули, проверяют, соответствуют ли хеши в файле go.sum основного модуля хешам, записанным для модулей, загруженных в кеш модуля. Если хеш отсутствует в go.sum (например, потому что модуль используется впервые), команда go проверяет его хеш, используя базу данных контрольных сумм (если путь модуля не совпадает с GOPRIVATE или GONOSUMDB).

Напротив, go mod verify проверяет, что .zip файлы модуля и их извлеченные каталоги имеют хеши, соответствующие хешам, записанным в кеш модуля при их первой загрузке. Это полезно для обнаружения изменений файлов в кеше модуля после того, как модуль был загружен и проверен. go mod verify не загружает содержимое для модулей, не находящихся в кеше, и не использует файлы go.sum для проверки содержимого модуля. Однако программа go mod verify может загрузить файлы go.mod, чтобы выбрать минимальную версию. Он будет использовать go.sum для проверки этих файлов и может добавлять записи go.sum для недостающих хешей.


Читайте также:


Модули в Golang: команды с поддержкой модулей, go mod vendor

Использование:

go mod vendor [-e] [-v]

Команда go mod vendor создает каталог с именем vendor в корневом каталоге основного модуля, который содержит копии всех пакетов, необходимых для поддержки сборки и тестирования пакетов в основном модуле. Пакеты, которые импортируются только тестами пакетов вне основного модуля, не включаются. Как и в случае с go mod tidy и другими командами модуля, ограничения сборки, за исключением игнорирования, не учитываются при создании каталога vendor.

Когда вендоринг включен, команда go будет загружать пакеты из каталога vendor вместо того, чтобы загружать модули из их источников в кеш модулей и использовать пакеты, которые были загружены копиями.

go mod vendor также создает файл vendor/modules.txt, содержащий список поставленных пакетов и версий модулей, из которых они были скопированы. Когда вендоринг включен, этот манифест используется в качестве источника информации о версии модуля, о чем сообщает go list -m и go version -m. Когда команда go читает vendor/modules.txt, она проверяет, соответствуют ли версии модуля go.mod. Если go.mod изменился с момента создания vendor/modules.txt, необходимо снова запустить go.mod vendor.

Обратите внимание, что go mod vendor удаляет каталог vendor, если он существует, перед его повторным построением. Не следует вносить локальные изменения в поставленные пакеты. Команда go не проверяет, что пакеты в каталоге vendor не были изменены, но можно проверить целостность каталога vendor, запустив go mod vendor и проверив, что никаких изменений не было.

Флаг -e (добавлен в Go 1.16) заставляет go mod vendor попытаться продолжить, несмотря на ошибки, обнаруженные при загрузке пакетов.

Флаг -v заставляет go mod vendor печатать имена поставленных модулей и пакетов в стандартную ошибку.


Читайте также:


суббота, 27 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go mod tidy

Использование:

go mod tidy [-e] [-v]

go mod tidy удостоверяется, что файл go.mod соответствует исходному коду модуля. Он добавляет любые отсутствующие требования к модулям, необходимые для сборки пакетов и зависимостей текущего модуля, и удаляет требования к модулям, которые не предоставляют никаких соответствующих пакетов. Он также добавляет все недостающие записи в go.sum и удаляет ненужные записи.

Флаг -e (добавлен в Go 1.16) заставляет go mod tidy попытаться продолжить работу, несмотря на ошибки, обнаруженные при загрузке пакетов.

Флаг -v заставляет go mod tidy выводить информацию об удаленных модулях в стандартную ошибку.

go mod tidy работает, рекурсивно загружая все пакеты в основной модуль и все пакеты, которые они импортируют. Сюда входят пакеты, импортированные тестами (включая тесты в других модулях). go mod tidy действует так, как будто все теги сборки включены, поэтому он будет учитывать исходные файлы для конкретной платформы и файлы, требующие настраиваемых тегов сборки, даже если эти исходные файлы обычно не собираются. Есть одно исключение: тег сборки ignore не включен, поэтому файл с ограничением сборки // +build ignore не будет рассматриваться. Обратите внимание, что go mod tidy не будет рассматривать пакеты в основном модуле в каталогах с именем testdata или с именами, начинающимися с . или _, если эти пакеты явно не импортированы другими пакетами.

После того, как go mod tidy загрузит этот набор пакетов, он удостоверяется, что каждый модуль, который предоставляет один или несколько пакетов, либо имеет директиву require в файле go.mod основного модуля, либо требуется для другого необходимого модуля. go mod tidy добавит требование о последней версии для каждого отсутствующего модуля. go mod tidy удалит директивы require для модулей, которые не предоставляют никаких пакетов в описанном выше наборе.

go mod tidy может также добавлять или удалять // indirect комментарии к директивам require. // indirect комментарий обозначает модуль, который не предоставляет пакеты, импортированные пакетами в основном модуле. Эти требования будут присутствовать, если модуль, импортирующий пакеты в косвенной зависимости, не имеет файла go.mod. Они также могут присутствовать, если косвенная зависимость требуется в более высокой версии, чем подразумевается графом модуля; обычно это происходит после выполнения такой команды, как go get -u ./... .


Читайте также:


Модули в Golang: команды с поддержкой модулей, go mod init

Использование:

go mod init [module-path]

Пример:

go mod init
go mod init example.com/m

Команда go mod init инициализирует и записывает новый файл go.mod в текущий каталог, фактически создавая новый модуль с корнем в текущем каталоге. Файл go.mod еще не должен существовать.

init принимает один необязательный аргумент - путь к новому модулю. Если аргумент пути к модулю опущен, init попытается вывести путь к модулю, используя комментарии импорта в файлах .go, файлы конфигурации инструмента поставщика (vendoring tool) и текущий каталог (если в GOPATH).

Если присутствует файл конфигурации для инструмента поставщика (vendoring tool), init попытается импортировать из него требования к модулю. init поддерживает следующие файлы конфигурации.

GLOCKFILE (Glock)
Godeps/Godeps.json (Godeps)
Gopkg.lock (dep)
dependencies.tsv (godeps)
glide.lock (glide)
vendor.conf (trash)
vendor.yml (govend)
vendor/manifest (gvt)
vendor/vendor.json (govendor)

Файлы конфигурации инструмента поставщика (vendoring tool) не всегда могут быть переведены с идеальной точностью. Например, если несколько пакетов в одном репозитории импортируются в разных версиях, а репозиторий содержит только один модуль, для импортированного go.mod может потребоваться только модуль одной версии. Вы можете запустить go list -m all, чтобы проверить все версии в списке сборки, и перейти к модификациям, чтобы добавить недостающие требования и отбросить неиспользуемые требования.


Читайте также:


пятница, 26 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go mod graph

Использование:

go mod graph

Команда go mod graph печатает граф требований модуля (с примененными заменами) в текстовой форме. Например:

example.com/main example.com/a@v1.1.0
example.com/main example.com/b@v1.2.0
example.com/a@v1.1.0 example.com/b@v1.1.1
example.com/a@v1.1.0 example.com/c@v1.3.0
example.com/b@v1.1.0 example.com/c@v1.1.0
example.com/b@v1.2.0 example.com/c@v1.2.0

Каждая вершина в графе модулей представляет определенную версию модуля. Каждое ребро в графе представляет собой требование минимальной версии зависимости.

go mod graph печатает ребра графа, по одному в строке. В каждой строке есть два поля, разделенных пробелами: версия модуля и одна из его зависимостей. Каждая версия модуля идентифицируется как строка вида path@version. У основного (main) модуля нет суффикса @version, так как у него нет версии.


Читайте также:


четверг, 25 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go mod edit

Использование:

go mod edit [editing flags] [-fmt|-print|-json] [go.mod]

Пример:

# Добавить директиву replace.
$ go mod edit -replace example.com/a@v1.0.0=./a

# Удалить директиву replace.
$ go mod edit -dropreplace example.com/a@v1.0.0

# Установить версию go, добавить требование и распечатать файл
# вместо записи на диск.
$ go mod edit -go=1.14 -require=example.com/m@v1.0.0 -print

# Отформатировать файл go.mod.
$ go mod edit -fmt

# Отформатировать и распечатать другой файл .mod.
$ go mod edit -print tools.mod

# Распечатать JSON-представление файла go.mod.
$ go mod edit -json

Команда go mod edit предоставляет интерфейс командной строки для редактирования и форматирования файлов go.mod для использования в основном инструментами и скриптами. go mod edit читает только один файл go.mod; он не ищет информацию о других модулях. По умолчанию go mod edit читает и записывает файл go.mod основного модуля, но после флагов редактирования можно указать другой целевой файл.

Флаги редактирования определяют последовательность операций редактирования.

  • Флаг -module изменяет путь к модулю (строка module файла go.mod).
  • Флаг -go=version устанавливает ожидаемую языковую версию Go.
  • Флаги -require=path@version и -droprequire=path добавляют и удаляют требование для указанного пути и версии модуля. Обратите внимание, что -require отменяет все существующие требования к пути. Эти флаги в основном предназначены для инструментов, которые понимают граф модуля. Пользователи должны предпочесть go get path@version или go get path@none, которые вносят другие корректировки go.mod по мере необходимости, чтобы удовлетворить ограничения, налагаемые другими модулями.
  • Флаги -exclude=path@version и -dropexclude=path@version добавляют и удаляют исключение для данного пути и версии модуля. Обратите внимание, что -exclude=path@version нельзя использовать, если это исключение уже существует.
  • Флаг -replace=old[@v]=new[@v] добавляет замену данной пары пути и версии модуля. Если @v в old@v опущен, добавляется замена без версии в левой части, которая применяется ко всем версиям старого пути к модулю. Если @v в new@v опущен, новый путь должен быть корневым каталогом локального модуля, а не путем к модулю. Обратите внимание, что -replace отменяет любые избыточные замены для old[@v], поэтому отсутствие @v приведет к удалению замен для определенных версий.
  • Флаг -dropreplace=old[@v] отменяет замену указанной пары пути и версии модуля. Если указан @v, замена данной версией отбрасывается. Существующая замена без версии с левой стороны может заменить модуль. Если @v опущен, замена без версии отбрасывается.
  • Флаги -retract=version и -dropretract=version добавляют и удаляют отзыв (retraction) для данной версии, который может быть отдельной версией (например, v1.2.3) или интервалом (например, [v1.1.0, v1.2.0]). Обратите внимание, что флаг -retract не может добавлять поясняющий комментарий для директивы retract. Рекомендуются пояснительные комментарии, которые можно показать с помощью go list -m -u и других команд.

Флаги редактирования могут повторяться. Изменения применяются в указанном порядке.

go mod edit имеет дополнительные флаги, управляющие его выводом.

  • Флаг -fmt переформатирует файл go.mod без внесения других изменений. Это переформатирование также подразумевается любыми другими модификациями, в которых используется или переписывается файл go.mod. Единственный раз, когда этот флаг необходим, если не указаны другие флаги, как в go mod edit -fmt.
  • Флаг -print печатает окончательный файл go.mod в его текстовом формате вместо того, чтобы записывать его обратно на диск.
  • Флаг -json печатает окончательный файл go.mod в формате JSON вместо того, чтобы записывать его обратно на диск в текстовом формате. Вывод JSON соответствует этим типам Go:

type Module struct {
        Path    string
        Version string
}

type GoMod struct {
        Module  Module
        Go      string
        Require []Require
        Exclude []Module
        Replace []Replace
}

type Require struct {
        Path     string
        Version  string
        Indirect bool
}

type Replace struct {
        Old Module
        New Module
}

type Retract struct {
        Low       string
        High      string
        Rationale string
}

Обратите внимание, что это описывает только сам файл go.mod, а не другие модули, на которые косвенно ссылаются. Чтобы получить полный набор модулей, доступных для сборки, используйте go list -m -json all.

Например, инструмент может получить файл go.mod как структуру данных, проанализировав вывод команды go mod edit -json, а затем может внести изменения, вызвав команду go mod edit с -require, -exclude и т. д.

Инструменты также могут использовать пакет golang.org/x/mod/modfile для анализа, редактирования и форматирования файлов go.mod.


Читайте также:


вторник, 23 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go install

Использование:

go install [build flags] [packages]

Примеры:

# Установить последнюю версию программы,
# игнорируя go.mod в текущем каталоге (если есть).
$ go install golang.org/x/tools/gopls@latest

# Установить определенную версию программы.
$ go install golang.org/x/tools/gopls@v0.6.4

# Установить программу в версии, 
# выбранной модулем в текущем каталоге.
$ go install golang.org/x/tools/gopls

# Установить все программы в каталог.
$ go install ./cmd/...

Команда go install собирает и устанавливает пакеты, имена которых указаны путями в командной строке. Исполняемые файлы (основные пакеты (main packages)) устанавливаются в каталог, названный переменной среды GOBIN, которая по умолчанию имеет значение $GOPATH/bin или $HOME/go/bin, если переменная среды GOPATH не установлена. Исполняемые файлы в $GOROOT устанавливаются в $GOROOT/bin или $GOTOOLDIR вместо $GOBIN.

Начиная с Go 1.16, если аргументы имеют суффиксы версии (например, @latest или @v1.0.0), go install создает пакеты в режиме с поддержкой модулей, игнорируя файл go.mod в текущем каталоге или любом родительском каталоге, если он есть. Это полезно для установки исполняемых файлов, не влияя на зависимости основного модуля.

Чтобы устранить двусмысленность в отношении того, версии чьего модуля используются в сборке, аргументы должны удовлетворять следующим ограничениям:

  • Аргументы должны быть путями пакетов или шаблонами пакетов (с подстановочными знаками "..."). Это не должны быть стандартные пакеты (например, fmt), мета-шаблоны (std, cmd, all) или относительные или абсолютные пути к файлам.
  • Все аргументы должны иметь один и тот же суффикс версии. Запрещены разные запросы, даже если они относятся к одной и той же версии.
  • Все аргументы должны относиться к пакетам в одном модуле одной версии.
  • Ни один модуль не считается основным. Если модуль, содержащий пакеты, названные в командной строке, имеет файл go.mod, он не должен содержать директив (replace и exclude), которые заставили бы его интерпретировать иначе, чем если бы это был основной модуль. Модуль не должен требовать более высокую версию самого себя.
  • Аргументы пути к пакету должны относиться к основным (main) пакетам. Аргументы шаблона будут соответствовать только основным пакетам.

Go 1.15 и ниже не поддерживают использование запросов версии с go install.

Если аргументы не имеют суффиксов версии, go install может выполняться в режиме с поддержкой модулей или в режиме GOPATH, в зависимости от переменной среды GO111MODULE и наличия файла go.mod. Если включен режим с поддержкой модулей, go install запускается в контексте основного модуля, который может отличаться от модуля, содержащего устанавливаемый пакет.


Читайте также:


понедельник, 22 февраля 2021 г.

Модули в Golang: файл go.mod, директива retract

Директива retract указывает версию или диапазон версий модуля, определенных go.mod, от которых не следует зависеть. Директива retract полезна, когда версия была опубликована преждевременно или после публикации версии была обнаружена серьезная проблема. Отозванные (Retracted) версии должны оставаться доступными в репозиториях системы контроля версий и на прокси-серверах модулей, чтобы гарантировать, что сборки, зависящие от них, не будут повреждены. Слово retract заимствовано из академической литературы: отозванная (retracted) исследовательская статья все еще доступна, но она имеет проблемы и не должна быть основой для будущей работы.

Когда версия модуля отозвана, пользователи не будут обновляться до нее автоматически с помощью go get, go mod tidy или других команд. Сборки, зависящие от отозванных версий, должны продолжать работать, но пользователи будут уведомлены об отзывах (retractions), когда они проверят наличие обновлений с помощью go list -m -u или обновят связанный модуль с помощью go get.

Чтобы отозвать версию, автор модуля должен добавить директиву retract в go.mod, а затем опубликовать новую версию, содержащую эту директиву. Новая версия должна быть выше, чем другие релизные или предварительные версии; то есть, запрос @latest версии должен разрешить новую версию до рассмотрения отзыва. Команда go загружает и применяет отзывы из версии, показанной go list -m -retracted $modpath@latest (где $modpath - это путь к модулю).

Отозванные версии скрываются из списка версий, выводимого командой go list -m -versions, если не используется флаг -retracted. Отозванные версии исключаются при разрешении запросов о версиях, таких как @>=v1.2.3 или @latest.

Версия, содержащая отзывы, может отозваться сама. Если самый высокий релиз или предварительная версия модуля удаляется, запрос @latest преобразуется в более низкую версию после исключения отозванных версий.

В качестве примера рассмотрим случай, когда автор модуля example.com/m случайно публикует версию v1.0.0. Чтобы предотвратить обновление пользователей до версии 1.0.0, автор может добавить две директивы retract в go.mod, а затем пометить версию 1.0.1 отзывами.

retract (
    v1.0.0 // Опубликовано случайно.
    v1.0.1 // Содержит только отзывы.
)

Когда пользователь запускает go get example.com/m@latest, команда go считывает отзывы из v1.0.1, которая теперь является самой высокой версией. И v1.0.0, и v1.0.1 отозваны, поэтому команда go обновит (или откатит!) до следующей высшей версии, возможно, v0.9.5.

Директивы retract могут быть написаны либо с одной версией (например, v1.0.0), либо с закрытым интервалом версий с верхней и нижней границами, разделенными символом [ и символом ] (например, [v1.1.0, v1.2.0]). Единая версия эквивалентна интервалу, в котором верхняя и нижняя границы совпадают. Как и другие директивы, несколько директив retract могут быть сгруппированы в блок, разделенный символом ( в конце строки и символом ) на отдельной строке.

В каждой директиве retract должен быть комментарий, объясняющий причину отзыва, хотя это не обязательно. Команда go может отображать комментарии с обоснованием в предупреждениях об отозванных версиях и в выводе go list. Обосновывающий комментарий может быть написан непосредственно над директивой retract (без пустой строки между ними) или после в той же строке. Если комментарий появляется над блоком, он применяется ко всем директивам retract внутри блока, у которых нет собственных комментариев. Комментарий-обоснование может занимать несколько строк.

RetractDirective = "retract" ( RetractSpec | "(" newline { RetractSpec } ")" ) .
RetractSpec = ( Version | "[" Version "," Version "]" ) newline .

Пример:

retract v1.0.0
retract [v1.0.0, v1.9.9]
retract (
    v1.0.0
    [v1.0.0, v1.9.9]
)

Директива retract была добавлена в Go 1.16. Go 1.15 и ниже будет сообщать об ошибке, если директива retract записана в файле go.mod главного модуля, и игнорирует директивы retract в файлах go.mod зависимостей.

Пример использования rectract - https://github.com/A1esandr/retract


Читайте также:


воскресенье, 21 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go mod download

Использование:

go mod download [-json] [-x] [modules]

Пример:

$ go mod download
$ go mod download golang.org/x/mod@v0.2.0

Команда go mod download загружает названные модули в кеш модулей. Аргументами могут быть пути к модулям или шаблоны модулей, выбирающие зависимости основного модуля, или запросы версии формы path@version. Без аргументов загрузка применяется ко всем зависимостям основного модуля.

Команда go автоматически загрузит модули по мере необходимости во время обычного выполнения. Команда go mod download полезна в основном для предварительного заполнения кеша модуля или для загрузки данных, которые будут обслуживаться прокси модуля.

По умолчанию download ничего не записывает в стандартный вывод. Он выводит сообщения о ходе выполнения и ошибки в стандартный вывод ошибок.

Флаг -json заставляет download распечатать последовательность объектов JSON на стандартный вывод, описывая каждый загруженный модуль (или сбой), соответствующий этой структуре Go:

type Module struct {
    Path     string // путь к модулю
    Version  string // версия модуля
    Error    string // ошибка загрузки модуля
    Info     string // абсолютный путь к кешированному .info файлу 
    GoMod    string // абсолютный путь к кешированному .mod файлу
    Zip      string // абсолютный путь к кешированному .zip файлу
    Dir      string // абсолютный путь к кэшированному исходному корневому каталогу
    Sum      string // контрольная сумма для пути, версии (как в go.sum)
    GoModSum string // контрольная сумма для go.mod (как в go.sum)
}

Флаг -x заставляет download печатать команды, которые он выполняет с выводом в стандартный вывод ошибок.


Читайте также:


Релиз Go 1.16, основная библиотека

Встроенные файлы

Новый пакет embed обеспечивает доступ к файлам, встроенным в программу во время компиляции, с помощью новой директивы //go:embed.

Файловые системы

Новый пакет io/fs определяет интерфейс fs.FS, абстракцию для деревьев файлов, доступных только для чтения. Стандартные пакеты библиотек были адаптированы для использования интерфейса по мере необходимости.

На стороне производителя интерфейса новый тип embed.FS реализует fs.FS, как и zip.Reader. Новая функция os.DirFS обеспечивает реализацию fs.FS, поддерживаемую деревом файлов операционной системы.

На стороне потребителя новая функция http.FS преобразует fs.FS в http.FileSystem. Кроме того, функции и методы ParseFS пакетов html/template и text/template считывают шаблоны из fs.FS.

Для тестирования кода, реализующего fs.FS, новый пакет testing/fstest предоставляет функцию TestFS, которая проверяет и сообщает о типичных ошибках. Он также предоставляет простую реализацию файловой системы в памяти, MapFS, которая может быть полезна для тестирования кода, который принимает реализации fs.FS.

Прекращение поддержки io/ioutil

Пакет io/ioutil оказался плохо определенным и трудным для понимания набором вещей. Все функции, предоставляемые пакетом, были перенесены в другие пакеты. Пакет io/ioutil остается и будет продолжать работать, как прежде, но новому коду рекомендуется использовать новые определения в пакетах io и os. Вот список новых расположений имен, экспортированных io/ioutil:

  • Discard => io.Discard
  • NopCloser => io.NopCloser
  • ReadAll => io.ReadAll
  • ReadDir => os.ReadDir (примечание: возвращает срез os.DirEntry, а не срез fs.FileInfo)
  • ReadFile => os.ReadFile
  • TempDir => os.MkdirTemp
  • TempFile => os.CreateTemp
  • WriteFile => os.WriteFile

Незначительные изменения в библиотеке

Как всегда, в библиотеку внесены различные незначительные изменения и обновления, сделанные с учетом обещания совместимости с Go 1.

archive/zip

Новый метод Reader.Open реализует интерфейс fs.FS.

crypto/dsa

Пакет crypto/dsa устарел.

crypto/hmac

New теперь будет вызывать panic, если отдельные вызовы функции генерации хэша не вернут новые значения. Раньше поведение было неопределенным, и иногда генерировались недопустимые выходные данные.

crypto/tls

Операции ввода-вывода при закрытии или закрытые TLS-соединения теперь можно обнаруживать с помощью новой ошибки net.ErrClosed. Типичное использование - это errors.Is(err, net.ErrClosed).

Крайний срок записи по умолчанию теперь устанавливается в Conn.Close перед отправкой предупреждения "close notify", чтобы предотвратить блокировку на неопределенный срок.

Теперь клиенты возвращают ошибку установления связи, если сервер выбирает протокол ALPN, которого нет в списке, объявленном клиентом.

Серверы теперь будут предпочитать другие доступные наборы шифров AEAD (например, ChaCha20Poly1305), а не наборы шифров AES-GCM, если клиент или сервер не имеют аппаратной поддержки AES, если не установлены оба Config.PreferServerCipherSuites и Config.CipherSuites. Предполагается, что клиент не имеет аппаратной поддержки AES, если он не сигнализирует о предпочтении наборов шифров AES-GCM.

Config.Clone теперь возвращает nil, если получатель nil, а не паникует.

crypto/x509

Флаг GODEBUG=x509ignoreCN=0 будет удален в Go 1.17. Это позволяет использовать устаревшее поведение, при котором поле CommonName сертификатов X.509 рассматривается как имя хоста, когда нет альтернативных имен субъектов.

ParseCertificate и CreateCertificate теперь накладывают ограничения на кодировку строк для полей DNSNames, EmailAddresses и URI. Эти поля могут содержать только строки с символами в диапазоне ASCII.

CreateCertificate теперь проверяет подпись сгенерированного сертификата, используя открытый ключ подписывающей стороны. Если подпись недействительна, вместо неверного сертификата возвращается ошибка.

Проверка подписи DSA больше не поддерживается. Обратите внимание, что создание подписи DSA никогда не поддерживалось.

В Windows Certificate.Verify теперь будет возвращать все цепочки сертификатов, созданные верификатором сертификатов платформы, а не только цепочку с самым высоким рейтингом.

Новый метод SystemRootsError.Unwrap позволяет получить доступ к полю Err через функции пакета errors.

В системах Unix пакет crypto/x509 теперь более эффективен в том, как он хранит свою копию пула сертификатов системы. Программы, использующие лишь небольшое количество корней, будут использовать примерно на пол мегабайта меньше памяти.

debug/elf

Добавлено больше констант DT и PT.

encoding/asn1

Unmarshal и UnmarshalWithParams теперь возвращают ошибку вместо паники, если аргумент не является указателем или равен nil. Это изменение соответствует поведению других пакетов кодирования, таких как encoding/json.

encoding/json

Теги поля структуры json, понятные для Marshal, Unmarshal и связанных функций, теперь позволяют использовать символы точки с запятой в имени объекта JSON для поля структуры Go.

encoding/xml

Кодировщик всегда старался избегать использования префиксов пространства имен, начинающихся с xml, которые зарезервированы спецификацией XML. Теперь, более внимательно следуя спецификации, эта проверка нечувствительна к регистру, поэтому префиксы, начинающиеся с XML, XmL и т. д., также исключаются.

flag

Новая функция Func позволяет регистрировать флаг, реализованный путем вызова функции, как более легкую альтернативу реализации интерфейса Value.

go/build

В структуре Package есть новые поля, которые сообщают информацию о директивах //go:embed в пакете: EmbedPatterns, EmbedPatternPos, TestEmbedPatterns, TestEmbedPatternPos, XTestEmbedPatterns, XTestEmbedPatternPos.

Поле пакета IgnoredGoFiles больше не будет включать файлы, начинающиеся с "_" или ".", поскольку эти файлы всегда игнорируются. IgnoredGoFiles предназначен для файлов, игнорируемых из-за ограничений сборки.

В новом поле Package IgnoredOtherFiles есть список файлов, отличных от Go, которые игнорируются из-за ограничений сборки.

go/build/constraint

Новый пакет go/build/constraint анализирует строки ограничений сборки, как исходный синтаксис // +build, так и синтаксис //go:build, который будет представлен в Go 1.17. Этот пакет существует для того, чтобы инструменты, созданные с помощью Go 1.16, могли обрабатывать исходный код Go 1.17. Обратите внимание, что строки //go:build не поддерживаются в Go 1.16 и пока не должны вводиться в программы Go.

html/template

Новая функция template.ParseFS и метод template.Template.ParseFS похожи на template.ParseGlob и template.Template.ParseGlob, но считывают шаблоны из fs.FS.

io

Теперь пакет определяет интерфейс ReadSeekCloser.

Пакет теперь определяет Discard, NopCloser и ReadAll, которые будут использоваться вместо тех же имен в пакете io/ioutil.

log

Новая функция по умолчанию обеспечивает доступ к регистратору по умолчанию.

log/syslog

Writer теперь использует формат локального сообщения (без имени хоста и с использованием более короткой отметки времени) при входе в пользовательские сокеты домена Unix, что соответствует формату, уже используемому для сокета журнала по умолчанию.

mime/multipart

Метод ReadForm Reader больше не отклоняет данные формы при передаче максимального значения int64 в качестве ограничения.

net

Случай ввода-вывода в закрытом сетевом соединении или ввода-вывода в сетевом соединении, которое закрывается до завершения любой из операций ввода-вывода, теперь можно обнаружить с помощью новой ошибки ErrClosed. Типичное использование - это errors.Is(err, net.ErrClosed). В более ранних релизах единственным способом надежного обнаружения этого случая было сопоставление строки, возвращаемой методом Error, с "use of closed network connection" ("использование закрытого сетевого соединения").

В предыдущих релизах Go размер невыполненной работы прослушивателя TCP по умолчанию в системах Linux, установленный с помощью /proc/sys/net/core/somaxconn, был ограничен максимумом 65535. В ядре Linux версии 4.1 и выше максимальное значение теперь составляет 4294967295.

В Linux поиск имени хоста больше не использует DNS перед проверкой /etc/hosts, если /etc/nsswitch.conf отсутствует; это распространено в системах на основе musl и заставляет программы Go соответствовать поведению программ на C в этих системах.

net/http

В пакете net/http поведение StripPrefix было изменено для удаления префикса из поля RawPath URL-адреса запроса в дополнение к его полю Path. В прошлых релизах обрезалось только поле Path, поэтому, если URL-адрес запроса содержал какие-либо экранированные символы, URL-адрес изменялся бы, чтобы иметь несоответствующие поля Path и RawPath. В Go 1.16 StripPrefix обрезает оба поля. Если в префиксной части URL-адреса запроса есть экранированные символы, обработчик обслуживает 404 вместо своего предыдущего поведения, вызывая базовый обработчик с несовпадающей парой Path/RawPath.

Пакет net/http теперь отклоняет запросы диапазона HTTP в форме "Range": "bytes=--N", где "-N" - отрицательная длина суффикса, например "Range": "bytes=--2". Теперь он отвечает с ответом 416 "Range Not Satisfiable".

Файлы cookie, установленные с помощью SameSiteDefaultMode, теперь ведут себя в соответствии с текущей спецификацией (атрибуты не установлены), а не генерируют ключ SameSite без значения.

Теперь клиент отправляет явный заголовок Content-Length: 0 в запросах PATCH с пустыми телами, что соответствует существующему поведению POST и PUT.

Функция ProxyFromEnvironment больше не возвращает значение переменной среды HTTP_PROXY для URL-адресов https://, если HTTPS_PROXY не задан.

Тип транспорта имеет новое поле GetProxyConnectHeader, которое может быть установлено на функцию, которая возвращает заголовки для отправки прокси-серверу во время запроса CONNECT. Фактически GetProxyConnectHeader является динамической версией существующего поля ProxyConnectHeader; если GetProxyConnectHeader не равен нулю, то ProxyConnectHeader игнорируется.

Новая функция http.FS конвертирует fs.FS в http.FileSystem.

net/http/httputil

ReverseProxy теперь более агрессивно сбрасывает буферизованные данные при проксировании потоковых ответов с неизвестной длиной тела.

net/smtp

Теперь метод Mail Client отправляет директиву SMTPUTF8 на серверы, которые ее поддерживают, сигнализируя, что адреса закодированы в UTF-8.

os

Process.Signal теперь возвращает ErrProcessDone вместо неэкспортируемого errFinished, когда процесс уже завершился.

Пакет определяет новый тип DirEntry как псевдоним для fs.DirEntry. Новую функцию ReadDir и новый метод File.ReadDir можно использовать для чтения содержимого каталога в часть DirEntry. Метод File.Readdir (обратите внимание на букву d в dir в нижнем регистре) все еще существует, возвращая фрагмент FileInfo, но для большинства программ более эффективно переключиться на File.ReadDir.

Пакет теперь определяет CreateTemp, MkdirTemp, ReadFile и WriteFile, которые будут использоваться вместо функций, определенных в пакете io/ioutil.

Типы FileInfo, FileMode и PathError теперь являются псевдонимами для одноименных типов в пакете io/fs. Сигнатуры функций в пакете os были обновлены, чтобы ссылаться на имена в пакете io/fs. Это не должно влиять на существующий код.

Новая функция DirFS обеспечивает реализацию fs.FS на основе дерева файлов операционной системы.

os/signal

Новая функция NotifyContext позволяет создавать контексты, которые отменяются при поступлении определенных сигналов.

path

Функция Match теперь возвращает ошибку, если несопоставленная часть шаблона имеет синтаксическую ошибку. Раньше функция возвращала рано при неудачном сопоставлении и, следовательно, не сообщала о каких-либо последующих синтаксических ошибках в шаблоне.

path/filepath

Новая функция WalkDir похожа на Walk, но обычно более эффективна. Функция, переданная в WalkDir, получает fs.DirEntry вместо fs.FileInfo. (Чтобы прояснить для тех, кто помнит, что функция Walk принимает os.FileInfo, os.FileInfo теперь является псевдонимом для fs.FileInfo.)

Функции Match и Glob теперь возвращают ошибку, если несопоставленная часть шаблона имеет синтаксическую ошибку. Раньше функции возвращали рано при неудачном сопоставлении и, таким образом, не сообщали о каких-либо последующих синтаксических ошибках в шаблоне.

runtime/debug

Значения runtime.Error, используемые при включении SetPanicOnFault, теперь могут иметь метод Addr. Если этот метод существует, он возвращает адрес памяти, который вызвал сбой.

strconv

ParseFloat теперь использует алгоритм Эйзеля-Лемира, повышая производительность в 2 раза. Это также может ускорить декодирование текстовых форматов, таких как encoding/json.

syscall

NewCallback и NewCallbackCDecl теперь правильно поддерживают функции обратного вызова с несколькими аргументами sub-uintptr-sized в строке. Это может потребовать изменения использования этих функций, чтобы исключить ручное заполнение небольших аргументов.

SysProcAttr в Windows имеет новое поле NoInheritHandles, которое отключает наследование дескрипторов при создании нового процесса.

DLLError в Windows теперь имеет метод Unwrap для распаковки основной ошибки.

В Linux теперь реализованы Setgid, Setuid и связанные с ними вызовы. Ранее они возвращали ошибку syscall.EOPNOTSUPP.

В Linux новые функции AllThreadsSyscall и AllThreadsSyscall6 могут использоваться для выполнения системного вызова для всех потоков Go в процессе. Эти функции могут использоваться только программами, не использующими cgo; если программа использует cgo, они всегда будут возвращать syscall.ENOTSUP.

testing/iotest

Новая функция ErrReader возвращает io.Reader, который всегда возвращает ошибку.

Новая функция TestReader проверяет правильность работы io.Reader.

text/template

Символы новой строки теперь разрешены внутри разделителей действий, что позволяет действиям занимать несколько строк.

Новая функция template.ParseFS и метод template.Template.ParseFS похожи на template.ParseGlob и template.Template.ParseGlob, но считывают шаблоны из fs.FS.

text/template/parse

В дерево синтаксического анализа был добавлен новый CommentNode. Поле Mode в parse.Tree разрешает доступ к нему.

time/tzdata

Тонкий формат данных часового пояса теперь используется для базы данных часовых поясов в $GOROOT/lib/time/zoneinfo.zip и встроенной копии в этом пакете. Это уменьшает размер базы данных часовых поясов примерно на 350 КБ.

unicode

Пакет unicode и связанная с ним поддержка во всей системе были обновлены с Unicode 12.0.0 до Unicode 13.0.0, что добавляет 5930 новых символов, включая четыре новых скрипта и 55 новых эмодзи. Unicode 13.0.0 также обозначает плоскость 3 (U+30000-U+3FFFF) как третичную идеографическую плоскость.


Читайте также:


Релиз Go 1.16, runtime, компилятор

Среда времени исполнения (Runtime)

Новый пакет runtime/metrics представляет стабильный интерфейс для чтения метрик, определенных реализацией, из среды выполнения Go. Он заменяет существующие функции, такие как runtime.ReadMemStats и debug.GCStats, и является значительно более общим и эффективным.

Установка для переменной среды GODEBUG значения inittrace=1 теперь заставляет среду выполнения выдавать одну строку стандартной ошибки для каждого пакета init, суммируя время выполнения и выделение памяти. Эта трассировка может использоваться для поиска узких мест или снижения производительности Go при запуске. Документация GODEBUG описывает формат.

В Linux среда выполнения теперь по умолчанию немедленно освобождает память операционной системе (с использованием MADV_DONTNEED), а не лениво, когда операционная система испытывает нехватку памяти (с помощью MADV_FREE). Это означает, что статистика памяти на уровне процесса, такая как RSS, будет более точно отражать объем физической памяти, используемой процессами Go. Системам, которые в настоящее время используют GODEBUG=madvdontneed=1 для улучшения поведения мониторинга памяти, больше не нужно устанавливать эту переменную среды.

В Go 1.16 исправлено несоответствие между детектором гонки и моделью памяти Go. Детектор гонки теперь более точно следует правилам синхронизации каналов модели памяти. В результате теперь детектор может сообщать о ранее пропущенных гонках.

Компилятор

Компилятор теперь может встраивать функции с немаркированными циклами for, значениями методов и переключателями типов. Инлайнер также может обнаруживать больше косвенных вызовов, когда встраивание возможно.

Компоновщик (Linker)

Этот релиз включает в себя дополнительные улучшения компоновщика Go, снижающие использование ресурсов компоновщика (как времени, так и памяти) и повышающие надежность и удобство сопровождения кода. Эти изменения образуют вторую половину проекта с двумя релизами по модернизации компоновщика Go.

Изменения компоновщика в 1.16 распространяют улучшения 1.15 на все поддерживаемые комбинации архитектуры/ОС (улучшения производительности 1.15 были в основном сосредоточены на ОС на основе ELF и архитектурах amd64). Для репрезентативного набора больших программ Go компоновка на 20-25% быстрее, чем 1.15, и требует в среднем на 5-15% меньше памяти для linux/amd64 с большими улучшениями для других архитектур и ОС. Большинство двоичных файлов также меньше в результате более агрессивной обрезки символов.

В Windows go build -buildmode=c-shared теперь по умолчанию генерирует Windows ASLR DLL. ASLR можно отключить с помощью --ldflags=-aslr=false.


Читайте также:


Релиз Go 1.16, порты, инструменты

Введение в Go 1.16

Последний выпуск Go, версия 1.16, выходит через шесть месяцев после Go 1.15. Большинство его изменений связано с реализацией цепочки инструментов, среды выполнения и библиотек. Как всегда, релиз поддерживает обещание Go 1 о совместимости. Ожидается, что почти все программы Go будут продолжать компилироваться и работать как раньше.

Изменения в языке

В синтаксисе языка изменений нет.

Порты

Darwin и iOS

Go 1.16 добавляет поддержку 64-битной архитектуры ARM в macOS (также известной как Apple Silicon) с помощью GOOS=darwin, GOARCH=arm64. Как и порт darwin/amd64, порт darwin/arm64 поддерживает режимы cgo, внутреннее и внешнее связывание, c-archive, c-shared и pie build, а также детектор гонки.

Порт iOS, который ранее был darwin/arm64, был переименован в ios/arm64. GOOS=ios подразумевает тег сборки darwin, так же как GOOS=android подразумевает тег сборки linux. Это изменение должно быть прозрачным для всех, кто использует gomobile для создания приложений iOS.

Go 1.16 добавляет порт ios/amd64, предназначенный для симулятора iOS, работающего в macOS на базе AMD64. Ранее это неофициально поддерживалось через darwin/amd64 с набором тегов сборки ios.

Go 1.16 - это последний выпуск, который будет работать в macOS 10.12 Sierra. Go 1.17 потребует macOS 10.13 High Sierra или новее.

NetBSD

Go теперь поддерживает 64-битную архитектуру ARM в NetBSD (порт netbsd/arm64).

OpenBSD

Go теперь поддерживает архитектуру MIPS64 в OpenBSD (порт openbsd/mips64). Этот порт еще не поддерживает cgo.

В 64-битных x86 и 64-битных архитектурах ARM в OpenBSD (порты openbsd/amd64 и openbsd/arm64) системные вызовы теперь выполняются через libc, а не напрямую с помощью инструкции SYSCALL/SVC. Это гарантирует прямую совместимость с будущими версиями OpenBSD. В частности, OpenBSD 6.9 и новее потребует, чтобы системные вызовы выполнялись через libc для нестатических двоичных файлов Go.

386

Как было объявлено в примечаниях к выпуску Go 1.15, Go 1.16 отказывается от поддержки компиляции в режиме x87 (GO386=387). Поддержка процессоров, отличных от SSE2, теперь доступна в режиме soft float (GO386=softfloat). Пользователи, работающие на процессорах, отличных от SSE2, должны заменить GO386=387 на GO386=softfloat.

RISC-V

Порт linux/riscv64 теперь поддерживает cgo и -buildmode=pie. Этот выпуск также включает оптимизацию производительности и улучшения генерации кода для RISC-V.

Инструменты


Команда Go


Модули

Режим с поддержкой модулей включен по умолчанию, независимо от того, присутствует ли файл go.mod в текущем рабочем каталоге или в родительском каталоге. Точнее, переменная среды GO111MODULE теперь по умолчанию равна on (включена). Чтобы переключиться на предыдущее поведение, установите GO111MODULE на auto.

Команды сборки, такие как go build и go test, больше не изменяют go.mod и go.sum по умолчанию. Вместо этого они сообщают об ошибке, если требуется добавить или обновить требование модуля или контрольную сумму (как если бы использовался флаг -mod=readonly). Требования к модулю и суммы могут быть скорректированы с помощью go mod tidy или go get.

go install теперь принимает аргументы с суффиксами версии (например, go install example.com/cmd@v1.0.0). Это приводит к тому, что go install создает и устанавливает пакеты в режиме с поддержкой модулей, игнорируя файл go.mod в текущем каталоге или любом родительском каталоге, если он есть. Это полезно для установки исполняемых файлов, не влияя на зависимости основного модуля.

go install с суффиксом версии или без него (как описано выше) теперь является рекомендуемым способом сборки и установки пакетов в модульном режиме. go get следует использовать с флагом -d для настройки зависимостей текущего модуля без сборки пакетов, а использование go get для сборки и установки пакетов является устаревшим. В будущих выпусках флаг -d всегда будет включен.

Директивы retract теперь могут использоваться в файле go.mod, чтобы указать, что определенные опубликованные версии модуля не должны использоваться другими модулями. Автор модуля может отозвать версию после обнаружения серьезной проблемы или если версия была опубликована непреднамеренно.

Подкоманды go mod vendor и go mod tidy теперь принимают флаг -e, который дает им указание продолжить, несмотря на ошибки в разрешении отсутствующих пакетов.

Команда go теперь игнорирует требования к версиям модуля, исключенным директивами exclude в основном модуле. Раньше команда go использовала следующую версию выше, чем исключенная версия, но эта версия могла со временем изменяться, что приводило к невоспроизводимым сборкам.

В модульном режиме команда go теперь запрещает импорт путей, содержащих символы, отличные от ASCII, или элементы пути с начальным знаком точки (.). Пути к модулям с этими символами уже были запрещены, поэтому это изменение влияет только на пути в подкаталогах модулей.

Встраивание файлов

Команда go теперь поддерживает включение статических файлов и файловых деревьев в окончательный исполняемый файл с помощью новой директивы //go:embed.

go test

При использовании go test тест, который вызывает os.Exit(0) во время выполнения тестовой функции, теперь будет считаться неудачным. Это поможет выявить случаи, когда тест вызывает код, вызывающий os.Exit(0), и тем самым прекращает выполнение всех будущих тестов. Если функция TestMain вызывает os.Exit(0), это все еще считается пройденным тестом.

go test сообщает об ошибке, когда флаги -c или -i используются вместе с неизвестными флагами. Обычно в тесты передаются неизвестные флаги, но при использовании -c или -i тесты не запускаются.

go get

Флаг go get -insecure устарел и будет удален в будущей версии. Этот флаг разрешает выборку из репозиториев и разрешение пользовательских доменов с использованием небезопасных схем, таких как HTTP, а также обходит проверку суммы модулей с использованием базы данных контрольных сумм. Чтобы разрешить использование небезопасных схем, используйте вместо них переменную среды GOINSECURE. Чтобы обойти проверку суммы модуля, используйте GOPRIVATE или GONOSUMDB.

go get example.com/mod@patch теперь требует, чтобы какая-то версия example.com/mod уже требовалась для основного модуля. (Тем не менее, go get -u=patch продолжает исправлять даже недавно добавленные зависимости.)

Переменная среды GOVCS

GOVCS - это новая переменная среды, которая ограничивает инструменты управления версиями, которые команда go может использовать для загрузки исходного кода. Это уменьшает проблемы безопасности с помощью инструментов, которые обычно используются в доверенных средах с проверкой подлинности. По умолчанию git и hg можно использовать для загрузки кода из любого репозитория. svn, bzr и fossil можно использовать только для загрузки кода из репозиториев с путями модулей или путями пакетов, соответствующими шаблонам в переменной среды GOPRIVATE.

all шаблон

Когда файл go.mod основного модуля объявляет версию 1.16 или выше, шаблон пакетов all теперь соответствует только тем пакетам, которые транзитивно импортируются пакетом или тестом, найденным в основном модуле. (Пакеты, импортированные тестами пакетов, импортированных основным модулем, больше не включаются.) Это тот же набор пакетов, который оставался после go mod vendor, начиная с версии Go 1.11.

Флаг сборки -toolexec

Когда флаг сборки -toolexec указан для использования программы при вызове программ инструментальной цепочки, таких как compile или asm, переменная среды TOOLEXEC_IMPORTPATH теперь устанавливается на путь импорта собираемого пакета.

Флаг сборки -i

Флаг -i, принимаемый командами go build, go install и go test, устарел. Флаг -i указывает команде go установить пакеты, импортированные пакетами, указанными в командной строке. Поскольку кеш сборки был введен в Go 1.10, флаг -i больше не оказывает существенного влияния на время сборки и вызывает ошибки, когда каталог установки недоступен для записи.

Команда list

Когда указан флаг -export, в поле BuildID теперь устанавливается идентификатор сборки скомпилированного пакета. Это эквивалентно запуску инструмента go tool buildid в go list -exported -f {{.Export}}, но без дополнительного шага.

Флаг -overlay

Флаг -overlay указывает файл конфигурации JSON, содержащий набор замен пути к файлу. Флаг -overlay может использоваться со всеми командами сборки и подкомандами go mod. Он в первую очередь предназначен для использования инструментами редактора, такими как gopls, для понимания последствий несохраненных изменений в исходных файлах. Файл конфигурации сопоставляет фактические пути к файлам замены, и команда go, и ее сборки будут выполняться так, как если бы фактические пути к файлам существовали с содержимым, указанным в путях к файлам замены, или не существовали, если пути к файлам замены пусты.

Cgo

Инструмент cgo больше не будет пытаться переводить битовые поля структуры C в поля структуры Go, даже если их размер может быть представлен в Go. Порядок, в котором битовые поля C появляются в памяти, зависит от реализации, поэтому в некоторых случаях инструмент cgo выдавал результаты, которые были заведомо неверными.

Vet

Новое предупреждение о недопустимом тестировании. Использование в горутинах

Инструмент vet теперь предупреждает о недопустимых вызовах метода testing.T Fatal из горутины, созданной во время теста. Это также предупреждает о вызовах методов Fatalf, FailNow и Skip{,f,Now} для тестов testing.T или тестов testing.B.

Вызов этих методов останавливает выполнение созданной горутины, а не функции Test* или Benchmark*. Таким образом, они должны вызываться горутиной, выполняющей функцию тестирования или бенчмарка. Например:

func TestFoo(t *testing.T) {
    go func() {
        if condition() {
            t.Fatal("oops") // Выход из внутренней функции 
                            // вместо TestFoo.
        }
        ...
    }()
}

Код, вызывающий t.Fatal (или аналогичный метод) из созданной горутины, должен быть переписан, чтобы сигнализировать об ошибке теста с помощью t.Error и досрочно выйти из горутины с помощью альтернативного метода, например, с помощью оператора return. Предыдущий пример можно было бы переписать как:

func TestFoo(t *testing.T) {
    go func() {
        if condition() {
            t.Error("oops")
            return
        }
        ...
    }()
}

Новое предупреждение для frame указателя

Инструмент vet теперь предупреждает о сборке amd64, которая затирает регистр BP (frame указатель), не сохраняя и не восстанавливая его, вопреки соглашению о вызовах. Код, который не сохраняет регистр BP, должен быть изменен, чтобы либо не использовать BP вообще, либо сохранить BP путем его сохранения и восстановления. Простой способ сохранить BP - это установить для размера frame ненулевое значение, в результате чего сгенерированные пролог и эпилог сохранят регистр BP для вас.

Новое предупреждение для asn1.Unmarshal

Инструмент vet теперь предупреждает о неправильной передаче аргумента, не являющегося указателем, или аргумента nil в asn1.Unmarshal. Это похоже на существующие проверки для encoding/json.Unmarshal и encoding/xml.Unmarshal.


Читайте также:


среда, 17 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go list -m

Использование:

go list -m [-u] [-versions] [list flags] [modules]

Пример:

$ go list -m all
$ go list -m -versions example.com/m
$ go list -m -json example.com/m@latest

Флаг -m заставляет go list выводить список модулей вместо пакетов. В этом режиме аргументы для go list могут быть модулями, шаблонами модулей (содержащими подстановочный знак ...), запросами версии или специальным шаблоном all, который соответствует всем модулям в списке сборки. Если аргументы не указаны, отображается основной модуль (main module).

При перечислении модулей флаг -f по-прежнему указывает шаблон формата, применяемый к структуре Go, но теперь это структура Module:

type Module struct {
    Path      string       // путь к модулю
    Version   string       // версия модуля
    Versions  []string     // доступные версии модуля (для -versions)
    Replace   *Module      // заменен этим модулем
    Time      *time.Time   // время создания версии
    Update    *Module      // доступное обновление, если есть (для -u)
    Main      bool         // это основной модуль (main module)?
    Indirect  bool         // этот модуль только косвенная зависимость от основного модуля?
    Dir       string       // каталог, содержащий файлы для этого модуля, если есть
    GoMod     string       // путь к файлу go.mod для этого модуля, если есть
    GoVersion string       // версия go, используемая в модуле
    Error     *ModuleError // ошибка загрузки модуля
}

type ModuleError struct {
    Err string // сама ошибка
}

По умолчанию выводится путь к модулю, а затем информация о версии и замене, если таковая имеется. Например, go list -m all может напечатать:

example.com/main/module
golang.org/x/text v0.3.0 => /tmp/text
rsc.io/pdf v0.1.1

В структуре Module есть метод String, который форматирует эту строку вывода, так что формат по умолчанию эквивалентен -f '{{.String}}'.

Обратите внимание, что когда модуль был заменен, его поле Replace описывает модуль заменяемого модуля, а его поле Dir устанавливается на исходный код заменяющего модуля, если он присутствует. (То есть, если Replace не равно nil, тогда Dir устанавливается в Replace.Dir, без доступа к замененному исходному коду.)

Флаг -u добавляет информацию о доступных обновлениях. Если последняя версия данного модуля новее, чем текущая, list -u устанавливает в поле Update модуля информацию о более новом модуле. list -u также напечатает, отозвана (retracted) ли текущая выбранная версия. Метод String модуля указывает доступное обновление путем форматирования новой версии в скобках после текущей версии. Например, go list -m -u all может напечатать:

example.com/main/module
golang.org/x/net v0.1.0 (retracted) [v0.2.0]
golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text
rsc.io/pdf v0.1.1 [v0.1.2]

(Для инструментов, go list -m -u -json может быть более удобным для синтаксического анализа.)

Флаг -versions заставляет list установить в поле Versions модуля список всех известных версий этого модуля, упорядоченных в соответствии с семантическим управлением версиями, от наименьшего к наибольшему. Флаг также изменяет формат вывода по умолчанию для отображения пути к модулю, за которым следует список версий, разделенных пробелами. Отозванные версии не включаются в этот список, если также не указан флаг -retracted.

Флаг -retracted инструктирует list показывать отозванные версии в списке, напечатанном с флагом -versions, и учитывать отозванные версии при разрешении запросов о версиях. Например, go list -m -retracted example.com/m@latest показывает самый высокий релиз или предварительную версию модуля example.com/m, даже если эта версия отозвана. Директивы retract загружаются из файла go.mod в этой версии. Флаг -retracted был добавлен в Go 1.16.

Шаблонная функция module принимает единственный строковый аргумент, который должен быть путем к модулю или запросом, и возвращает указанный модуль как структуру Module. В случае возникновения ошибки результатом будет структура Module с полем Error, отличным от nil.


Читайте также:


вторник, 16 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, go get

Использование:

go get [-d] [-t] [-u] [build flags] [packages]

Примеры:

# Установить последнюю версию инструмента.
$ go get golang.org/x/tools/cmd/goimports

# Обновить конкретный модуль.
$ go get -d golang.org/x/net

# Обновить модули, которые предоставляют пакеты, 
# импортированные пакетами в основном модуле.
$ go get -d -u ./...

# Обновить или вернуть определенную версию модуля.
$ go get -d golang.org/x/text@v0.3.2

# Обновление до коммита в главной ветке модуля.
$ go get -d golang.org/x/text@master

# Удалить зависимость от модуля и понизить версию модулей, 
# которые требуют этого, в версии, которые этого не требуют.
$ go get -d golang.org/x/text@none

Команда go get обновляет зависимости модуля в файле go.mod для основного модуля (main module), а затем создает и устанавливает пакеты, перечисленные в командной строке.

Первый шаг - определить, какие модули нужно обновить. go get принимает в качестве аргументов список пакетов, шаблонов пакетов и пути модулей. Если указан аргумент пакета, go get обновляет модуль, который предоставляет пакет. Если указан шаблон пакета (например, all или путь с подстановочным знаком ...), go get расширяет шаблон до набора пакетов, а затем обновляет модули, которые предоставляют пакеты. Если аргумент называет модуль, но не пакет (например, модуль golang.org/x/net не имеет пакета в корневом каталоге), go get обновит модуль, но не создаст пакет. Если аргументы не указаны, go get действует как будто . (точка) была указана (пакет в текущем каталоге); его можно использовать вместе с флагом -u для обновления модулей, которые предоставляют импортированные пакеты.

Каждый аргумент может включать суффикс запроса версии, указывающий на желаемую версию, например go get golang.org/x/text@v0.3.0. Суффикс запроса версии состоит из символа @, за которым следует запрос версии, который может указывать на конкретную версию (v0.3.0), префикс версии (v0.3), имя ветви или тега (master), ревизию (1234abcd), или один из специальных запросов latest, upgrade, patch, или none. Если версия не указана, go get использует запрос @upgrade.

После того, как go get разрешил свои аргументы для определенных модулей и версий, go get добавит, изменит или удалит директивы require в файле go.mod основного модуля, чтобы гарантировать, что модули останутся в желаемых версиях в будущем. Обратите внимание, что требуемые версии в файлах go.mod являются минимальными версиями и могут автоматически увеличиваться по мере добавления новых зависимостей. См. Выбор минимальной версии (MVS) для получения подробной информации о том, как выбираются версии и разрешаются конфликты с помощью команд с поддержкой модуля.

Другие модули могут быть обновлены при добавлении, обновлении или понижении версии модуля, указанного в командной строке, если для новой версии указанного модуля требуются другие модули более высоких версий. Например, предположим, что модуль example.com/a обновлен до версии v1.5.0, и для этой версии требуется модуль example.com/b версии v1.2.0. Если в настоящее время требуется модуль example.com/b для версии v1.1.0, перейдите по ссылке get example.com/a@v1.5.0, чтобы также обновить example.com/b до версии v1.2.0.

Другие модули могут быть переведены на более раннюю версию, когда модуль, указанный в командной строке, будет понижен или удален. Чтобы продолжить приведенный выше пример, предположим, что версия модуля example.com/b понижена до версии 1.1.0. Модуль example.com/a также будет понижен до версии, для которой требуется example.com/b версии v1.1.0 или ниже.

Требование модуля может быть удалено с помощью суффикса версии @none. Это особый вид понижения. Модули, зависящие от удаленного модуля, будут при необходимости понижены или удалены. Требование модуля может быть удалено, даже если один или несколько его пакетов импортированы пакетами в основном модуле. В этом случае следующая команда сборки может добавить требование нового модуля.

Если модуль требуется в двух разных версиях (явно указанных в аргументах командной строки или для выполнения обновлений и понижения версий), go get сообщит об ошибке.

После того, как go get выбрал новый набор версий, он проверяет, отозваны (retracted) ли какие-либо недавно выбранные версии модулей или модули, предоставляющие пакеты, указанные в командной строке. go get выводит предупреждение для каждой найденной отозванной версии. go list -m -u all может использоваться для проверки отзывов во всех зависимостях.

После того, как go get обновляет файл go.mod, он собирает пакеты, указанные в командной строке. Исполняемые файлы будут установлены в каталог, названный переменной среды GOBIN, которая по умолчанию имеет значение $GOPATH/bin или $HOME/go/bin, если переменная среды GOPATH не установлена.

go get поддерживает следующие флаги:

  • Флаг -d сообщает go get не собирать и не устанавливать пакеты. Когда используется -d, go get будет управлять только зависимостями в go.mod.
  • Флаг -u указывает перейти к обновлению модулей, предоставляющих пакеты, импортированные прямо или косвенно пакетами, указанными в командной строке. Каждый модуль, выбранный с помощью -u, будет обновлен до своей последней версии, если он уже не требуется в более поздней версии (предварительный выпуск, pre-release).
  • Флаг -u=patch (не -u patch) также сообщает go get обновлять зависимости, но go get обновит каждую зависимость до последней версии исправления (аналогично запросу @patch version).
  • Флаг -t сообщает go get рассмотреть модули, необходимые для создания тестов пакетов, названных в командной строке. Когда -t и -u используются вместе, go get также обновит тестовые зависимости.
  • Флаг -insecure больше не должен использоваться. Это позволяет go get разрешать настраиваемые пути импорта и выборку из репозиториев и прокси-серверов модулей с использованием небезопасных схем, таких как HTTP. Переменная среды GOINSECURE обеспечивает более детальный контроль, и ее следует использовать вместо этого флага.

Начиная с Go 1.16, go install - это рекомендуемая команда для сборки и установки программ. При использовании с суффиксом версии (например, @latest или @v1.4.6) go install создает пакеты в режиме с поддержкой модулей, игнорируя файл go.mod в текущем каталоге или любом родительском каталоге, если он есть.

go get больше ориентирован на управление требованиями в go.mod. Флаг -d устарел, и в будущих выпусках он всегда будет включен.


Читайте также:


Модули в Golang: команды с поддержкой модулей, вендоринг

При использовании модулей команда go обычно удовлетворяет зависимости, загружая модули из их источников в кеш модулей, а затем загружая пакеты из этих загруженных копий. Вендоринг может использоваться для обеспечения взаимодействия со старыми версиями Go или для того, чтобы все файлы, используемые для сборки, хранились в едином дереве файлов.

Команда go mod vendor создает каталог с именем vendor в корневом каталоге основного модуля (main module), содержащий копии всех пакетов, необходимых для сборки и тестирования пакетов в основном модуле. Пакеты, которые импортируются только тестами пакетов вне основного модуля, не включаются. Как и в случае с go mod tidy и другими командами модуля, ограничения сборки, за исключением игнорирования, не учитываются при создании каталога vendor.

go mod vendor также создает файл vendor/modules.txt, содержащий список поставленных пакетов и версий модулей, из которых они были скопированы. Когда вендоринг включен, этот манифест используется в качестве источника информации о версии модуля, о чем сообщает go list -m и go version -m. Когда команда go читает vendor/modules.txt, она проверяет, соответствуют ли версии модуля go.mod. Если go.mod был изменен с момента создания vendor/modules.txt, команда go сообщит об ошибке. go mod vendor следует запустить снова, чтобы обновить каталог vendor.

Если каталог vendor присутствует в корневом каталоге основного модуля, он будет использоваться автоматически, если версия go в файле go.mod основного модуля 1.14 или выше. Чтобы явно включить вендоринг, вызовите команду go с флагом -mod=vendor. Чтобы отключить вендоринг, используйте флаг -mod=mod.

Когда вендоринг включен, команды сборки, такие как go build и go test, загружают пакеты из каталога vendor вместо доступа к сети или локальному кешу модуля. Команда go list -m выводит информацию только о модулях, перечисленных в go.mod. Команды go mod, такие как go mod download и go mod tidy, не работают по-другому, когда включен вендоринг, и все равно будут загружать модули и обращаться к кешу модулей. go get также не работает по-другому, когда включен вендоринг.

В отличие от вендоринга в GOPATH, команда go игнорирует каталоги поставщиков (vendor directories) в местах, отличных от корневого каталога основного модуля.


Читайте также:


суббота, 13 февраля 2021 г.

Модули в Golang: команды с поддержкой модулей, команды сборки

Все команды, загружающие информацию о пакетах, поддерживают модули. Это включает в себя:

  • go build
  • go fix
  • go generate
  • go get
  • go install
  • go list
  • go run
  • go test
  • go vet

При запуске в режиме с поддержкой модулей эти команды используют файлы go.mod для интерпретации путей импорта, перечисленных в командной строке или записанных в исходных файлах Go. Эти команды принимают следующие флаги, общие для всех команд модуля.

  • Флаг -mod определяет, может ли go.mod обновляться автоматически и будет ли использоваться каталог поставщика.
    • -mod=mod указывает команде go игнорировать каталог поставщика (vendor directory) и автоматически обновлять go.mod, например, когда импортированный пакет не предоставляется каким-либо известным модулем.
    • -mod=readonly указывает команде go игнорировать каталог поставщика (vendor directory) и сообщать об ошибке, если go.mod необходимо обновить.
    • -mod=vendor указывает команде go использовать каталог поставщика (vendor directory). В этом режиме команда go не будет использовать сеть или кеш модуля.
    • По умолчанию, если версия go в go.mod - 1.14 или выше и присутствует каталог поставщика (vendor directory), команда go будет действовать так, как если бы использовалось -mod=vendor. В противном случае команда go будет действовать так, как если бы использовалось -mod=mod.
  • Флаг -modcacherw указывает команде go создавать новые каталоги в кеше модуля с разрешениями на чтение и запись вместо того, чтобы делать их доступными только для чтения. Когда этот флаг используется последовательно (обычно путем установки GOFLAGS=-modcacherw в среде или путем запуска go env -w GOFLAGS=-modcacherw), кеш модуля можно удалить с помощью таких команд, как rm -r, без предварительного изменения разрешений. Команда go clean -modcache может использоваться для удаления кеша модуля, независимо от того, использовалась ли -modcacherw.
  • Флаг -modfile=file.mod указывает команде go прочитать (и, возможно, записать) альтернативный файл вместо go.mod в корневом каталоге модуля. Имя файла должно заканчиваться на .mod. Файл с именем go.mod все еще должен присутствовать, чтобы определить корневой каталог модуля, но к нему нет доступа. Если указан -modfile, также используется альтернативный файл go.sum: его путь определяется флагом -modfile путем обрезки расширения .mod и добавления .sum.

Читайте также:


Модули в Golang: команды с поддержкой модулей

Большинство команд go могут выполняться в режиме с поддержкой модулей (module-aware mode) или в режиме GOPATH. В режиме с поддержкой модулей команда go использует файлы go.mod для поиска зависимостей с поддержкой версий и обычно загружает пакеты из кеша модулей, загружая модули, если они отсутствуют. В режиме GOPATH команда go игнорирует модули; она ищет зависимости в каталогах поставщиков (vendor directories) и в GOPATH.

Режим с поддержкой модулей активен по умолчанию всякий раз, когда файл go.mod обнаруживается в текущем каталоге или в любом родительском каталоге. Для более детального управления переменная среды GO111MODULE может иметь одно из трех значений: on, off или auto.

  • Если GO111MODULE = off, команда go игнорирует файлы go.mod и работает в режиме GOPATH.
  • Если GO111MODULE = on, команда go выполняется в режиме с поддержкой модулей, даже если файл go.mod отсутствует. Не все команды работают без файла go.mod.
  • Если GO111MODULE = auto или не задано, команда go запускается в режиме с поддержкой модулей, если файл go.mod присутствует в текущем каталоге или любом родительском каталоге (поведение по умолчанию).

В режиме с поддержкой модулей GOPATH больше не определяет значение импорта во время сборки, но по-прежнему сохраняет загруженные зависимости (в GOPATH/pkg/mod) и установленные команды (в GOPATH/bin, если GOBIN не установлен).


Читайте также:


четверг, 11 февраля 2021 г.

Модули в Golang: минимальная совместимость модулей

Модуль, выпущенный в основной версии 2 или выше, должен иметь суффикс основной версии в пути к модулю. Модуль может быть разработан или не разработан в подкаталоге основной версии в своем репозитории. Это имеет значение для пакетов, которые импортируют пакеты внутри модуля при построении режима GOPATH.

Обычно в режиме GOPATH пакет хранится в каталоге, соответствующем корневому пути его репозитория, соединенному с его директорией в репозитории. Например, пакет в репозитории с корневым путем example.com/repo в подкаталоге sub будет храниться в $GOPATH/src/example.com/repo/sub и будет импортирован как example.com/repo/sub.

Для модуля с суффиксом основной версии можно ожидать найти пакет example.com/repo/v2/sub в каталоге $GOPATH/src/example.com/repo/v2/sub. Это потребует разработки модуля в подкаталоге v2 его репозитория. Команда go поддерживает это, но не требует этого.

Если модуль разрабатывается не в подкаталоге основной версии, то его каталог в GOPATH не будет содержать суффикс основной версии, и его пакеты могут быть импортированы без суффикса основной версии. В приведенном выше примере пакет будет находиться в каталоге $GOPATH/src/example.com/repo/sub и будет импортирован как example.com/repo/sub.

Это создает проблему для пакетов, предназначенных для создания как в модульном режиме, так и в режиме GOPATH: режим модуля требует суффикса, а режим GOPATH - нет.

Чтобы исправить это, минимальная совместимость модулей была добавлена в Go 1.11 и была перенесена в Go 1.9.7 и 1.10.3. Когда путь импорта разрешается в каталог в режиме GOPATH:

  • При разрешении импорта формы $modpath/$vn/$dir, где:
    • $modpath - допустимый путь к модулю,
    • $vn - суффикс основной версии,
    • $dir - возможно, пустой подкаталог,
  • Если все следующее верно:
    • Пакет $modpath/$vn/$dir отсутствует ни в одном соответствующем каталоге поставщика (vendor directory).
    • Файл go.mod находится в том же каталоге, что и файл импорта, или в любом родительском каталоге до корня $GOPATH/src,
    • Каталог $GOPATH[i]/src/$modpath/$vn/$suffix не существует (для любого корневого $GOPATH[i]),
    • Файл $GOPATH[d]/src/$modpath/go.mod существует (для некоторого корня $GOPATH[d]) и объявляет путь модуля как $modpath/$vn,
  • Затем импорт $modpath/$vn/$dir разрешается в каталог $GOPATH[d]/src/$modpath/$dir.

Эти правила позволяют пакетам, которые были перенесены в модули, импортировать другие пакеты, которые были перенесены в модули при сборке в режиме GOPATH, даже если подкаталог основной версии не использовался.


Читайте также:


Модули в Golang: +incompatible версии

Модуль, выпущенный в основной версии 2 или выше, должен иметь соответствующий суффикс основной версии в пути к модулю. Например, если модуль выпущен в версии 2.0.0, его путь должен иметь суффикс /v2. Это позволяет команде go обрабатывать несколько основных версий проекта как отдельные модули, даже если они разработаны в одном репозитории.

Требование суффикса основной версии было введено, когда поддержка модуля была добавлена к команде go, и многие репозитории уже помечали выпуски с основной версией 2 или выше до этого. Для обеспечения совместимости с этими репозиториями команда go добавляет суффикс +incompatible к версиям с основной версией 2 или выше без файла go.mod. +incompatible означает, что версия является частью того же модуля, что и версии с меньшими основными номерами версий; следовательно, команда go может автоматически обновиться до более поздних +incompatible версий, даже если это может нарушить сборку.

Рассмотрим пример требования ниже:

require example.com/m v4.1.2+incompatible

Версия v4.1.2+incompatible относится к тегу семантической версии v4.1.2 в репозитории, который предоставляет модуль example.com/m. Модуль должен находиться в корневом каталоге репозитория (то есть корневой путь репозитория также должен быть example.com/m), а файл go.mod не должен присутствовать. Модуль может иметь версии с более низкими основными номерами версий, например v1.5.2, и команда go может автоматически обновляться до v4.1.2+incompatible с этими версиями.

Репозиторий, который переносится на модули после пометки версии v2.0.0, обычно должен выпускать новую основную версию. В приведенном выше примере автор должен создать модуль с путем example.com/m/v5 и выпустить версию v5.0.0. Автору также следует обновить импорт пакетов в модуле, чтобы использовать префикс example.com/m/v5 вместо example.com/m.

Обратите внимание, что суффикс +incompatible не должен появляться в теге в репозитории; тег типа v4.1.2+incompatible будет проигнорирован. Суффикс появляется только в версиях, используемых командой go.

Также обратите внимание, что суффикс +incompatible может появляться в псевдоверсиях. Например, v2.0.1-20200722182040-012345abcdef+incompatible может быть допустимой псевдо-версией.


Читайте также: