Comments 22
Позволяет сделать в проекте подобие системы модулей.
Project
.../.godeps/… (Или любая другая папка от менеджера пакетов)
.../bin/…
.../pkg/…
.../src/moduleone
.../src/moduletwo
...main.go
Обычно, чтобы не скачивать все барахло и не тащить его за собой на продакшен, применяются менеджеры пакетов, а они, как правило — применяются в той самой архитектуре, что я дал выше. Исключений не видел, либо их просто нету.
Вы можете написать, что можно составить список «go get» для себя и использовать его на продакшене, но когда речь заходит о контроле версий существующих пакетов при разработке — то он становится бесполезным.
1) отдельный GOPATH для отдельного проекта
2) исходники в корне GOPATH, видимо, для использования относительных путей для «модулей»
Изолированный GOPATH — с зависимостями (как с применением менеджеров пакетов, так и без) — вобщем-то, не крамольно, и для «локинга» зависимостей — даже необходимо. Но это вполне ложится на исполнение менеджерами пакетов, не обязательно выделять отдельный GOPATH для каждого проекта. Я на самом деле стараюсь не пользоваться этими менеджерами, и поддерживать код с последними версиями всех зависимых библиотек (Go-Package-Store очень помогает). Но пока еще ни разу не пришлось, собственно, «поддерживать» — все таки «обещание backward-compatibility» достаточно хорошо и на авторов библиотек распространяется, создает некую культуру.
Ну а второй момент — с выходом за src/ и относительными путями — это уж точно неодобрительная практика.
В конце концов, если вы захотите завтра ваш проект заопенсорсить, и выложить на github — придется всю эту конструкцию с отдельным GOPATH и относительными именами рефакторить и менять под корень.
Отдельных сущностей GOPATH не создается. Всегда есть команда, которая перенаправляет его на текущий проект с которым вы собираетесь работать.
«Ну а второй момент — с выходом за src/ и относительными путями — это уж точно неодобрительная практика.»
Если под «относительными путями» вы подразумеваете указание прямых директорий в импортах, то ничуть этого не происходит, из-за причины, описанной выше.
Так же, когда проект идет в опен-сорс, то он выкладывается в полном виде с приложенным файлом для конкретного менеджера пакетов, чтобы можно было собрать быстро и без боли.
И насчет — «backward-compatibility», не могу вешать никаких ярлыков, но вы живете в слишком прекрасной реальности. Я сам в своих библиотеках ломал зависимости и такое происходило во многих популярных, однако было заметно, когда очень долго пользуешься конкретной библиотекой.
не могу вешать никаких ярлыков, но вы живете в слишком прекрасной реальности
Но таки повесили ярлык :) Нет, я не питаю иллюзий и прекрасно понимаю, что это происходит время от времени, но давайте будем откровенны — бОльшая часть библиотек в Go все-таки уважают принцип обратной совместимости, и, насколько это возможно, стремятся не ломать API. Или же — пишут большими жирными буквами — «unstable. possible API break in the future» или что-то вроде.
И это я говорю о вообще любых библиотеках, мелких и никем не используемых, в том числе. Самые же основные, популярные вещи (вроде gorilla или mysql/mgo/amqp-драйверов) — стабильны, и ломать в них API не будут, 100%.
Вобщем, я не отрицаю надобность dependency менеджмента, но стараюсь не использовать. В приватных проектах, где GOPATH шерится с другими разработчиками — время от времени обновляю зависимости с помощью Go-Package-Store, и это да — можно называть «GOPATH per project», но project тут в общем смысле — на самом деле там много go-программ и все используют один общий GOPATH.
И да, я не готов спорить сейчас по теме version/dependency-менеджмента, поскольку все варианты не пробовал, но, насколько я понимаю, все эти решения создают отдельную поддиректорию вроде _vendor или .godeps и в ней хранят все зависимости, и её же используют как (второй) GOPATH. При этом делается это автоматически, без форсирования использовать какую-то нестандартную схему GOPATH.
Если кто-то напишет подробный пост с различиями существующих решений — будет отлично и познавательно.
Вместо продакшена, я имел ввиду локальное окружение, которое переносится куда нибудь в другое место или передается между разработчиками в своей команде.
GOPATH — это что-то вроде PYTHON_PATH, переменная, указывающая, где лежат все ваши библиотеки и исходники. То, что ваш код удобнее складывать тоже в GOPATH/src — это не обязательное требование, но естественно возникающее удобство, как только вы начинаете писать код, который а) выкладывается в open-source б) начинается использоваться в других ваших или не ваших проектах. Тогда просто нет разницы — делаете вы go get драйверу mongo или своей библиотеке.
И на самом деле GOPATH очень помогает, причем неявно, организовывать ваш код. Это просто и это удобно. С этой схемой сложно создавать хаос из исходников на компьютере. Попробуйте, и через какое-то время вы поймете, насколько это удобно. Вот тут, к примеру, один девелопер, вообще, говорит, что взял идею GOPATH на вооружение не только go-кода, но и для всего другого: mwholt.blogspot.com.es/2014/02/why-i-use-just-one-gopath.html
Адепты собирающие tip из исходников думаю все прочувствовали)))
Ну, сейчас у них есть вендоринг зависимостей.
Подкину несколько замечаний из опыта борьбы с GOPATH кутерьмой:
Если держать в GOPATH один путь, то в GOPATH/src перемешаны «свои» и «чужие» исходники и чем больше либ подключаешь, тем хуже становится.
Можно полечить двумя путями в GOPATH, что-то типаGOPATH=/home/user/work/go-imports:/home/user/work/project-name
. go get будет скачивать зависимости в первый путь, а «свои» исходники лежат по второму пути. При желании можно переносить исходники из первого во второй, чтобы поправить что-то чужое и чтобы go get не затирал изменения master-ом.
GOPATH не дружит с форками. То есть как не дружит… Обычно на github-е жмёшь Fork и делаешь clone проекта своего пользователя и логично его склонировать в GOPATH/src/github.com/user/forked-repo. Бум, бах, тут-то всё и сломалось.
Приходится применять другой алгоритм: клонировать основной проект и потом править его git remote-ы.
Можно в GOPATH указывать даже 3 пути: в первый путь go get будет качать проектные зависимости, второй — глобальный, туда можно будет перемещать зависимости, чтобы несколько проектов их использовали и третий путь к директории со «своими» исходниками.
Мульти-GOPATH не такая уж и страшная штука. Во-первых можно сделать env файл, которому делать source при переключении на другой проект (аля virtualenv). Во-вторых можно посмотреть в сторону менеджеров окружений, например, smartcd — помимо изменения GOPATH при переходе в директорию с проектом они дают ещё много возможностей.
Всё, что вы хотели знать про GOPATH и GOROOT