Come importare pacchetti locali in go?


101

Sono nuovo e sto lavorando su un codice di esempio che voglio localizzare.

Nella main.godichiarazione di importazione originale era:

 import (
    "log"
    "net/http"
    "github.com/foo/bar/myapp/common"
    "github.com/foo/bar/myapp/routers"
)

Ora ho commone routerspacchetto/home/me/go/src/myapp

Quindi ho convertito l'istruzione import in:

import (
    "log"
    "net/http"
    "./common"
    "./routers"
)

Ma quando corro go install myappottengo questi errori:

can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package

Inoltre, quando uso commone routersinvece di ./commone ./routersnell'istruzione import, ottengo:

myapp/main.go:7:3: cannot find package "common" in any of:
    /usr/local/go/src/common (from $GOROOT)
    /home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
    /usr/local/go/src/routers (from $GOROOT)
    /home/me/go/src/routers (from $GOPATH)

Come posso risolvere questo problema?


5
Tutte le importazioni sono "locali" indipendentemente dal percorso di importazione. Vedere "Come scrivere codice Go" per una spiegazione dettagliata.
JimB

24
@ JimB mettendo da parte i dibattiti filosofici, quello che mi interessa è come risolvere il problema di cui sopra.
Karlom

3
Non sto cercando di fare una dichiarazione filosofica, sto letteralmente dicendo che tutte le importazioni avvengono nel tuo filesystem locale; non c'è mai alcuna differenza se provengono da un repository remoto o meno. Non tentare di utilizzare percorsi relativi (a volte funzionano, ma sono sconsigliati) e passare attraverso il documento "Come scrivere codice di go", in particolare la sezione "Organizzazione del codice" .
JimB

Risposte:


70

Bene, ho capito il problema. Fondamentalmente, il percorso di partenza per l'importazione è$HOME/go/src

Quindi dovevo solo aggiungere myappdavanti ai nomi dei pacchetti, cioè l'importazione dovrebbe essere:

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)

4
usare il nome del progetto come se myappfosse una cattiva idea, ad esempio se cambi il nome del progetto, tutta l'importazione
fallirà

9
Qual è l'alternativa? Go non consiglia di utilizzare le importazioni relative.
Sam Holmes

12
Ovviamente tutte le importazioni falliranno se cambi il nome del progetto. Il nome del progetto cambia raramente.
Damien Roche

23
Bene, a partire da go1.11 puoi usare il nuovo sistema di moduli. go mod init <module_name>e poi solo import "<module_name>/<pkg_name>".
strillo

Come possiamo importare github.com/dgrijalva/jwt-go nel nostro file .go? La mia cartella jwt-go è all'interno di src / github.com / dgrijalva
Manik Thakur,

34

Se si utilizza Go 1.5 di cui sopra, si può provare a utilizzare vendoring funzione. Ti consente di mettere il tuo pacchetto locale nella cartella del fornitore e importarlo con un percorso più breve. Nel tuo caso, puoi mettere la tua cartella comune e router nella cartella del fornitore in modo che sia come

myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go

e importalo in questo modo

import (
    "common"
    "routers"
    "routers/middleware"
)

Questo funzionerà perché Go proverà a cercare il tuo pacchetto partendo dalla directory del fornitore del tuo progetto (se ha almeno un file .go) invece di $ GOPATH / src.

FYI: Puoi fare di più con il fornitore, perché questa funzionalità ti consente di mettere "tutto il codice della tua dipendenza" per un pacchetto nella directory del tuo progetto in modo che sia in grado di ottenere sempre le stesse versioni delle dipendenze per tutte le build. È come npm o pip in python, ma devi copiare manualmente le tue dipendenze nel tuo progetto, o se vuoi renderlo facile, prova a guardare govendor di Daniel Theophanes

Per ulteriori informazioni su questa funzione, prova a cercare qui

Comprensione e utilizzo della cartella del fornitore di Daniel Theophanes

Capire Go Dependency Management di Lucas Fernandes da Costa

Spero che tu o qualcun altro lo troviate utile


19

I percorsi di importazione sono relativi alle variabili di ambiente $GOPATHe $GOROOTdell'utente. Ad esempio, con quanto segue $GOPATH:

GOPATH=/home/me/go

I pacchetti che si trovano in /home/me/go/src/lib/commone /home/me/go/src/lib/routersvengono importati rispettivamente come:

import (
    "lib/common"
    "lib/routers"
)

Sì, il primo esempio è stato il mio errore.
wlredeye

Cosa intendi per percorso relativo non supportato dagli strumenti?
wlredeye

2
Non puoi go installpacchetti che utilizzano importazioni relative.
JimB

Penso che sia un malinteso qui. Intendo relativo a GOPATH. Non solo parente come "../../mypackage"
wlredeye

Era in riferimento alla parte che hai corretto sull'importazione rispetto alla directory corrente. Sì, tutte le importazioni degli utenti sono relative a $GOPATH/src.
JimB

5

Il pacchetto locale è un fastidioso problema in go.

Per alcuni progetti nella nostra azienda decidiamo di non utilizzare affatto pacchetti secondari.

  • $ glide install
  • $ go get
  • $ go install

Tutto funziona.

Per alcuni progetti utilizziamo pacchetti secondari e importiamo pacchetti locali con percorso completo:

import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage

Ma se forchiamo questo progetto, i sottopacchetti fanno ancora riferimento a quello originale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.