Mit der Golang Version 1.11 wurde an dem Dependency Management mit der Einführung von Go Modules eine Menge gearbeitet (siehe Golang Blog). Es gibt inzwischen Diskussionen, ob die gute alte GOPATH-Variable deprecated ist und nicht mehr genutzt werden soll. Ab Golang Version 1.13 ist die GOPATH jetzt als offiziell Legacy eingestuft. Also fott damit.
Ich hatte vor einiger Zeit mal ein Golang-Projekt entwickelt, um für Prometheus Metriken bereitzustellen dies aus jeder APIs bzw. aus Splunk kommen können. Dieses Projekt habe ich jetzt als GitHub-Projekt goPrometheusMetricsCollector veröffentlicht. Damals hatte ich verschiedene Packages programmiert die aufeinander verweisen. Alle lagen ganz klassische im Golang Workspace im /src Folder vor, wie es üblich ist, wenn man die GOPATH Variable für den Projektverweis nutzt.
Da GOPATH inzwischen als deprecated gilt, bin ich gleich mal auf Golang Modules gegangen. Da deren Prinzip nicht zwingend sofort eingängig ist, habe ich diese Migration hier mal beschrieben. Ich habe IntelliJ als IDE genutzt. Aber das Prinzip ist generisch übertragbar.
content
(this table of content was created by Markdown Menu)
Schritt 1: Deaktivierung von GOPATH
Ich habe das Projekt in IntelliJ entwickelt und dort die Einträge für GOPATH auf den default Wert zurückgestellt. Zudem habe ich Go modules (vgo)
in den Projektsettings aktiviert. IntellijJ bestätigte damit auch gleich die Deaktivierung der GOPATH-Variable.
Schritt 2: Das neue Githubprojekt
Wie bereits erwähnt wollte ich aus meinem Projekt ein GitHub-Projekt basteln. Ich wusste, dass das Projekt im YOTRON Repository unter
goPrometheusMetricsCollector liegen wird, also unter https://github.com/yotron/goPrometheusMetricsCollector
. Das bedeutet,
dass der “Name” des Moduls github.com/yotron/goPrometheusMetricsCollector sein muss. Wie ihr seht wird dem Modul direkt auch das “Repository” mitgegeben.
Dies kennt man z.B. auch bei den Dockerimages, die auch immer das Repository im Namen haben, wenn es nicht aus den Standardrepo wie dockerhub stammt.
Schritt 3: Initiierung des Moduls
Als erstes muss das Modul initiiert werden. Dies erfolgt im Rootordner des neuen Moduls github.com/yotron/goPrometheusMetricsCollector. Bei mir ist es der Ordner goPrometheusMetricsCollector.
Die Initiierung erfolgt mit:
GO111MODULE=on go mod init github.com/yotron/goPrometheusMetricsCollector
Viel passiert ist nicht, außer, dass ein neues go.mod
-File für die Modulkonfiguration erstellt wird:
module github.com/yotron/goPrometheusMetricsCollector
go 1.13
Schritt 4: Auflösen des src-Ordners
Golang erwartet einen src
-Ordner im Workspace worauf die GOPATH-Variable verweist. Dieser Ordner ist
für Golang-Modules irrelevant und kann aufgelöst werden. Dieser kann einfach gelöscht werden. Wenn man eigene
Projektdateien dort abgelegt hat, könne diese in der Root-Ordner des Projektes verschoben werden.
Ab jetzt meldet IntelliJ Fehler, dass Dependencies nicht mehr gefunden werden. So ist es recht.
Schritt 5: Laden der Dependencies
Um die Dependencies für das Modul zu laden, muss im Root-Ordner des Projektes
GO111MODULE=on go get -v -t -d ./...
gefeuert werden.
In dem Zuge wird die go.mod
-Datei aktualisiert und weist jetzt alle vom Projekt genutzten Dependencies auf:
module github.com/yotron/goPrometheusMetricsCollector
go 1.13
require (
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
github.com/prometheus/client_golang v1.3.0
github.com/yotron/goConfigurableLogger v0.0.0-20200125155224-b4950fd3e34c
gopkg.in/yaml.v2 v2.2.8
)
Zudem wird eine neue Datei go.sum
erzeugt, die alle heruntergeladene Abhängigkeiten mit ihren Versionen und Hash-Werten beinhaltet.
Also auch die indirekt geladenen, also die, die über die Packages aus der go.mod-Datei geladen werden.
Schritt 6: Anpassen der Import Direktiven
Die Import-Direktiven in den einzelnen Golang-Files werfen noch immer Fehler. Diese müssen jetzt so umgestellt werden, als würden Sie aus einem Repository stammen.
Beispiel: In der main.go-Datei im Root-Ordner habe ich die Packages collector
und common
als Abhängigkeit.
import (
...
"collector"
"common"
...
)
Jetzt muss noch der GitHub-Pfad ergänzt werden.
import (
...
"github.com/yotron/goPrometheusMetricsCollector/collector"
"github.com/yotron/goPrometheusMetricsCollector/common"
...
)
Diese Änderung muss für alle Abhängigkeiten auf lokale Packages in allen Golang-Dateien erfolgen.
Bitte beachtet, dass die Änderungen greifen, obwohl noch kein Repository für das Modul besteht.
Schritt 7: Verweis auf die lokalen Packages im Golang-Modul
Das eigene Projekt muss in die go.mod
-Datei noch nachgetragen werden. Während der Entwicklung liegen aber sämtliche Packages nicht
im Repository, sondern im eigenen lokalen Ordner. Es wäre auch zu umständlich während der Entwicklung immer erst in das Repository zu pushed
bevor man testen möchte. Trotzdem müssen alle eigenen Packages auf das Modul nachkonfiguriert werden. Über die go.mod
-Datei ist es möglich eine
URL, die auf ein Repository verweist, auf einen lokalen Ordner zu referenzieren:
go mod edit -replace github.com/yotron/goPrometheusMetricsCollector=./
Damit lässt man den virtuellen Repository-Ordner auf den eigenen Root-Ordner verweisen. Die go.mod
-Datei sieht jetzt so aus:
module github.com/yotron/goPrometheusMetricsCollector
go 1.13
require (
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
github.com/prometheus/client_golang v1.3.0
github.com/yotron/goConfigurableLogger v0.0.0-20200125155224-b4950fd3e34c
gopkg.in/yaml.v2 v2.2.8
)
replace github.com/yotron/goPrometheusMetricsCollector => ./
Jetzt berücksichtigt Golang alle Änderungen im lokalen Code sofort.
Schritt 8: Start des Builds
Das wars. IntelliJ kann jetzt wieder mit dem Projekt umgehen und ein go build
funktioniert auch wieder.