Автоматическое определение GOPATH на основе каждого проекта
Для каждого проекта, который я создаю, я должен делать export GOPATH={path_to_project}
каждый раз, когда я cd в директорию проекта. Должен быть более простой способ. Не могу ли я создать файл .bashrc или .bash_profile для данного каталога, чтобы определить GOPATH для этого проекта?
Например, у меня есть два проекта перехода A и B. Если у меня есть единственный GOPATH, который не переопределяется при переходе между проектами, тогда двоичные файлы для обоих проектов будут храниться в одном месте. Что еще более важно, двоичные файлы для сторонних библиотек будут храниться в одном и том же месте, поэтому я не могу поддерживать несколько версий одной и той же библиотеки для каждого проекта.
Однако, если я могу определить GOPATH для каждого проекта, тогда все двоичные файлы и библиотеки сторонних разработчиков зависят от проекта. Это, по-видимому, общий способ управления пакетами в большинстве других языковых сред (ruby rbenv, python vertiualenv и т.д.).
Ответы
Ответ 1
У вас есть аналогичная идея, выраженная в Управлять несколькими дисками GOPATH с легкостью, Герберт Фишер (hgfischer
), для среды Linux/Unix (база вопроса уже упоминается в комментариях выше):
Просто включите следующий фрагмент в ~/.bashrc
(или ~/.bash_profile
) и перезагрузите среду оболочки с помощью источника ~/.bashrc
.
Этот фрагмент создаст функцию оболочки, которая переопределит встроенную команду cd
с настраиваемой версией, которая сканирует введенный каталог и все остальные выше для файла с именем .gopath
.
cd () {
builtin cd "[email protected]"
cdir=$PWD
while [ "$cdir" != "/" ]; do
if [ -e "$cdir/.gopath" ]; then
export GOPATH=$cdir
break
fi
cdir=$(dirname "$cdir")
done
}
Теперь вам просто нужно создать файл .gopath
в каждом каталоге, который вам нужен, как ваш GOPATH
, и каждый раз, когда вы входите в этот каталог, переопределенная cd
функция установит GOPATH
вашей текущей среды на этот каталог.
Обновление 2017: если вы не хотите изменять свою среду, вы все равно можете использовать один GOPATH
для каждого проекта, открыв папку src
этого проекта в коде Visual Studio (vscode, который является многоплатформенной средой IDE), в сочетании с расширением " Перейти для кода Visual Studio".
В этой среде IDE вы можете:
- сохраните свой глобальный уникальный
GOPATH
в настройке с именем go.toolsGopath
.
- выведите текущий
GOPATH
с помощью параметра go.inferGopath
![Настройки пользователя vscode]()
Таким образом, VSCode установит набор инструментов в вашем глобальном GOPATH
(для вас также использовать внешний VSCode).
См. " Инструменты Go, которые зависят от расширения Go: godep
, golint
, guru
, godoc
,...
И все же ваш GOPATH
для вашего проекта будет родительской папкой src:
![local GOPATH]()
Это работает, когда вы компилируете/устанавливаете свой проект из среды IDE.
Если вы хотите сделать это из командной строки, исходный ответ выше будет применяться.
Ответ 2
Вы можете использовать инструмент autoenv для настройки script, который автоматически выполняется, когда вы cd
в конкретный каталог.
В ваших целях пример файла /happy/go/path/yay/.env
может выглядеть так:
export GOPATH="/happy/go/path/yay"
export PATH="$GOPATH/bin:$PATH"
Ответ 3
Я бы написал script, который может вывести правильный GOPATH из текущего каталога, а затем с помощью команды go
сначала вызвать этот script. Например, очень простая реализация:
#!/bin/bash
# infer-gopath.sh
pwd
И затем, в .bash_aliases (или где бы вы не сохранили свои псевдонимы):
alias go='GOPATH=$(infer-gopath.sh) go'
Это устанавливает GOPATH
для всех infer-gopath.sh
выходов только для вызова команды go
, поэтому он не будет иметь долговременного эффекта для вашей оболочки.
Ответ 4
Мое впечатление, что инструмент go
активно препятствует "поддерживать несколько версий одной и той же библиотеки на основе каждого проекта" по той причине, что опыт показал, что эта стратегия не работает на больших кодовых базах (например, в Google). Было довольно много обсуждений о версиях пакетов на golang-nuts: (искать в списке), и кажется, что обсуждение все еще открыто, как указал Ян Лэнс Тейлор в этом интервью 6 июня 2013 г. (поиск слова "управление версиями" ).
Система упаковки go
предназначена для того, чтобы каждый проект имел свою собственную структуру каталогов; единственным ограничением является то, что все они должны быть дочерними (некоторым) каталогом в GOPATH
. Это имеет то преимущество, что он хорошо взаимодействует с системами управления версиями, если только мастер VCS всегда строит. В интервью в блоге, упомянутом выше, ILT предлагает:
Что мы делаем внутренне, это сделать снимок импортированного кода и время от времени обновлять этот снимок. Таким образом, наша база кода не будет неожиданно ломаться, если API изменится.
Подставляя "мои другие библиотеки" для "импортированного кода", это похоже на возможность; вы могли бы иметь две директории go
, производство и развитие; для разработки вы можете поместить каталог разработки сначала в путь, чтобы двоичные файлы и библиотеки разработки не загрязняли производственные каталоги. Я не знаю, достаточно ли этого.
Если вы действительно хотите иметь отдельный GOPATH
для каждого проекта, я бы предложил следующее:
1) Сделайте каждый проект GOPATH
завершенным в каталоге с именем go
(или некоторых таких)
2) Выделите GOPATH
с помощью чего-то вроде следующей функции оболочки (почти полностью непроверенной):
gopath() {
GOPATH="$(
( while [[ $PWD != / && $(basename $PWD) != go ]]; do
cd ..
done
if [[ $PWD == / ]]; then
echo $GOPATH
else
echo $PWD
fi
))" go "[email protected]"
}
Затем вы можете использовать GOPATH
вместо go
, пока ваш текущий рабочий каталог находится где-то внутри репозитория проекта. (Более сложные возможности могут включать использование явно предоставленного пути к проекту, если таковые имеются, для вывода GOPATH
.)
Ответ 5
Я не могу комментировать, но для того, чтобы построить ответ от @joshlf:
alias go
, добавив GOPATH
- мой метод не требует, чтобы вы занимались/создавали дополнительный файл:
alias go='GOPATH=$(echo $(pwd)) go'
веселит
Ответ 6
Мне нравится кишок ответа gopath() выше, но мне не нравится (a) наличие GOPATH
, установленного только для go
(я использую его в vim-плагинах и т.д.), и мне не нравится (b) не запоминать тип GOPATH
вместо go
:)
Вот что я в конечном итоге добавил в свой ~/.bash_profile
:
export GOPATH="... a default path ..."
function cd() {
builtin cd [email protected] &&
export GOPATH="$(
( while [[ $PWD != / && $(basename $PWD) != go ]]; do
cd ..
done
if [[ $PWD == / ]]; then
echo $GOPATH
else
echo $PWD
fi
))"
}
(Я также написал выше с небольшим дополнительным обсуждением требований в этом сообщении в блоге)
Ответ 7
Я новичок Golang, но лучший способ сделать это - это, вероятно, создать оболочку script в каждом из ваших проектов, построить/запустить проект и поместить этот script в свой проект root:)
#!/usr/bin/env bash
// get absolute path to the directory which contains this script
PROJECT_DIR=$(cd $(dirname $0) && pwd)
// set GOPATH as you wish, then run go build
GOPATH=${GOPATH}:${PROJECT_DIR} && cd ${PROJECT_DIR} && go build
этот script должен работать, даже если вы выполняете его из каталога, который не является корнем проекта.