DevGang
Авторизоваться

Обработка рабочего пространства 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 и их созданием.

#Golang
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

Напиши статью и выиграй годовую подписку на Яндекс плюс или лицензию от Jet Brains

Участвовать