О команде go
Дистрибутив Go включает в себя команду под названием
"go", которая автоматизирует загрузку, сборку, установку и тестирование Go пакетов
и команд. В данном документе говорится о том, почему мы написали новую команду, что
это за команда, что она не является, и как её использовать.
Мотивация
Вы могли видеть ранние выступления Роба Пайка, в которых он шутит, что идея для Go возникла во время ожидания компиляции большого сервера Google. Это действительно была мотивация для Go: создать язык, который хорошо работает для создания крупного программного обеспечения, которое пишет и запускает Google. Было ясно с самого начала, что такой язык должен предоставлять способ выражать зависимости между библиотеками кода четко, поэтому была введена группировка пакетов и явные блоки импорта. Также с самого начала было ясно, что вы можете захотеть произвольный синтаксис для описания импортируемого кода; поэтому пути импорта являются строковыми литералами.
Явной целью для Go с самого начала было возможность сборки Go кода, используя только информацию, содержащуюся в исходном коде, без необходимости писать makefile или один из множества современных замен makefiles. Если бы Go требовал конфигурационный файл для объяснения, как собирать вашу программу, то Go бы провалил свою задачу.
Сначала не было компилятора Go, и начальная разработка сосредоточилась на создании компилятора и последующем создании библиотек для него. Для удобства мы отложили автоматизацию сборки Go кода с использованием make и написания makefiles. Когда компиляция одного пакета требовала множественных вызовов компилятора Go, мы даже использовали программу для автоматического создания makefiles. Вы можете найти её, если углубитесь в историю репозитория.
Цель новой команды go — это возвращение к этой идеале, согласно которой программы на Go должны компилироваться без конфигурации или дополнительных усилий со стороны пользователя, которые не требуют установки дополнительных инструментов.
Начало работы с командой go
Наконец, краткий обзор того, как использовать команду go.
Как упоминалось выше, стандартный $GOPATH в Unix — это $HOME/go.
Мы будем хранить наши программы там.
Чтобы использовать другое расположение, вы можете установить $GOPATH;
подробности см. в разделе Как писать код на Go.
Сначала добавим некоторый исходный код. Предположим, мы хотим использовать
библиотеку индексации из проекта codesearch вместе с левосторонним красно-черным деревом.
Мы можем установить оба с помощью подкоманды "go get":
$ go get github.com/google/codesearch/index $ go get github.com/petar/GoLLRB/llrb $
Оба этих проекта теперь загружены и установлены в $HOME/go,
который содержит два каталога
src/github.com/google/codesearch/index/ и
src/github.com/petar/GoLLRB/llrb/, а также скомпилированные
пакеты (в pkg/) для этих библиотек и их зависимостей.
Поскольку мы использовали системы контроля версий (Mercurial и Git) для получения
исходников, дерево исходников также содержит другие файлы из
соответствующих репозиториев, такие как связанные пакеты. Подкоманда "go list" перечисляет
пути импорта, соответствующие своим аргументам, и шаблон "./..." означает начать в текущем каталоге
("./") и найти все пакеты ниже этого каталога
("..."):
$ cd $HOME/go/src $ go list ./... github.com/google/codesearch/cmd/cgrep github.com/google/codesearch/cmd/cindex github.com/google/codesearch/cmd/csearch github.com/google/codesearch/index github.com/google/codesearch/regexp github.com/google/codesearch/sparse github.com/petar/GoLLRB/example github.com/petar/GoLLRB/llrb $
Мы также можем протестировать эти пакеты:
$ go test ./... ? github.com/google/codesearch/cmd/cgrep [no test files] ? github.com/google/codesearch/cmd/cindex [no test files] ? github.com/google/codesearch/cmd/csearch [no test files] ok github.com/google/codesearch/index 0.203s ok github.com/google/codesearch/regexp 0.017s ? github.com/google/codesearch/sparse [no test files] ? github.com/petar/GoLLRB/example [no test files] ok github.com/petar/GoLLRB/llrb 0.231s $
Если подкоманда go вызывается без указания путей, она работает с текущим каталогом:
$ cd github.com/google/codesearch/regexp $ go list github.com/google/codesearch/regexp $ go test -v === RUN TestNstateEnc --- PASS: TestNstateEnc (0.00s) === RUN TestMatch --- PASS: TestMatch (0.00s) === RUN TestGrep --- PASS: TestGrep (0.00s) PASS ok github.com/google/codesearch/regexp 0.018s $ go install $
Подкоманда "go install" устанавливает последнюю версию пакета
в каталог pkg. Поскольку команда go может анализировать граф зависимостей,
"go install" также устанавливает любые пакеты, которые импортирует этот пакет,
но которые устарели, рекурсивно.
Обратите внимание, что "go install" смог определить имя пути импорта для пакета в текущем каталоге,
благодаря соглашению о именовании каталогов. Было бы немного удобнее, если бы мы могли выбрать
имя каталога, где хранится исходный код, и, вероятно, мы не выбрали бы такое длинное имя,
но такая возможность потребовала бы дополнительной конфигурации и усложнения инструмента.
Набирать дополнительное имя каталога или два — небольшая цена, которую стоит заплатить за увеличение простоты и мощности.
Ограничения
Как упоминалось выше, команда go не является универсальным инструментом сборки.
В частности, она не имеет возможности генерировать исходные файлы Go во время сборки, хотя она предоставляет
go
generate,
которая может автоматизировать создание Go файлов до сборки.
Для более сложных конфигураций сборки вам может потребоваться написать
makefile (или конфигурационный файл для выбранного вами инструмента сборки),
чтобы запустить инструмент, создающий Go файлы, а затем проверить эти сгенерированные исходные файлы
в ваш репозиторий. Это требует больше усилий от автора пакета,
но значительно меньше усилий для ваших пользователей, которые могут использовать
"go get" без необходимости получать и собирать
дополнительные инструменты.
Дополнительная информация
Для получения дополнительной информации прочитайте Как писать код на Go и ознакомьтесь с документацией команды go.