Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

23 KiB

Standard Go Project Layout

Translations:

Overview

Это базовый макет организации проектов, разработанных на Golang. Это не официально определенный командой разработчиков Golang стандарт, однако он удовлетворяет исторически сложившимся шаблонам организации проекта в экосистеме Golang. Некоторые из шаблонов могут быть известнее остальных. В макете также присутствуют несколько улучшений, включая дополнительные директории, используемые в любом достаточно большом реальном приложении.

Если вы пытаетесь изучить Golang или собрать маленький обучающий проект для личного пользования, данный макет будет явным перебором. Стоит начать с чего-нибудь действительно простого (одного файла main.go будет достаточно). Как только ваш проект начнет расти, стоит задуматься о важности содержания кода в структурированном состоянии, чтобы в конечном итоге не получить грязный код с множеством скрытых зависимостей и global state. А когда над проектом начнут работать другие люди - понадобится еще большая структуризация. В этот момент важно определить стандартный путь организации пакетов/библиотек. Если вы разрабатываете проект с открытым исходным кодом или знаете, что вашим кодом будут пользоваться при разработке других проектов, необходимо понимать важность создания личных, внутренних (или internal) пакетов и кода. Клонируйте репозиторий, пользуйтесь тем, что действительно нужно, и удалите всё остальное! Наличие этого “всего остального” вовсе не означает, что это обязательно использовать. Заметьте, что ни один из этих шаблонов не обязан быть использован в абсолютно каждом проекте. Даже vendor не может быть универсален во всех случаях.

С выходом обновления Golang 1.14, Go Modules стали наконец-то доступны для использования. Применяйте Go Modules везде, пока не столкнётесь с веской причиной отказаться от них, и если такой момент всё же настанет - вам больше не придётся волноваться о значении переменной окружения $GOPATH и месте, где вы размещаете свой проект. Базовый go.mod файл в репозитории показывает, что ваш проект размещён на GitHub, однако он не является обязательным. Путь к модулю может быть любым, при условии, что первый компонент пути должен содержать точку в имени (текущая версия Golang больше не требует этого, но если вы используете достаточно устаревшие версии - не стоит удивляться, что ваши сборки могу перестать работать). Ознакомьтесь с проблемами: 37554 и 32819 если хотите узнать об этом больше.

Этот шаблон организации проекта намеренно сделан обобщенным, и не является примером структуры какого-то конкретного пакета Golang.

Этот репозиторий открыт к усилиям сообщества. Создайте заявку о проблеме, если вы нашли новый шаблон или считаете, что один из существующих шаблонов необходимо обновить.

Если вам нужна помощь в наименовании, форматировании или стилизации кода - начните с gofmt и golint. Также обязательно прочтите эти руководства по стилизации кода Golang и рекомендации:

Обратите внимание на Шаблон проекта Golang для получения дополнительной информации.

Еще больше про наименование и организацию пакетов, а так же про структуру кода можно узнать здесь:

Пост о руководствах по пакетноориентированному дизайну и макетам архитектур

Директории Go

/cmd

Основные приложения проекта.

Имя директории для каждого приложения должно совпадать с именем исполняемого файла, который вы хотите собрать (например, /cmd/myapp).

Не стоит располагать в этой директории большие объёмы кода. Если вы предполагаете дальнейшее использование кода в других проектах, вам стоит хранить его в директории /pkg в корне проекта. Если же код не должен быть переиспользован где-то еще - ему самое место в директории /internal в корне проекта. Вы будете удивлены тем, что другие люди могут сделать, поэтому будьте уверены в своих намерениях!

Самой распространнёной практикой является использование маленькой main функции, которая импортирует и вызывает весь необходимый код из директорий /internal и /pkg и никаких других.

Ознакомьтесь с директорией /cmd для примера.

/internal

Внутренний код приложения и библиотек. Это код, который не должен быть применен в других приложениях и библиотеках. Стоит отметить, что этот шаблон навязан самим компилятором Golang. Ознакомьтесь с release notes Go 1.4. Также, вы вольны использовать internal директорию на разных уровнях своего проекта.

Вы можете добавить дополнительное структурирование, чтобы разделить открытую и закрытую части вашего внутреннего кода. Такой подход не является необходимым, особенно для маленьких проектов, но позволяет сразу визуально оценить применение кода. Код самого приложения может находиться в директории /internal/app (например, /internal/app/myapp), а код, который это приложение использует - в директории /internal/pkg (например, /internal/pkg/myprivlib).

/pkg

Код библиотек, пригодных для использования в сторонних приложениях. (например, /pkg/mypubliclib). Другие проекты будут импортировать эти библиотеки, ожидая их автономной работы, поэтому стоит подумать дважды, прежде чем класть сюда какой-нибудь код :-) Заметьте, что использование директории internal - более оптимальный способ не дать импортировать внутренние пакеты, потому что это обеспечит сам Golang. Директория /pkg - всё еще хороший путь дать понять, что код в этой директории могут безопасно использовать другие. Пост I'll take pkg over internal в блоге Трэвиса Джеффери предоставляет хороший обзор директорий pkg и internal и когда есть смысл их использовать.

Существует возможность группировать код на Golang в одном месте, когда ваша корневая директория содержит множество не относящихся к Go компонентов и директорий, что позволит облегчить работу с разными инструментами Go (как упомянуто в этих разговорах: Best Practices for Industrial Programming с GopherCon EU 2018, GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps и GoLab 2018 - Massimiliano Pippi - Project layout patterns in Go).

Ознакомьтесь с директорией /pkg, если хотите увидеть, какие популярные репозитории используют такой шаблон организации проекта. Несмотря на его распространенность, он не был принят всеми, а некоторые в сообществе Go и вовсе не рекомендует его использовать.

Вы можете не использовать эту директорию, если проект совсем небольшой и добавление нового уровня вложенности не имеет практического смысла (разве что вы сами этого не хотите :-)). Подумайте об этом, когда ваша корневая директория начинает слишком сильно разрастаться, особенно, если у вас много компонентов, написанных не на Go.

/vendor

Зависимости приложений, управляемые вручную или с использованием вашей любимой системы управления зависимостями, вроде новых встроенных Go Modules). Команда go mod vendor создаст для вас директорию /vendor. Заметьте, что вам возможно придётся добавить флаг -mod=vendor к команде go build, если вы используете версию, отличную от Go 1.14, где такой флаг выставлен по-умолчанию.

Не стоит отправлять зависимости вашего приложения в репозиторий, если собираетесь создавать библиотеку.

Стоит отметить, что с версии 1.13 Go добавил возможность проксирования модулей (с использованием https://proxy.golang.org как прокси-сервера по-умолчанию). Здесь можно побольше узнать про эту возможность, чтобы убедиться, что она удовлетворяет вашим необходимостям и ограничениям. Если это так - использование директории vendor не требуется вовсе.

Директории приложений-сервисов

/api

Спецификации OpenAPI/Swagger, файлы JSON schema, файлы определения протоколов.

Ознакомьтесь с директорией /api для примеров.

Директории Веб-приложений

/web

Специальные компоненты для веб-приложений: статические веб-ресурсы, серверные шаблоны и одностраничные приложения.

Распространенные директории

/configs

Шаблоны файлов конфигураций и файлы настроек по-умолчанию.

Положите файлы конфигураций confd или consul-template сюда.

/init

Файлы конфигураций для процессов инициализации системы (systemd, upstart, sysv) и менеджеров процессов (runit, supervisord).

/scripts

Скрипты для сборки, установки, анализа и прочих операций над проектом.

Эти скрипты позволяют оставить основной Makefile небольшим и простым (например, https://github.com/hashicorp/terraform/blob/master/Makefile).

Ознакомьтесь с директорией /scripts для примеров.

/build

Сборка и непрерывная интеграция (Continuous Integration, CI).

Поместите файлы конфигурации и скрипты облака (AMI), контейнера (Docker), пакетов (deb, rpm, pkg) в директорию /build/package.

Поместите ваши файлы конфигурации CI (travis, circle, drone) и скрипты в директорию /build/ci. Заметьте, что некоторые инструменты CI (например, Travis CI) очень требовательны к расположению их конфигурационных файлов. Попробуйте поместить их в директорию /build/ci создав ссылку на них в месте, где их ожидают найти инструменты Go (если возможно).

/deployments

Шаблоны и файлы конфигураций систем оркестраций IaaS, PaaS, операционных систем и контейнеров (docker-compose, kubernetes/helm, mesos, terraform, bosh). Отметьте, что в некоторых репозиториях, особенно в приложениях, развернутых с использованием Kubernetes, эта директория называется /deploy.

/test

Дополнительные внешние приложения и данные для тестирования. Вы вольны организовывать структуру директории /test так, как вам угодно. Для больших проектов имеет смысл создавать вложенную директорию с данными для тестов. Например,/test/data или /test/testdata, если вы хотите, чтобы Go игнорировал находящиеся там файлы. Отметьте, что Go будет также игнорировать файлы, путь к которым начинается с “.” или “_", что предоставляет вам гибкость в наименовании вашей папки с тестами.

Ознакомьтесь с директорией /test для примеров.

Другие Директории

/docs

Документы пользователей и дизайна (в дополнение к автоматической документации godoc).

Ознакомьтесь с директорией /docs для примеров.

/tools

Инструменты поддержки проекта. Отметьте, что эти инструменты могут импортировать код из директорий /pkg и /internal.

Ознакомьтесь с директорией /tools для примеров.

/examples

Примеры ваших приложений и/или библиотек.

Ознакомьтесь с директорией /examples для примеров.

/third_party

Внешние вспомогательные инструменты, ответвления кода и другие сторонние утилиты (например, Swagger UI).

/githooks

Git hooks.

/assets

Другие ресурсы, необходимые для работы (картинки, логотипы и т.д.)

/website

Здесь можно разделить файлы для вебсайта вашего проекта, если вы не используете GitHub pages.

Ознакомьтесь с директорией /website для примеров.

Директории, которые не стоит размещать у себя в проекте

/src

Некоторые проекты на Go имеют директорию src, но это обычно происходит, когда разработкой занялся человек, пришедший из мира Java, где такой подход весьма распространен. Постарайтесь не использовать его в разработке на Golang, если не хотите, чтобы ваш код или проект выглядел, будто написан на Java :-).

Не путайте директорию уровня проекта /src с директорией /src, которую Go использует для своих рабочих пространств, как это описано в How to Write Go Code. Переменная окружения $GOPATH указывает на ваше текущее рабочее пространство (по-умолчанию - $HOME/go на системах под управлением ОС, отличной от Windows). Это рабочее пространство включает высокоуровневые директории /pkg, /bin и /src. Ваш проект в свою очередь находится во вложенной в /src директории, поэтому если вы имеете директорию /src внутри вашего проекта, путь к нему будет выглядеть примерно так: /some/path/to/workspace/src/your_project/src/your_code.go. Отметьте, что в версиях после Go 1.11 возможно хранить проект отдельно от локации, описанной в GOPATH, но это всё еще не значит, что применять этот Java-шаблон - хорошая идея.

Badges

  • Go Report Card - Просканирует ваш код с помощью gofmt, go vet, gocyclo, golint, ineffassign, license и misspell. Замените github.com/golang-standards/project-layout на ссылку на ваш проект.

    Go Report Card

  • GoDoc - Предоставит онлайн версию вашей сгенерированной GoDoc документации

    Go Doc

  • Pkg.go.dev - Pkg.go.dev is a new destination for Go discovery & docs. You can create a badge using the badge generation tool.

    PkgGoDev

  • Release - Покажет версию последнего релиза вашего проекта.

    Release