web-dev-qa-db-fra.com

Go get ne peut pas trouver les paquets locaux lors de l’utilisation de plusieurs modules dans un dépôt

J'ai des problèmes avec le nouveau système de modules de go, car j'aimerais définir un module local et l'importer dans le programme principal. Le paquet local réside dans un dossier du dossier paquet/racine principal. Imaginez la structure de projet suivante en dehors de la $GOPATH.

Structure de projet

./main.go

package main

import "fmt"
import "example.com/localModule/model"

func main() {
    var p = model.Person{name: "Dieter", age:25}
    fmt.Printf("Hello %s\n", p.name)
}

./model/person.go

package model

type Person struct {
    name string
    age int
}

Dans le dossier racine, j'ai initialisé un module en appelant

go mod init example.com/localModule

Dans le model/ dossier j’ai ensuite initialisé le sous-module en appelant

go mod init example.com/localModule/model

L'erreur

Dans le dossier racine appelant les commandes suivantes, échouez.

$ go get
go build example.com/localModule/model: no Go files in

$ go build
main.go:4:8: unknown import path "example.com/localModule/model": cannot find module providing package example.com/localModule/model

Le message d’erreur pour go get est coupé, je ne l’analyse pas à tort.

Je n’envisage pas de transférer le module sur un serveur et j’avais besoin d’un moyen de référencer le paquet local model, j’ai donc choisi example.com/localModule/ et example.com/localModule/model respectivement.

J'utilise go1.11 darwin/AMD64 sur un Macbook sous MacOS 10.13.6.

22
Tobs.Core

Vous pouvez avoir des "sous" modules locaux comme vous le demandez en ajoutant une instruction require et une instruction de remplacement correspondante avec un chemin de fichier relatif dans go.mod.

Dans la "racine" ./go.mod:

module example.com/localModule

require example.com/localModule/model v0.0.0

replace example.com/localModule/model v0.0.0 => ./model
32
Jostein Stuhaug

Problème de racine

Vous obtenez cette erreur parce que vous avez défini deux modules qui ne savent pas comment se trouver l'un sur l'autre sur votre disque local.

$ go build
main.go:4:8: unknown import path "example.com/localModule/model": 
 cannot find module providing package example.com/localModule/model

Solution 1: replace

Vous pouvez ajouter une directive replace au module go.mod fichier, tel que:

replace example.com/localModule/model v0.0.0 => ./model

ce qui permet au module supérieur de trouver l’autre module sur le disque. Ceci est couvert plus en détail dans la section remplacez FAQ et "Référentiels multi-modules" sur le wiki des modules.

Cependant, il s’agit d’une solution plus complexe, qui peut s’avérer difficile à mettre en place, qui demande généralement plus de travail et dont certaines limitations, telles que replace est ignorée pour tous les modules, à l’exception du module actuel. Pour la plupart des gens, un référentiel multi-modules n'est probablement pas ce qu'ils veulent. Il est relativement rare à ce stade d'avoir réellement besoin de plusieurs modules dans un même référentiel.

Solution 2: un repo == un module

Bien qu'il soit possible d'utiliser une directive replace, la solution la plus courante et la plus simple est:

  • Avoir un seul go.mod fichier dans votre référentiel, et
  • Placez ce single go.mod fichier à la racine de votre référentiel.

C'est une solution très simple, et cela signifie que vos deux paquets dans le référentiel pourront se trouver automatiquement sans avoir besoin de replace, ce qui évite le message d'erreur que vous avez signalé.

replace avec référentiel multi-module, vs référentiel à module unique?

Russ Cox a commenté dans # 26664 :

Pour tous les utilisateurs sauf les utilisateurs expérimentés, vous voudrez probablement adopter la convention habituelle selon laquelle un référentiel = un module. Il est important pour l'évolution à long terme des options de stockage de code qu'un référentiel puisse contenir plusieurs modules, mais ce n'est certainement pas quelque chose que vous souhaitez faire par défaut.

Si vous voulez plutôt que plusieurs modules soient définis dans un même référentiel, il y a beaucoup de nuances sur la façon de le faire correctement, et il y a une section section entière du wiki de Modules à lire. comment gérer la complexité associée à plusieurs modules dans un même référentiel, y compris ce conseil:

Ajouter des modules, supprimer des modules et gérer des versions avec plusieurs modules dans un même référentiel requiert une attention et des délibérations considérables. Il est donc toujours plus simple et plus simple de gérer un référentiel à module unique plutôt que plusieurs modules dans un référentiel existant.

2
typical182