Übersicht

Dies ist ein grundlegendes Layout für Go-Anwendungsprojekte. Es handelt sich nicht um einen offiziell definierten Standard des Go-Kernentwicklungsteams; es handelt sich um eine häufig verwendete Verzeichnisanordnung für Community-Go-Projekte.

Wenn Sie Go lernen oder einen Proof of Concept (PoC) oder ein einfaches persönliches Projekt erstellen, ist dieses Projektlayout zu kompliziert. Beginnen Sie stattdessen mit einem wirklich einfachen Layout (nur eine main.go -Datei und go.mod is genug). Wenn Ihr Projekt wächst, stellen Sie sicher, dass Ihre Code-Struktur gut ist, da Sie sonst mit unordentlichem Code enden, der viele versteckte Abhängigkeiten und globalen Zustand enthält. Wenn mehr Menschen am Projekt beteiligt sind, benötigen Sie eine strukturiertere Herangehensweise. In diesem Fall ist es wichtig, einen gemeinsamen Weg zur Verwaltung von Paketen/Bibliotheken einzuführen. Wenn Sie ein Open-Source-Projekt haben oder wissen, dass andere Projekte Code aus Ihrem Projektrepository importieren, werden private (auch als internal bezeichnete) Pakete und Code wichtig. Klonen Sie das Repository, behalten Sie die Teile, die Sie brauchen, und löschen Sie alles andere! Nur weil es vorhanden ist, heißt das nicht, dass Sie alles verwenden müssen. Keines dieser Muster wird in jedem Projekt verwendet. Selbst das vendor-Muster ist nicht universell.

Diese Projektstruktur ist absichtlich sehr allgemein gehalten und versucht nicht, eine spezifische Go-Paketstruktur vorzuschreiben.

Spezifikation des Go-Projektverzeichnisses

Nachstehend finden Sie die empfohlene Spezifikation des Go-Projektverzeichnisses.

.
├── go.mod
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

Die Bedeutung jedes Verzeichnisses wird unten erläutert.

/cmd

Die Hauptanwendungen für das Projekt, d.h. der Einstiegspunkt der Programme. Die Go-Dateien in diesem Verzeichnis generieren in der Regel ausführbare Dateien. In einem einfachen Projekt kann eine Datei wie /test/main.go als Einstiegspunkt dienen.

Der Verzeichnisname für jede Anwendung sollte dem Namen der ausführbaren Datei entsprechen, die Sie möchten (z.B. /cmd/myapp).

Geben Sie nicht zu viel Code im Anwendungsverzeichnis an. Wenn Sie denken, dass der Code importiert und in anderen Projekten verwendet werden kann, fügen Sie ihn in das /pkg-Verzeichnis ein. Wenn der Code nicht wiederverwendbar ist oder Sie nicht möchten, dass andere ihn verwenden, platzieren Sie ihn im /internal-Verzeichnis. Sie werden überrascht sein von dem Verhalten anderer Menschen, geben Sie also Ihre Absicht deutlich wieder!

In der Regel gibt es eine kleine main-Funktion, die Code aus den Verzeichnissen /internal und /pkg importiert und aufruft, und nichts anderes.

/internal

Privater Anwendungs- und Bibliothekscode. Dies ist der Code, den Sie nicht möchten, dass andere ihn in ihre Anwendungen oder Bibliotheken importieren. Beachten Sie, dass dieses Layoutmuster vom Go-Compiler selbst durchgesetzt wird. Für genauere Informationen lesen Sie bitte die Versionshinweise für Go 1.4 nach. Beachten Sie, dass dies nicht auf das Top-Level-Verzeichnis internal beschränkt ist. Sie können mehrere internal-Verzeichnisse auf jeder Ebene des Projektbaums haben.

Sie können sich dafür entscheiden, eine zusätzliche Struktur für interne Pakete hinzuzufügen, um zwischen freigegebenem und nicht freigegebenem internen Code zu unterscheiden. Dies ist nicht erforderlich (insbesondere für kleinere Projekte), aber die visuelle Darstellung der beabsichtigten Verwendung von Paketen ist eine gute Praxis. Ihr tatsächlicher Anwendungscode kann im Verzeichnis /internal/app platziert werden (zum Beispiel /internal/app/myapp), und der gemeinsam genutzte Code für diese Anwendungen kann im Verzeichnis /internal/pkg platziert werden (zum Beispiel /internal/pkg/myprivlib).

/pkg

Bibliothekscode, der von externen Anwendungen verwendet werden kann (z.B. /pkg/mypubliclib). Andere Projekte werden diese Bibliotheken importieren und erwarten, dass sie ordnungsgemäß funktionieren, also überlegen Sie gut, bevor Sie hier Inhalte platzieren :-) Beachten Sie, dass das internal-Verzeichnis eine bessere Möglichkeit ist, sicherzustellen, dass private Pakete nicht importiert werden können, da es von Go selbst durchgesetzt wird. Das Verzeichnis /pkg ist dennoch eine gute Möglichkeit, explizit zu vermitteln, dass der Code in diesem Verzeichnis für andere sicher zu verwenden ist.

Wenn Ihr Anwendungsprojekt sehr klein ist und die mehrstufige Verschachtelung nicht viel Wert hinzufügt, ist es auch in Ordnung, sie nicht zu verwenden (es sei denn, Sie möchten es wirklich verwenden :-)). Wenn das Projekt groß genug wird und das Stammverzeichnis sehr beschäftigt wird, sollten Sie dies in Betracht ziehen (insbesondere wenn Sie viele nicht-Go-Anwendungskomponenten haben).

/vendor

Anwendungsabhängigkeiten (manuell verwaltet oder unter Verwendung Ihres bevorzugten Abhängigkeitsverwaltungstools, wie z.B. das integrierte Go Modules-Feature). Der Befehl go mod vendor erstellt das Verzeichnis /vendor für Sie. Beachten Sie, dass Sie, wenn Sie nicht die standardmäßig aktivierten Go 1.14 Version verwenden, möglicherweise den -mod=vendor-Flag dem go build-Befehl hinzufügen müssen.

Wenn Sie eine Bibliothek erstellen, sollten Sie Ihre Anwendungsabhängigkeiten nicht commiten.

Dienstanwendungsverzeichnisse

/api

OpenAPI/Swagger-Spezifikationen, JSON-Schemadateien, Protokolldefinitionen und API-Protokollverzeichnisse.

Webanwendungsverzeichnisse

/web

Spezifische Komponenten für Webanwendungen: Assets für statische Websites, serverseitige Vorlagen und Single-Page-Anwendungen (SPAs).

Allgemeine Anwendungsverzeichnisse

/configs

Konfigurationsdateivorlagen oder Standardkonfigurationen.

Platzieren Sie Ihre confd- oder consul-template-Vorlagendateien hier.

/init

Systeminitialisierung (systemd, upstart, sysv) und Prozessmanager/Daemon (runit, supervisord) Konfigurationen.

/scripts

Skripte für verschiedene Build-, Installations-, Analyse- und andere Operationen.

/build

Paketierung und kontinuierliche Integration.

Platzieren Sie die Konfigurationen und Skripte für Cloud (AMI), Container (Docker), Betriebssystem (deb, rpm, pkg) im Verzeichnis /build/package.

Platzieren Sie die Konfigurationen und Skripte für kontinuierliche Integrationstools (Travis, Circle, Drone) im Verzeichnis /build/ci. Bitte beachten Sie, dass bestimmte kontinuierliche Integrationstools (wie Travis CI) sehr spezifisch hinsichtlich des Speicherorts ihrer Konfigurationsdateien sind. Versuchen Sie, die Konfigurationsdateien im Verzeichnis /build/ci zu platzieren und verwenden Sie Links, um sie mit dem Speicherort zu verbinden, der von den kontinuierlichen Integrationstools erwartet wird (falls möglich).

/deployments

Bereitstellungskonfigurationen und Vorlagen für IaaS, PaaS, System- und Containerorchestrierung (docker-compose, kubernetes/helm, terraform). Bitte beachten Sie, dass in einigen Repositories (insbesondere für Anwendungen, die mithilfe von Kubernetes bereitgestellt werden) dieses Verzeichnis /deploy genannt wird.

/test

Andere externe Testanwendungen und Testdaten. Organisieren Sie das Verzeichnis /test nach Ihren Bedürfnissen. Bei größeren Projekten macht es Sinn, Daten in Unterverzeichnisse zu organisieren. Sie können beispielsweise Verzeichnisse wie /test/data oder /test/testdata innerhalb von /test erstellen, um Go dazu zu bringen, den Inhalt zu ignorieren. Bitte beachten Sie, dass Go auch Verzeichnisse oder Dateien ignoriert, die mit "." oder "_" beginnen, was eine größere Flexibilität bei der Benennung von Testdatenverzeichnissen bietet.

Andere Verzeichnisse

/docs

Entwurfs- und Benutzerdokumentation (außer den von Ihnen generierten godoc-Dokumenten).

/tools

Unterstützende Tools für dieses Projekt. Bitte beachten Sie, dass diese Tools Code aus den Verzeichnissen /pkg und /internal importieren können.

/examples

Beispiele für Anwendungen und/oder öffentliche Bibliotheken.

/third_party

Externe Hilfstools, geforkter Code und andere Drittanbieter-Dienstprogrammtools (z.B. Swagger UI).

/githooks

Git Hooks.

/assets

Zusätzliche Assets (Bilder, Logos usw.), die mit dem Repository bereitgestellt werden.

/website

Speicherort für die Daten der Projektwebsite, wenn Sie GitHub Pages nicht verwenden.

/src

Einige Go-Projekte können ein src-Verzeichnis haben, was jedoch typischerweise darauf zurückzuführen ist, dass Entwickler aus der Java-Welt stammen, wo dies ein gängiges Muster ist. Versuchen Sie, dieses Java-ähnliche Muster zu vermeiden, wenn möglich. Sie möchten wirklich nicht, dass Ihr Go-Code oder Ihr Projekt wie Java aussieht :-)

Verwechseln Sie das projektweite /src-Verzeichnis nicht mit dem für den Go-Workspace verwendeten /src-Verzeichnis, das in How to Write Go Code beschrieben ist. Die Umgebungsvariable $GOPATH zeigt auf Ihren (aktuellen) Workspace (standardmäßig zeigt sie auf das Verzeichnis $HOME/go auf Nicht-Windows-Systemen). Dieser Workspace enthält die Top-Level-Verzeichnisse /pkg, /bin und /src. Ihr tatsächliches Projekt wird ein Unterverzeichnis unter dem Verzeichnis /src sein. Wenn Ihr Projekt also ein /src-Verzeichnis hat, sieht der Projekt-Pfad so aus: /some/path/to/workspace/src/your_project/src/your_code.go. Bitte beachten Sie, dass Ihr Projekt ab Go 1.11 außerhalb des GOPATH liegen kann, aber das bedeutet nicht, dass die Verwendung dieses Layoutmusters eine gute Idee ist.