Что такое разумный способ компоновки проекта


У меня есть проект go, который начинает становиться все более сложным, и я хочу выложить файловую систему таким образом, чтобы уменьшить боль.

есть ли хорошие примеры того, что имеет смысл?

4 101

4 ответа:

обновление май 2013: официальная документация находится в разделе "организация код"

код должен быть внутри рабочее место.
Рабочее пространство-это иерархия каталогов с тремя каталогами в корне:

  • src содержит исходные файлы Go, организованные в пакеты (по одному пакету на каталог),
  • pkg содержит объекты пакета, и
  • bin содержит исполняемые команды.

The go tool создает исходные пакеты и устанавливает полученные двоичные файлы в pkg и bin справочники.

The src подкаталог обычно содержит несколько репозиториев управления версиями (например, для Git или Mercurial), которые отслеживают разработку одного или нескольких пакетов исходного кода.

bin/
    streak                         # command executable
    todo                           # command executable
pkg/
    linux_amd64/
        code.google.com/p/goauth2/
            oauth.a                # package object
        github.com/nf/todo/
            task.a                 # package object
src/
    code.google.com/p/goauth2/
        .hg/                       # mercurial repository metadata
        oauth/
            oauth.go               # package source
            oauth_test.go          # test source

обновление июль 2014: см."структурирование приложений в Иди" из Бен Джонсон

эта статья включает в себя такие советы, как:

отделите двоичный файл от вашего приложения

объединение и моя логика приложения в одном пакете имеет два последствия:

  • это делает мое приложение непригодным для использования в качестве библиотеки.
  • у меня может быть только одно двоичное приложение.

лучший способ я нашел, чтобы исправить это просто использовать "cmd" каталог в моем проекте, где каждый из его подкаталогов-это двоичный файл приложения.

camlistore/
  cmd/
    camget/
      main.go
    cammount/
      main.go
    camput/
      main.go
    camtool/
      main.go

библиотечное развитие

перемещение main.go file out of your root позволяет создавать приложения с точки зрения библиотеки. Ваш двоичный файл приложения-это просто клиент библиотеки вашего приложения.

иногда вы можете захотеть, чтобы пользователи взаимодействовали несколькими способами, чтобы вы создайте несколько двоичных файлов.
Например, если у вас "adder" пакет, который позволяет пользователям добавлять номера вместе, вы можете выпустить версию командной строки, а также веб-версию.
Вы можете легко сделать это, организовав свой проект следующим образом:

adder/
  adder.go
  cmd/
    adder/
      main.go
    adder-server/
      main.go

пользователи могут установить двоичные файлы приложения "adder" с помощью" go get", используя многоточие:

$ go get github.com/benbjohnson/adder/...

и вуаля, ваш пользователь "adder" и "adder-server" установлено!

не сходите с ума с подпакетами

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

  1. группируйте связанные типы и код вместе в каждом файле. Если ваши типы и функции хорошо организованы, то я считаю, что файлы, как правило, быть между 200 и 500 Слок. Это может показаться много, но я считаю, что это легко ориентироваться. 1000 SLOC обычно мой верхний предел для одного файла.
  2. организуйте самый важный тип в верхней части файла и добавьте типы с уменьшением важности в нижней части файла.
  3. как только ваше приложение начнет получать более 10 000 SLOC, вы должны серьезно оценить, можно ли его разбить на более мелкие проекты.

Примечание.: эта последняя практика не всегда хороша:

Извините, я просто не могу согласиться с этой практикой.
Разделение типа на файлы помогает управлению кодом, удобочитаемости, сопровождаемости, тестируемости.
Он также может обеспечить единую ответственность и соблюдение принципа открытости / закрытости...
Правило, запрещающее циклическую зависимость, заключается в том, чтобы заставить нас иметь четкую структуру пакетов.


(альтернативный февраль 2013, относительно src только)
Вы можете найти классический макет, проиллюстрированный в " Макет Кода GitHub":

приложение и обе библиотеки живут на Github, каждый в своем собственном репозитории.
$GOPATH это корень проекта - Каждый из ваших репозиториев Github будет проверен несколькими папками ниже $GOPATH.

ваш макет кода будет выглядеть так:

$GOPATH/
    src/
        github.com/
            jmcvetta/
                useless/
                    .git/
                    useless.go
                    useless_test.go
                    README.md
                uselessd/
                    .git/
                    uselessd.go
                    uselessd_test.go
                    README.md

каждая папка под src/github.com/jmcvetta/ - это корень отдельная проверка git.

это вызвало некоторые критические замечания, хотя, в этом reddit page:

я настоятельно рекомендую не структурировать РЕПО так, как у вас есть, он сломается"go get", что является одной из самых полезных вещей о Go.
Гораздо лучше написать свой код для людей, которые знают Go, так как они, скорее всего, будут его компилировать.
И для людей, которые этого не делают, они, по крайней мере, почувствуют язык.

поставить основной пакет в корень РЕПО.
Имейте активы в подкаталоге (чтобы все было аккуратно).
Держите мясо кода в подпакете (в случае, если кто-то хочет использовать его вне вашего двоичного файла).
Включите сценарий установки в корень репо, чтобы его было легко найти.

это все еще только двухэтапный процесс для загрузки, сборки, установки и настройки.:

  • "go get <your repo path>": загрузка и устанавливает код, с каталогом активов
  • $GOPATH/<your repo path>/setup.sh: распределяет активы в нужное место и установит службу

Я предполагаю, что с "проектом" вы не имеете в виду пакет Go, но программное обеспечение, которое вы разрабатываете. В противном случае вы можете получить помощь здесь и здесь. Однако это не так сильно отличается от написания пакетов для Go: используйте пакеты, создайте папку для каждого пакета и объедините эти пакеты в своем приложении.

чтобы построить себе мнение, вы можете посмотреть на трендовые репозитории Go на github:https://github.com/trending/go. примечательными примерами являются Кайли и Зевс.

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

есть рекомендуемый подход от авторов Golang, который определяет, как макет вашего кода лучше всего работать с инструментами go и поддерживать системы управления версиями

вы, вероятно, также должны взглянуть на это РЕПО. Он показывает много идей, как структурировать приложения go:https://github.com/golang-standards/project-layout