GoLang: Perché non usare la GOPATH

Nelle prime versioni di Go la configurazione richiedeva l’impostazione di alcune variabili d’ambiente. Con il tempo questi requisiti sono stati rimossi ma molti tutorial online menzionano ancora queste variabili causando confusione.

Di recente è stata rilasciata una nuova funzionalità chiamata Go Modules che finalmente rende inutile la GOPATH. In questo post, spiegherò cos’è la GOPATH, perché i Go Modules sono preferiti e come configurare un progetto per usare i Go Modules (che è sorprendentemente facile).

La GOPATH è una variabile d’ambiente che dirà a Go dove dovrebbe leggere e scaricare tutti i file sorgente che userà per compilare il tuo progetto. Questo concetto viene con alcune restrizioni insolite che non si vedono in altri linguaggi di programmazione:

  • Richiede che tu scriva i tuoi progetti Go all’interno di questa directory indicata dalla variabile GOPATH (di default ~/go), anche se i tuoi altri progetti risiedono altrove;
  • La gerarchia di directory all’interno della directory GOPATH deve riflettere l’URL del tuo progetto. Per esempio, se il tuo URL è github.com/foo/bar devi creare una directory $GOPATH/src/github.com , poi, creare una nuova directory al suo interno: foo/ e al suo interno una nuova directory bar/ . Poi, all’interno della directory bar/ dovresti mettere il tuo attuale progetto git;
  • Non c’è un modo integrato per tenere traccia delle versioni dei pacchetti che stai usando.

Il problema peggiore di questa configurazione è che è completamente diversa da quella a cui siamo abituati nella maggior parte degli altri linguaggi di programmazione. Inoltre, dato che GOPATH è una variabile d’ambiente, richiede che gli utenti sappiano un po’ come configurare il proprio sistema operativo, il che è soggetto a errori soprattutto per i principianti.

Perché dovresti usare Go Modules?

Go Modules non dipende da nessuna delle dipendenze menzionate sopra per l’impostazione di specifiche variabili d’ambiente, né dai requisiti per mettere il tuo progetto in una directory specifica come avviene con GOPATH.

È anche retro-compatibile, sicuro e facile da usare:

  1. Richiede un solo comando per migrare un progetto esistente per usare Go Modules;
  2. Influisce solo sul tuo ambiente di sviluppo (come GOPATH) quindi non influenzerà in alcun modo la tua distribuzione in produzione;
  3. È retro-compatibile con GOPATH, il che significa che se aggiorni un progetto per usare Go Modules e i tuoi colleghi preferiscono ancora usare GOPATH possono farlo senza problemi.

Un’altra ragione per imparare a usare Go Modules è che GOPATH probabilmente smetterà di essere ampiamente adottato in futuro, quindi dovrai impararlo prima o poi.

Ci sono, comunque, alcune avvertenze:

Caveat 1: GoLang versione 1.11 o superiore

Go Modules funziona solo con GoLang versione 1.11 o superiore. Al momento di scrivere questo post, alcune distribuzioni Linux, Ubuntu inclusa, usavano ancora GoLang 1.10.

Puoi testare la versione corrente del tuo pacchetto Go installato con il seguente comando:

go version

Dovrebbe produrre qualcosa come:

go version go1.11.2 linux/amd64

Se la versione che vedi è inferiore a 1.11.x dovrai disinstallarla e seguire i passi seguenti per installare la versione Go richiesta. Inoltre, notate che le istruzioni qui sotto sono state pensate per funzionare su Ubuntu e distro derivate, se state usando qualche altra distro dovrete adattare i comandi per farli funzionare per voi.

Prima di tutto, aprite un terminale poi potete eseguire i seguenti comandi:

# 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
  • Scaricate il pacchetto Go 1.11 (o più recente) ed estraetelo:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installatelo manualmente nella vostra directory /usr/local:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Poi chiudi il tuo terminale, aprine uno nuovo e verifica se Go è alla versione corretta:
    which go, dovrebbe uscire: /usr/local/go/bin/go
    go version, dovrebbe uscire: go version go1.11.x linux/amd64 o simile
  • Se hai già installato il pacchetto Go rimuovilo:
    sudo apt-get remove --purge --auto-remove golang
  • Assicurati che il tuo sistema sia aggiornato:
    sudo apt-get update
    sudo apt-get -y upgrade
  • Scarica il pacchetto Go 1.11 ed estrailo:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Installalo manualmente nella tua directory /usr/local:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Poi chiudi il tuo terminale, aprine uno nuovo e verifica se Go è alla versione corretta:
    which go, dovrebbe uscire: /usr/local/go/bin/go
    go version, dovrebbe uscire: go version go1.11.x linux/amd64 o simile

Caveat 2: Annulla le modifiche a GOPATH e GOROOT

Se hai fatto delle modifiche ai valori di default del tuo GOPATH o GOROOT potrebbe essere saggio rimuovere quelle modifiche. Non sono necessari e mischiare le configurazioni GOPATH con i Go Modules è un modo per causare confusione. Più specificamente:

  1. Il valore di default per il GOPATH (quando non è impostato) è ~/go, quindi quando menziono la directory ~/go intendo la directory di default usata da Go. Se hai fatto delle modifiche al tuo GOPATH, questa directory potrebbe essere da qualche altra parte, quindi, ti suggerisco di annullare queste modifiche per evitare confusione.
  2. Non dovresti dover cambiare la variabile d’ambiente GOROOT poiché abbiamo installato Go nella directory predefinita: /usr/local. Se, tuttavia, hai cambiato questa variabile d’ambiente ti suggerisco di annullarla per evitare confusione.

Caveat 3: Non hai bisogno di modificare la directory ~/go

Come detto prima ~/go è la directory predefinita dove Go si aspetta di leggere i tuoi file quando GOPATH non è impostato. Tuttavia, questo fa la differenza solo se hai intenzione di creare i tuoi progetti usando GOPATH.

Se vuoi usare Go Modules non hai bisogno di creare, modificare o anche leggere la directory ~/go. Se non esiste ancora sarà creata automaticamente per te, e se esiste non dovresti aver bisogno di cambiare nulla al suo interno.

Quindi puoi ignorare qualsiasi passo del tutorial che ti chieda di fare dei cambiamenti in questa directory poiché probabilmente si riferiscono ai requisiti di GOPATH.

Inoltre, se hai un progetto Go attualmente all’interno di questa directory e vuoi che funzioni con i moduli Go dovresti spostarlo all’esterno poiché le vecchie versioni di Go disabiliterebbero go mod all’interno della GOPATH anche se avesse un file go.mod.

Utilizzare i moduli Go

Utilizzare i moduli Go consiste fondamentalmente nell’usare il seguente comando:

go mod init <your_projects_import_path>

Per creare un nuovo progetto hai solo bisogno di creare una nuova directory (ovunque fuori da ~/go/) e poi inizializzarla come modulo, cioè:

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

Il comando go mod init creerà un nuovo file chiamato go.mod nella directory del tuo progetto. Questo file conterrà il percorso di importazione del tuo progetto (di solito l’URL del tuo repo) e una lista con tutti i pacchetti che stai attualmente usando su questo progetto.

Non dovresti aver bisogno di modificare questo file poiché è gestito automaticamente dalla maggior parte dei comandi go come go run e go get . Quindi, dopo aver eseguito questi 3 comandi hai finito di configurare questa directory come un modulo Go.

Per testarlo crea un nuovo file main.go all’interno di questa directory con queste righe di codice:

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

Poi testalo usando il comando go run:

go run main.go 

Che dovrebbe produrre Hello Go Modules come previsto.

Ma ho già un progetto che usa GOPATH, come migrare?

Il processo è simile:

  1. Sposta la directory del tuo progetto in un punto qualsiasi al di fuori di ~/go/
  2. Inizializzalo come modulo Go, per esempio:
mv ~/go/src/github.com/myGithubName/myProject ~/anywhere_else/
cd ~/anywhere_else/myProject
go mod init github.com/myGithubName/myProject

Poi puoi testare se tutto funziona con go test ./... o go run main.go , entrambi i comandi scaricheranno automaticamente le loro dipendenze e aggiorneranno il file go.mod.

Fico, quindi dovrei creare moduli, sottomoduli e sotto-sotto-moduli? No.

Anche se è possibile creare diversi moduli in un singolo progetto questo è quasi sempre inutile. Se vuoi una sottocartella per organizzare il tuo codice Go stai cercando pacchetti, non moduli. Dovresti eseguire il comando go mod init solo una volta per progetto, non di più.

Cosa dovrei fare con i file `go.mod` e `go.sum`?

Come per i file package.json e package-lock.json di NPM, il concetto di Go Modules crea anche alcuni file per tenere traccia di tutte le versioni delle tue dipendenze, cioè i file go.mod e go.sum.

Non dovresti aver bisogno di modificare nessuno di questi 2 file poiché sono gestiti automaticamente da alcuni strumenti di Go come go get e go test. È anche una buona idea aggiungerli ai tuoi commit poiché sono necessari per eseguire build riproducibili del tuo progetto, cioè compilare con tutte le stesse versioni e pacchetti che hai in locale.

Conclusione

Ora dovresti essere pronto ad usare Go Modules nei tuoi progetti. Usarlo non è obbligatorio, ma se avete letto fin qui avrete probabilmente notato quanto Go Modules sia più facile e intuitivo rispetto a GOPATH. C’è anche una caratteristica che solo Go Modules ti offrirà: Builds riproducibili.

Se volete imparare più dettagli sui Go Modules vi suggerisco di leggere questo post per una versione più breve o questo per una più lunga, entrambi sono molto concisi e facili da leggere. Ti raccomando anche di fare le tue ricerche, ci sono diversi grandi post su questo argomento sul web. Buona codifica!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.