Существует крупный проект с большим количеством файлов, которых уже слишком много в корневом каталоге. К тому-же было бы неплохо отделить мух от котлет, контроллеры от моделей и т.д., вынести их в отдельный каталог. Но есть "но".
Go предоставляет возможность создавать подпакеты, с двумя сособами их импорта.
Импорт с относительными путями: import "./sub-package"
Go-сообществом считается плохой идеей, к тому же не работает, если проект находится в каталоге $GOPATH.
Импорт с указанием родительского пакета import "github.com/user/main-package/sub-package"
Чаще всего это наилучший способ, но проекты фирмы находятся не на github, а в закрытом репозитории, который не поддерживает go get, а админы при деплое могут склонировать репозиторий не только в $GOPATH/src, но и в $GOPATH/src/CompanyApps или вообще в /srv. В таком случае import "package/subpackage" сломается. Не говоря уже о том, что в конторе десяток разрабов и в какую папку склонируют пакет к себе можно узнать только по крикам, что проект не собирается.
UPD: Вторая ситуация - при форке такого проекта все секции import указывают на подпакеты оригинального проекта, изменения в котором могут сломать форк.
Хотелось бы услышать оптимальный способ решения таких задач.
для крупных проектов использую директорию vendor, причем код разрабатываемого приложения тамже, пример:
GOPATH = ~/go
~/go/src/.../PROJECT/vendor/projectName/
~/go/src/.../PROJECT/vendor/projectName/projectName.go - package main
~/go/src/.../PROJECT/vendor/projectName/controllers/
~/go/src/.../PROJECT/vendor/projectName/models/
~/go/src/.../PROJECT/vendor/projectName/templates/
...
~/go/src/.../PROJECT/vendor/someutil/
~/go/src/.../PROJECT/vendor/github.com/user/package/
~/go/src/.../PROJECT/assets/
~/go/src/.../PROJECT/testdata/
~/go/src/.../PROJECT/ - тут лежат бинарники, конфиг файлы, Makefile ит.д.
подобная структура позволяет иметь в проекте "красивые" пути к внутренним компонентам проекта - контролерам, моделям ит.д.
позволяет иметь локальные версии каких-то внешних пакетов
и в тоже самое время позволяет импортировать внешние пакеты не перенося их в директорию vendor
С закрытыми репо не умеет 'go get'. После клонирования в нужное место '$GOPARH/src/package/subpackage' посредством git (или rsync) команды 'go build', 'go install', 'go run' работают как ни в чем не бывало. import "package/subpackage"
GOPATH - это лист так же как и PATH, перечень список возможно нескольких путей. Валидно export GOPATH=$GOPATH:"/srv"
Проблема в человеческом факторе. Понятно, что можно написать в README, чтобы админы и девелоперы ложили пакет в $GOPATH/src, но тогда кто-нибудь додумается переименовать каталог, и т.д. Идем дальше - возникает необходимость форкнуть проект, который использует свои подпакеты. Но в import секциях останутся подпакеты старого репозитория, и большой шанс, что в результате правок исходного проекта может сломаться форк. Идеальным вариантом было бы что-то типа import "$SELF/subpackage", но такого, к сожалению нет, как я понимаю..
Олексiй Чечель В принципе вы можете сделать работу за devops при помощи команды go generate
директивой вроде //go:generate sed s/SELF/TrueImportPathObtainedWithPWD/
мне лично такое не нравится, лучше написать в README