Структурирование Go подпакетов для команд
В настоящее время мы перемещаем некоторые из наших кодов для Go и немного боремся с гибкой структурой каталогов для нескольких разработчиков внутри команды. Извиняюсь, если это вопрос о нобе, но я искал везде и не придумывал ответа.
Скажем, у меня есть пакет со следующей структурой:
package main
import "username/myproject/subpackage"
func main() {
}
и подпакет:
package subpackage
func main() {
}
Это прекрасно работает и, читая код других людей на Github, кажется, что это приемлемый способ определения подпакетов.
В качестве примера обратитесь к источнику CoreOS: https://github.com/coreos/etcd/blob/master/main.go
Моя проблема заключается в том, что из-за структуры каталогов Go эти пакеты хранятся в определенном репозитории git, и если кто-то из команды проверяет этот код для работы, их структура каталогов будет отличаться из-за forking, Имя пользователя в путях и операторах импорта изменится. Этому не помогает тот факт, что мы тянем и толкаем друг друга друг к другу, а не используя централизованное репо.
package main
import "otherusername/myproject/subpackage" (This line will have to be changed)
func main() {
}
Все, что я прочитал о Go, указывает на его удобство использования в командных средах, поэтому мне интересно, правильно ли я понимаю систему пакетов.
В идеале мы хотели бы иметь возможность вызывать подпакеты с относительными путями. Мы привыкли работать с пространствами имен, и я знаю, что у Go их нет. то есть:
package main
import "myproject/subpackage"
func main() {
}
Но Go не может найти файл, и я уверен, что это не правильный способ сделать это, поскольку в примерах в Интернете не используются относительные пути.
Итак, пару вопросов:
1) Если пакеты имеют определенный владелец и всегда сохраняют это имя пользователя как часть путей импорта?
2) Должен ли этот "владелец" репо представлять собой центологизированный репозиторий (например, компанию или организацию), что весь код выталкивается или вытаскивается из?
3) Если другие члены команды, работающие над фрагментом кода, используют его в папке создателей/пространстве имен, а не в своих собственных?
4) Есть ли способ определить относительные пути в операторах импорта, и если да, то почему никто этого не делает? Это считается плохой практикой?
5) Как обрабатывать репо с помощью подпакетов Go?
Спасибо.
Ответы
Ответ 1
Краткая версия:
-
Пакет всегда должен быть включен в gettable (работа с go get package
), поэтому в 99% случаев ваш пакет будет github.com/user/reponame
, и вы всегда держите это в своем проекте.
-
Да, это должно быть центральное репо и вкладчик (внутренний сотрудник или сообщество) должны создавать запрос на перенос для этого репо, никогда на самом деле не работать на нем.
-
Да, они должны использовать его в исходной папке с помощью git remote forked (см. ниже)
-
Нет и Да. Вы можете определить относительный импорт для пакета без go-gettable. То есть когда вы не находитесь в своем гопате, вы можете import "./subpackage"
. Однако, если вы перейдете на свой GOPATH, Go будет жаловаться на то, что вы смешиваете локальный и удаленный импорт. В общем случае не используйте относительный импорт.
-
При загрузке подпакета обрабатывается основной пакет.
Длинная версия:
Я возьму, например, репозиторий Github с несколькими членами команды.
Центральное репо было бы http://github.com/central/repo
В этом репо есть субрепозиции, такие как github.com/central/repo/pkg, github.com/central/repo/whatever.
Самый простой способ и ИМХО - лучший способ использовать удаленный git.
Скажем, я хочу внести вклад в подрепо (или что-нибудь в этом отношении), процесс прост: так же, как на любом другом языке, fork repo.
Теперь, как вы упомянули, у вас есть копия репозитория с импортом, который нацелен на центральный. Не очень практично работать с действительно.
Вот почему (ожидайте для простых небольших проектов), я никогда не go get
моя вилка, я go get
центральный репозиторий, перейдите к $GOPATH/src/github.com/central/repo
и добавьте мой пульт с git remote add creack https://github.com/creack/repo
Теперь я могу работать над проектом, использовать его, как если бы он был центральным, и как только я закончил, я нажимаю свою ветку на свою вилку, а затем создаю запрос на растяжение.
В этом случае fork является только заполнителем для источников на github и не используется.