Обработка рабочего пространства Go с помощью direnv
Когда я начал изучать Go, я быстро преодолел свое первое препятствие: рабочее пространство Go. Инструменты go предназначены для работы с кодом, который хранится в общедоступных репозиториях с использованием полного доменного имени и пути в качестве пространства имен и имени пакета. Например: github.com/rach/project-x
где github.com/rach
- это вид пространства имен, реализуемый структурой каталогов, а project-x
имя пакета также обеспечивается структурой каталогов.
Исходя из Python, я был удивлен, что не было такого простого решения, как [virtualenv]. Go действительно предлагает способ, но требует немного больше упражнений с кодом.
В этой статье я опишу, как я упростил свою жизнь, работая с Go с помощью небольшого сценария оболочки и используя [direnv] для автоматизации переключения рабочей области. Когда я писал этот пост, я мало что знал о Go, поэтому не стесняйтесь пролить свет на любую из моих ошибок.
Workspaces
Проект Go должен храниться в рабочей области. Рабочая область - это иерархия каталогов содержащая:
src
содержит исходные файлы Go, организованные в пакеты (один пакет на каталог),pkg
содержит объекты пакетаbin
содержит исполняемые команды
Инструмент go собирает исходные пакеты и устанавливает получившиеся двоичные файлы в каталоги pkg и bin.
Подкаталог src
обычно содержит несколько хранилищ контроля версий (например, для Git или Mercurial) , которые отслеживают развитие одного или нескольких исходных пакетов.
Чтобы дать вам представление о том, как рабочее пространство выглядит на практике, вот пример:
bin/ hello outyet pkg/ linux_amd64/ github.com/golang/example/ stringutil.a src/ github.com/golang/example/ .git/ # Git repository metadata hello/ hello.go outyet/ main.go main_test.go stringutil/ reverse.go reverse_test.go
Проблема, которую я решал, была:
- как работать над несколькими различными проектами?
- как указать, на каком рабочем пространстве я работаю?
Для этого у нас есть переменная среды GOPATH
, чтобы определить местоположение рабочей области.
Переменная среды GOPATH
Переменная среды GOPATH указывает местоположение вашего рабочего пространства. Для начала создайте каталог рабочей области и установите GOPATH соответственно. Ваше рабочее пространство может быть расположено где угодно.
$ mkdir $HOME/go $ export GOPATH=$HOME/go
Чтобы иметь возможность вызывать двоичную сборку внутри вашего рабочего пространства, добавьте подкаталог bin в ваш PATH:
$ export PATH=$PATH:$GOPATH/bin
Для вашего проекта можно выбрать любой произвольный путь, при условии, что он уникален для стандартной библиотеки и большей экосистемы Go. В качестве структуры папок принято использовать полное доменное имя и путь, которые будут вести себя как пространства имен.
Мы будем использовать github.com/rach/project-x
в качестве нашего базового пути. Создайте каталог в вашей рабочей области, в котором будет храниться исходный код:
$ mkdir -p $GOPATH/src/github.com/rach/project-x
Обновите GOPATH автоматически с direnv
Direnv - это переключатель среды для оболочки. Он загружает или выгружает переменные окружения в зависимости от текущего каталога. Это позволяет иметь специфические пути для проекта переменные среды. direnv работает с bash, zsh, tcsh и fish shell. Direnv проверяет наличие файла ".envrc" в текущем и родительском каталогах. Если файл существует, переменные, объявленные в, .envrc
становятся доступными в текущей оболочке. Когда вы покидаете каталог или подкаталог, в котором присутствует .envrc, переменные выгружаются. Это также хорошо работает с обновлением существующей переменной среды.
Чтобы установить direnv на OSX с использованием zsh, выполните следующие действия:
$ brew update $ brew install direnv $ echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc
Используя direnv, становится легко иметь несколько рабочих пространств и переключаться между ними. Просто создайте файл .envrc
в месте вашего рабочего пространства и экспортируйте соответствующую переменную:
$ mkdir $HOME/new-workspace $ cd $HOME/new-workspace $ echo 'export GOPATH=$(PWD):$GOPATH' >> .envrc $ echo 'export PATH=$(PWD)/bin:$PATH' >> .envrc $ direnv allow
С помощью приведенного выше кода у нас теперь есть рабочее пространство, которое включается при его вводе. Наличие нескольких рабочих областей помогает экспериментировать с libs/package, который вы хотите протестировать, точно так же, как вы можете установить библиотеку Python только для одноразового использования.
Предполагая, что мы будем писать много проектов go, не будет приятно иметь вспомогательную функцию для создания рабочей области, которая будет следовать предложенной структуре с обработкой GOPATH
автоматически.
Автоматизировать создание рабочего пространства для проекта
Теперь, когда мы знаем, как должно выглядеть рабочее пространство и как сделать его проще. Давайте автоматизируем создание нового проекта с рабочими пространствами, чтобы избежать ошибок, для этого я написал для себя небольшую функцию zsh
.
function mkgoproject { TRAPINT() { print "Caught SIGINT, aborting." return $(( 128 + $1 )) } echo 'Creating new Go project:' if [ -n "$1" ]; then project=$1 else while [[ -z "$project" ]]; do vared -p 'what is your project name: ' -c project; done fi namespace='github/rach' while true; do vared -p 'what is your project namespace: ' -c namespace if [ -n "$namespace" ] ; then break fi done mkdir -p $project/src/$namespace/$project git init -q $project/src/$namespace/$project main=$project/src/$namespace/$project/main.go echo 'export GOPATH=$(PWD):$GOPATH' >> $project/.envrc echo 'export PATH=$(PWD)/bin:$PATH' >> $project/.envrc echo 'package main' >> $main echo 'import "fmt"' >> $main echo 'func main() {' >> $main echo ' fmt.Println("hello world")' >> $main echo '}' >> $main direnv allow $project echo "cd $project/src/$namespace/$project #to start coding" }
Если вы используете zsh, вы сможете скопировать / вставить эту функцию в zshrc, и после перезагрузки вы сможете вызывать ее mkgoproject
. Если вы вызываете функцию с аргументом, тогда она будет считать, что это имя проекта, и попросит вас указать пространство имен (например, github.com/rach), в противном случае она запросит у вас оба: имя проекта (пакет) и пространство имен, Функция создания нового Worspace с .envrc
и main.go
готова для сборки.
$ mkgoproject test Creating new Go project: what is your project namespace: github/rach cd test/src/github/rach/test #to start coding
Я надеюсь, что этот пост поможет вам автоматизировать переключение между вашим проектом go и их созданием.