Go get не может найти локальные пакеты при использовании нескольких модулей в репо - PullRequest
0 голосов
/ 29 августа 2018

У меня проблемы с новой системой модулей go, так как я хотел бы определить локальный модуль и импортировать его в основную программу. Локальный пакет находится в папке основного пакета / корневой папки. Представьте себе следующую структуру проекта за пределами $GOPATH.

Структура проекта

. / 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)
}

. / Модель / person.go

package model

type Person struct {
    name string
    age int
}

В корневой папке я инициализировал модуль, вызвав

go mod init example.com/localModule

В папке model/ я инициализировал субмодуль, вызвав

go mod init example.com/localModule/model

Ошибка

В корневой папке вызов следующих команд завершится ошибкой.

$ 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

Сообщение об ошибке для go get обрезано, я неправильно его разбираю.

Я не планирую отправлять модуль на сервер, и мне просто нужен был способ ссылки на локальный пакет model, поэтому я выбрал example.com/localModule/ и example.com/localModule/model соответственно.

Я использую go1.11 darwin/amd64 на Macbook с MacOS 10.13.6.

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Проблема с корнем

Причина, по которой вы получаете эту ошибку, заключается в том, что вы определили два модуля, которые не знают, как найти друг друга на локальном диске.

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

Решение 1: replace

Вы можете добавить директиву replace в файл go.mod верхнего модуля, например:

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

, который позволяет верхнему модулю найти другой модуль на диске. Более подробно это описано в разделе replace FAQ и "Многомодульные репозитории" на вики-модуле.

Тем не менее, это более сложное решение, которое может быть трудно понять правильно, обычно это более продолжительная работа и имеет некоторые ограничения, такие как replace игнорируется для всех модулей, кроме текущего модуля. Для большинства людей многомодульное репо, вероятно, не то, что они хотят. В настоящее время относительно редко требуется иметь несколько модулей в одном репозитории.

Решение 2: один репо == один модуль

Хотя можно использовать директиву replace, наиболее распространенным и простым решением является:

  • В вашем хранилище должен быть один go.mod файл, а
  • Поместите этот единственный файл go.mod в корень вашего хранилища.

Это очень простое решение, и оно означает, что ваши два пакета в репозитории смогут автоматически находить друг друга без необходимости replace, что позволяет избежать сообщения об ошибке, о котором вы сообщили.

replace с многомодульным репо по сравнению с одномодульным репо?

Рассказывает Расс Кокс в # 26664 :

Для всех, кроме опытных пользователей, вы, вероятно, захотите принять обычное соглашение, что один репо = один модуль. Для долгосрочного развития вариантов хранения кода важно, чтобы репо могло содержать несколько модулей, но это почти наверняка не то, что вы хотите сделать по умолчанию.

Если вы вместо этого хотите, чтобы в одном репозитории было определено несколько модулей, есть немало нюансов о том, как это сделать правильно, и есть весь раздел вики-модулей, который должен быть Прочтите о том, как управлять сложностью, связанной с несколькими модулями в одном репозитории, включая этот совет:

Добавление модулей, удаление модулей и управление версиями модулей с несколькими модулями в одном репозитории требует значительного внимания и тщательности, поэтому почти всегда проще и проще управлять одномодульным репозиторием , чем несколькими модулями. в существующем хранилище.

0 голосов
/ 12 сентября 2018

Вы можете иметь локальные «под» модули, как вы просите, добавив оператор require и соответствующий оператор замены с относительным путем к файлу в go.mod.

В "корне" ./go.mod:

module example.com/localModule

require example.com/localModule/model v0.0.0

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