Golang - Migration von Workspaces zu Golang Modules

drawing

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.

logs

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.

Interessiert? Klingen Sie einfach durch.

Jörn Kleinbub

Die YOTRON GmbH wird von Jörn Kleinbub gegründet. Ein Berater für Datenmanagement, IT-Automatisierung, DevOps und Cloud Management mit Erfahrung in einer Vielzahl von Projekten für viele verschiedene Kunden in unterschiedlichen Branchen.

Verlassen des Chats? / Leaving Chat?

Sie verlieren die aktuelle Chatkommunikation. / You are losing the current chat communication.

Send
Read the GDPR/DSGVO