Comment importer des packages locaux en go?

90

Je suis nouveau pour aller travailler sur un exemple de code que je veux localiser.

Dans la main.godéclaration d'importation d' origine , c'était:

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

Maintenant, j'ai commonet routersemballé/home/me/go/src/myapp

J'ai donc converti l'instruction d'importation en:

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

Mais quand je cours, go install myappj'obtiens ces erreurs:

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

De plus, lorsque j'utilise commonet routersau lieu de ./commonet ./routersdans l'instruction d'importation, j'obtiens:

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)

Comment puis-je réparer cela?

Karlom
la source
5
Toutes les importations sont "locales" quel que soit le chemin d'importation. Voir «Comment écrire du code Go» pour une explication détaillée.
JimB
21
@JimB mis à part les débats philosophiques, ce qui me préoccupe, c'est de savoir comment résoudre le problème évoqué plus haut.
Karlom
3
Je n'essaye pas de faire une déclaration philosophique, je dis littéralement que toutes les importations se produisent dans votre système de fichiers local; il n'y a jamais de différence qu'ils proviennent ou non d'un repo distant. N'essayez pas d'utiliser des chemins relatifs (ils fonctionnent parfois, mais sont déconseillés), et parcourez le document «Comment écrire du code Go», en particulier la section «Organisation du code» .
JimB

Réponses:

63

Eh bien, j'ai compris le problème. En gros, le chemin de départ pour l'importation est$HOME/go/src

Il me fallait donc juste ajouter myappdevant les noms de paquet, c'est-à-dire que l'importation devrait être:

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)
Karlom
la source
3
utiliser un nom de projet comme myappest une mauvaise idée, par exemple si vous modifiez le nom du projet, toute l'importation échouera
TomSawyer
7
Quelle est l'alternative? Go ne vous recommande pas d'utiliser les importations relatives.
Sam Holmes
11
Bien entendu, toutes les importations échoueront si vous modifiez le nom du projet. Le nom du projet change rarement.
Damien Roche
21
Eh bien, à partir de go1.11, vous pouvez utiliser le nouveau système de modules. go mod init <module_name>et puis juste import "<module_name>/<pkg_name>".
cri
Comment importer github.com/dgrijalva/jwt-go dans notre fichier .go? Mon dossier jwt-go se trouve dans src / github.com / dgrijalva
Manik Thakur
30

Si vous utilisez Go 1.5 ci-dessus, vous pouvez essayer d'utiliser la fonction de vente . Il vous permet de placer votre package local dans le dossier du fournisseur et de l'importer avec un chemin plus court. Dans votre cas, vous pouvez placer votre dossier commun et vos routeurs dans le dossier du fournisseur afin que ce soit comme

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

et importez-le comme ça

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

Cela fonctionnera car Go essaiera de rechercher votre package en commençant par le répertoire du fournisseur de votre projet (s'il a au moins un fichier .go) au lieu de $ GOPATH / src.

FYI: Vous pouvez faire plus avec le fournisseur, car cette fonctionnalité vous permet de mettre "tout le code de vos dépendances" pour un package dans le répertoire de votre propre projet afin qu'il puisse toujours obtenir les mêmes versions de dépendances pour toutes les versions. C'est comme npm ou pip en python, mais vous devez copier manuellement vos dépendances dans votre projet, ou si vous voulez le rendre facile, essayez de chercher govendor par Daniel Theophanes

Pour en savoir plus sur cette fonctionnalité, essayez de chercher ici

Comprendre et utiliser le dossier du fournisseur par Daniel Theophanes

Comprendre la gestion des dépendances Go par Lucas Fernandes da Costa

J'espère que vous ou quelqu'un d'autre le trouverez utile

arimaulana
la source
18

Les chemins d'importation sont relatifs à vos variables d'environnement $GOPATHet $GOROOT. Par exemple, avec ce qui suit $GOPATH:

GOPATH=/home/me/go

Les packages situés dans /home/me/go/src/lib/commonet /home/me/go/src/lib/routerssont importés respectivement comme:

import (
    "lib/common"
    "lib/routers"
)
wlredeye
la source
Oui, le premier exemple était mon erreur.
wlredeye
Qu'entendez-vous par chemin relatif non pris en charge par l'outillage?
wlredeye
2
Vous ne pouvez pas les go installpackages qui utilisent des importations relatives.
JimB
Je pense que son malentendu ici. Je veux dire par rapport à GOPATH. Pas seulement relatif comme "../../mypackage"
wlredeye
C'était en référence à la partie que vous avez fixée sur l'importation par rapport au répertoire actuel. Oui, toutes les importations d'utilisateurs sont relatives à $GOPATH/src.
JimB
5

Le paquet local est un problème ennuyeux en cours de route.

Pour certains projets de notre entreprise, nous décidons de ne pas utiliser du tout de sous-packages.

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

Tout le travail.

Pour certains projets, nous utilisons des sous-packages et importons des packages locaux avec le chemin complet:

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

Mais si nous forkons ce projet, les sous-packages font toujours référence à l'original.

tangxinfa
la source