Обзор
Это основной макет для проектов приложений на Go. Это не официально определенный стандарт командой разработки Go. Это общепринятая структура каталогов для проектов Go в сообществе
.
Если вы изучаете Go или создаете концепцию (PoC) или просто личный проект, этот макет проекта слишком сложен. Вместо этого начните с действительно простого макета (только
main.go файл и
go.mod достаточно).
По мере развития вашего проекта убедитесь, что ваша структура кода хороша, иначе вы получите запутанный код с большим количеством скрытых зависимостей и глобального состояния. Когда в проект вовлекается больше людей, вам потребуется более структурированный подход. В этом случае важно внедрить общепринятые способы управления пакетами/библиотеками. Когда у вас есть проект с открытым исходным кодом или вы знаете, что другие проекты импортируют код из вашего репозитория проекта, становится важным иметь частные (также известные как internal
) пакеты и код. Клонируйте репозиторий, сохраните нужные части и удалите все остальное! Просто потому что что-то существует, не обязательно использовать все. Ни один из этих шаблонов не используется в каждом проекте. Даже шаблон vendor
не универсален.
Этот макет проекта преднамеренно разработан очень общим и не пытается навязать конкретную структуру пакета Go.
Спецификация каталога проекта Go
Ниже приведена рекомендуемая спецификация каталога проекта Go.
.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website
Ниже приведены значения каждого каталога.
/cmd
Главные приложения проекта, т.е. точки входа программ. Файлы Go в этой директории обычно генерируют исполняемые файлы. В простом проекте файл вроде /test/main.go может служить точкой входа.
Имя директории для каждого приложения должно соответствовать имени исполняемого файла, который вы хотите (например, /cmd/myapp
).
Не помещайте слишком много кода в директорию приложения. Если вы считаете, что код можно импортировать и использовать в других проектах, поместите его в директорию /pkg
. Если код не подлежит повторному использованию или вы не хотите, чтобы им пользовались другие, поместите код в директорию /internal
. Вы удивитесь поведению других людей, поэтому ясно выражайте свое намерение!
Обычно внутри этой директории есть небольшая main
функция, которая импортирует и вызывает код из директории /internal
и /pkg
, и больше ничего.
/internal
Приватный приложенческий и библиотечный код. Это код, который вы не хотите, чтобы другие импортировали в свои приложения или библиотеки. Обратите внимание, что этот шаблон структуры обязателен самим компилятором Go. Для более подробной информации обратитесь к заметкам к релизу для Go 1.4. Обратите внимание, что это не ограничивается только верхним уровнем директории internal
. Вы можете иметь несколько internal
директорий на любом уровне дерева проекта.
Вы можете выбрать добавлчить дополнительные структуры для внутренних пакетов с целью различения между общим и непубличным внутренним кодом. Это не обязательно (особенно для небольших проектов), но визуальное демонстрирование предполагаемого использования пакетов - хорошая практика. Фактический код вашего приложения может находиться в директории /internal/app
(например, /internal/app/myapp
), а общий код для этих приложений может размещаться в директории /internal/pkg
(например, /internal/pkg/myprivlib
).
/pkg
Библиотечный код, который может быть использован внешними приложениями (например, /pkg/mypubliclib
). Другие проекты будут импортировать эти библиотеки и ожидать, что они будут работать правильно, поэтому перед размещением содержимого здесь хорошо подумайте :-) Обратите внимание, что директория internal
- лучший способ обеспечивать, что приватные пакеты не могут быть импортированы, так как это принудительно устанавливается самим Go. Директория /pkg
все равно хороший способ явно передать, что код в этой директории безопасен для использования другими.
Если ваш проект приложения очень мал и многоуровневая вложенность не добавляет много ценности, то это тоже нормально (если вы действительно не хотите этого :-)). Когда проект становится достаточно большим и корневая директория становится очень оживленной, рассмотрите его использование (особенно если у вас множество не-Go компонентов приложений).
/vendor
Зависимости приложения (управляемые вручную или с использованием выбранного вами инструмента управления зависимостями, такого как встроенная функция Go Modules
). Команда go mod vendor
создаст для вас каталог /vendor
. Обратите внимание, что если вы не используете включенную по умолчанию версию Go 1.14, вам может потребоваться добавить флаг -mod=vendor
к команде go build
.
Если вы создаете библиотеку, пожалуйста, не включайте зависимости вашего приложения.
Каталоги Приложений Сервисов
/api
Спецификации OpenAPI/Swagger, файлы схемы JSON, файлы определения протокола и каталоги протокола API.
Каталоги Веб-Приложений
/web
Отдельные компоненты для веб-приложений: статические ресурсы веб-сайта, серверные шаблоны и одностраничные приложения (SPA).
Общие Каталоги Приложений
/configs
Шаблоны файлов конфигурации или конфигурации по умолчанию.
Разместите здесь файлы шаблонов confd
или consul-template
.
/init
Инициализация системы (systemd, upstart, sysv) и конфигурации менеджера процессов/демона (runit, supervisord).
/scripts
Скрипты для различных операций сборки, установки, анализа и других операций.
/build
Упаковка и непрерывная интеграция.
Разместите конфигурации облачного (AMI), контейнерного (Docker), операционной системы (deb, rpm, pkg) и скрипты в каталоге /build/package
.
Разместите конфигурации и скрипты непрерывной интеграции (travis, circle, drone) в каталоге /build/ci
. Обратите внимание, что определенные инструменты непрерывной интеграции (например, Travis CI) очень требовательны к расположению их конфигурационных файлов. Попытайтесь разместить файлы конфигурации в каталоге /build/ci
и использовать ссылки для подключения их к ожидаемому местоположению инструментов непрерывной интеграции (если это возможно).
/deployments
Конфигурации развертывания и шаблоны для IaaS, PaaS, системы и оркестрации контейнеров (docker-compose, kubernetes/helm, terraform). Обратите внимание, что в некоторых репозиториях (особенно для приложений, развернутых с использованием Kubernetes) этот каталог называется /deploy
.
/test
Другие внешние приложения тестирования и тестовые данные. Вы можете организовать каталог /test
так, как вам удобно. Для крупных проектов имеет смысл организовать данные в подкаталоги. Например, вы можете создать каталоги /test/data
или /test/testdata
внутри /test
, чтобы игнорировать содержимое Go. Пожалуйста, обратите внимание, что Go также игнорирует каталоги или файлы, начинающиеся с "." или "_", что обеспечивает большую гибкость в именовании каталогов с тестовыми данными.
Другие Каталоги
/docs
Документация по дизайну и пользователя (кроме документов godoc, которые вы генерируете).
/tools
Вспомогательные инструменты для этого проекта. Обратите внимание, что эти инструменты могут импортировать код из каталогов /pkg
и /internal
.
/examples
Примеры для приложений и/или общедоступных библиотек.
/third_party
Внешние служебные инструменты, форкнутый код и другие сторонние утилиты (например, Swagger UI).
/githooks
Утилиты Git.
/assets
Дополнительные ресурсы (изображения, логотипы и т. д.), предоставленные с репозиторием.
/website
Место для хранения данных веб-сайта проекта, если вы не используете GitHub Pages.
/src
Некоторые проекты на Go могут иметь папку src
, но это обусловлено в основном тем, что разработчики приходят из мира Java, где это обычная практика. Пожалуйста, если возможно, постарайтесь избежать принятия этого подобного Java-подобного шаблона. Действительно, вы не хотите, чтобы ваш код на Go или ваш проект выглядел как Java :-)
Не путайте каталог уровня проекта /src
с каталогом /src
, используемым для рабочего пространства Go, описанного в Как писать код на Go
. Переменная среды $GOPATH
указывает на ваше (текущее) рабочее пространство (по умолчанию на системах, отличных от Windows, она указывает на каталог $HOME/go
). В это рабочее пространство входят верхнеуровневые каталоги /pkg
, /bin
и /src
. Ваш фактический проект будет подкаталогом в каталоге /src
, поэтому, если у вас есть каталог /src
в проекте, путь проекта будет выглядеть так: /some/path/to/workspace/src/your_project/src/your_code.go
. Обратите внимание, что начиная с Go 1.11, ваш проект может находиться за пределами GOPATH
, но это не означает, что использование этого шаблона расположения - это хорошая идея.