GoLang: Hvorfor ikke bruge GOPATH

I de tidligere versioner af Go var det nødvendigt at opsætte nogle miljøvariabler for at konfigurere den. Med tiden blev disse krav fjernet, men mange online-vejledninger nævner stadig disse variabler, hvilket skaber forvirring.

For nylig blev der frigivet en ny funktion kaldet Go Modules, som endelig gør GOPATH unødvendig. I dette indlæg vil jeg forklare, hvad GOPATH er, hvorfor Go Modules er at foretrække, og hvordan man konfigurerer et projekt til at bruge Go Modules (hvilket er overraskende nemt).

GOPATH er en miljøvariabel, der fortæller Go, hvor den skal læse og hente alle de kildefiler, den skal bruge til at kompilere dit projekt. Dette koncept er forbundet med nogle usædvanlige begrænsninger, som du ikke ser i andre programmeringssprog:

  • Det kræver, at du skriver dine Go-projekter i denne mappe, som GOPATH-variablen peger på (som standard ~/go), selv om dine andre projekter ligger et andet sted;
  • Mappehierarkiet i GOPATH-mappen skal afspejle URL’en for dit projekt. Hvis din URL f.eks. er github.com/foo/bar, skal du oprette en mappe $GOPATH/src/github.com , og derefter oprette en ny mappe inden for den: foo/ og inden for den en ny mappe bar/ . Inde i mappen bar/ skal du så lægge dit egentlige git-projekt;
  • Der er ingen indbygget måde at holde styr på versionerne af de pakker, du bruger.

Det værste problem med denne opsætning er, at den er helt anderledes end den, vi er vant til på de fleste andre programmeringssprog. Da GOPATH er en miljøvariabel, kræver det også, at brugerne ved lidt om at konfigurere dit operativsystem, hvilket er fejlbehæftet, især for begyndere.

Hvorfor skal du bruge Go Modules?

Go Modules er ikke afhængig af nogen af de ovenfor nævnte afhængigheder for opsætning af specifikke miljøvariabler, og heller ikke af kravene om at lægge dit projekt i en specifik mappe, som det er tilfældet med GOPATH.

Det er også retrokompatibelt, sikkert og nemt at bruge:

  1. Det kræver en enkelt kommando for at migrere et eksisterende projekt til at bruge Go Modules;
  2. Det påvirker kun dit udviklingsmiljø (ligesom GOPATH), så det vil ikke påvirke din produktionsimplementering på nogen måde;
  3. Det er retrokompatibelt med GOPATH, hvilket betyder, at hvis du opdaterer et projekt til at bruge Go Modules, og dine kolleger stadig foretrækker at bruge GOPATH, kan de gøre det uden problemer.

En anden grund til at lære at bruge Go Modules er, at GOPATH sandsynligvis ikke længere vil blive bredt anvendt i fremtiden, så du bliver nødt til at lære det før eller siden.

Der er dog nogle forbehold:

Caveat 1: GoLang version 1.11 eller nyere

Go Modules fungerer kun med GoLang version 1.11 eller nyere. På det tidspunkt, hvor dette indlæg blev skrevet, brugte nogle Linux-distributioner, herunder Ubuntu, stadig GoLang 1.10.

Du kan teste den aktuelle version af din installerede Go-pakke med følgende kommando:

go version

Den bør vise noget i stil med:

go version go1.11.2 linux/amd64

Hvis den version, du ser, er under 1.11.x, skal du afinstallere den og følge nedenstående trin for at installere den krævede Go-version. Bemærk også, at nedenstående instruktioner er beregnet til at fungere på Ubuntu og afledte distroer, hvis du bruger en anden distro, skal du tilpasse kommandoerne for at få dem til at fungere for dig.

Først skal du åbne en terminal, hvorefter du kan køre følgende kommandoer:

# If you have already installed the Go package remove it:
sudo apt-get remove --purge --auto-remove golang# Make sure your system is up-to-date:
sudo apt-get update
sudo apt-get -y upgrade# Download the Go 1.11 package and extract it:
wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
sudo tar -xvf go1.11.linux-amd64.tar.gz# Install it manually on your /usr/local directory:
sudo mv go /usr/local
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc# Then close your terminal, open a new one and test if Go is at the correct version:
which go # should output: /usr/local/go/bin/go
go version # should output: go version go1.11.x linux/amd64 or similar
  • Download Go 1.11-pakken (eller nyere) og udpak den:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installer den manuelt på din /usr/local-mappe:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Sluk derefter din terminal, åbn en ny og test, om Go er på den korrekte version:
    which go, bør output: /usr/local/go/bin/go

    go version, bør output: go version go1.11.x linux/amd64 eller lignende

  • Hvis du allerede har installeret Go-pakken, så fjern den:
    sudo apt-get remove --purge --auto-remove golang
  • Sørg for, at dit system er opdateret:
    sudo apt-get update
    sudo apt-get -y upgrade
  • Download Go-pakken 1.11 og udpak den:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installer den manuelt i din /usr/local-mappe:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Sluk derefter din terminal, åbn en ny og test, om Go er på den korrekte version:
    which go, bør output: /usr/local/go/bin/go

    go version, bør output: go version go1.11.x linux/amd64 eller lignende

Caveat 2: Fortryd ændringer til GOPATH og GOROOT

Hvis du har foretaget ændringer i standardværdierne for din GOPATH eller GOROOT, kan det være klogt at fjerne disse ændringer. De er ikke nødvendige, og at blande GOPATH-konfigurationer med Go-moduler er en måde at skabe forvirring på. Mere specifikt:

  1. Standardværdien for GOPATH (når den ikke er indstillet) er ~/go , så når jeg nævner mappen ~/go mener jeg den standardmappe, der bruges af Go. Hvis du har foretaget ændringer i din GOPATH, kan denne mappe være et andet sted, så jeg foreslår, at du fortryder disse ændringer for at undgå forvirring.
  2. Du bør ikke behøve at ændre miljøvariablen GOROOT, da vi har installeret Go i standardmappen: /usr/local. Hvis du imidlertid har ændret denne miljøvariabel, foreslår jeg, at du fortryder det for at undgå forvirring.

Caveat 3: Du behøver ikke at ændre mappen ~/go

Som nævnt før er ~/go standardmappen, hvor Go forventer at læse dine filer, når GOPATH ikke er indstillet. Dette gør dog kun en forskel, hvis du planlægger at oprette dine projekter ved hjælp af GOPATH.

Hvis du vil bruge Go Modules, behøver du ikke at oprette, redigere eller endda læse mappen ~/go. Hvis den ikke eksisterer endnu, vil den blive oprettet automatisk for dig, og hvis den eksisterer, skal du ikke ændre noget derinde.

Så du kan ignorere alle trin i vejledningen, der beder dig om at foretage ændringer i denne mappe, da de sandsynligvis henviser til GOPATH-krav.

Og hvis du har et Go-projekt i øjeblikket inde i denne mappe, og du vil have det til at fungere med Go Modules, bør du flytte det udenfor, da ældre versioner af Go ville deaktivere Go mod inde i GOPATH, selv om det havde en go.mod-fil.

Brug af Go Modules

Brug af Go Modules består grundlæggende af følgende kommando:

go mod init <your_projects_import_path>

For at oprette et nyt projekt skal du blot oprette en ny mappe (et sted uden for ~/go/) og derefter initialisere den som et modul, dvs.:

mkdir myProject/
cd myProject
go mod init github.com/myGithubName/myProject

Kommandoen go mod init vil oprette en ny fil kaldet go.mod på dit projekts mappe. Denne fil vil indeholde dit projekts importsti (normalt din repo’s URL) og en liste med alle de pakker, du i øjeblikket bruger på dette projekt.

Du bør ikke have behov for at redigere denne fil, da den styres automatisk af de fleste go-kommandoer som go run og go get . Når du har kørt disse 3 kommandoer, er du således færdig med at konfigurere denne mappe som et Go-modul.

For at teste det opretter du en ny main.go-fil i denne mappe med disse kodelinjer:

package mainimport "fmt"func main() {
fmt.Println("Hello Go Modules")
}

Test den derefter ved hjælp af go run-kommandoen:

go run main.go 

Den burde output Hello Go Modules som forventet.

Men jeg har allerede et projekt, der bruger GOPATH, hvordan migrerer jeg det?

Processen ligner:

  1. Flyt dit projekts mappe til et sted uden for ~/go/
  2. Initialisér det som et Go-modul, f.eks.:
mv ~/go/src/github.com/myGithubName/myProject ~/anywhere_else/
cd ~/anywhere_else/myProject
go mod init github.com/myGithubName/myProject

Så kan du teste, om alt fungerer med enten go test ./... eller go run main.go , begge kommandoer vil automatisk hente deres afhængigheder og opdatere go.mod-filen.

Det er cool, så skal jeg oprette moduler, submoduler og sub-submoduler? Nope.

Og selv om det er muligt at oprette flere moduler i et enkelt projekt, er det næsten altid unødvendigt. Hvis du vil have en undermappe til at organisere din Go-kode, er du på udkig efter pakker, ikke moduler. Du bør kun køre kommandoen go mod init én gang pr. projekt, ikke mere.

Hvad skal jeg gøre med filerne `go.mod` og `go.sum`?

Som med NPM’s package.json og package-lock.json opretter Go Modules-konceptet også nogle filer til at holde styr på alle versionerne af dine afhængigheder, nemlig go.mod og go.sum-filerne.

Du bør ikke have behov for at redigere nogen af disse 2 filer, da de administreres automatisk af nogle go-værktøjer, såsom go get og go test. Det er også en god idé at tilføje dem til dine commits, da de er nødvendige for at kunne udføre reproducerbare builds af dit projekt, dvs. kompilere med alle de samme versioner og pakker, som du har lokalt.

Konklusion

Du burde nu være klar til at bruge Go Modules på dine egne projekter. Det er ikke obligatorisk at bruge det, men hvis du har læst så langt, har du sikkert bemærket, hvor meget nemmere og mere intuitivt Go Modules er sammenlignet med GOPATH. Der er også en funktion, som kun Go Modules vil tilbyde dig: Reproducerbare builds.

Hvis du vil lære flere detaljer om Go Modules foreslår jeg at læse dette indlæg for en kortere version eller dette for en længere version, begge er meget kortfattede og lette at læse. Jeg kan også varmt anbefale dig at lave din egen research, der er flere gode indlæg om dette emne på nettet. God kodning!

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.