#go #gopath
#Вперед #gopath
Вопрос:
У меня есть следующая структура проекта, за пределами GOPATH
.
. // Project root
├── Dockerfile
├── .env
├── README.md
└── src
├── main.go
├── go.mod
├── go.sum
├── internal
│ ├── somepackage
│ │ ├── main.go
│ │ └── types.go
│ ├── someother
│ │ ├── main.go
│ │ ├── oauth.go
│ │ └── types.go
│ └── models
│ └── main.go
└── pkg
├── somepackage
│ └── main.go
└── anotherpackage
└── main.go
Я хочу запустить свой код модуля Go, расположенный в src
каталоге.
Когда я cd
вхожу в src
каталог и go run .
/ или go build .
в свой код, он работает отлично.
Когда я стою в корне своего проекта, я не могу запустить go run ./src
или go build ./src
. Я получаю следующую ошибку.
src/service.go:8:2: cannot find package "web-service/internal/auth" in any of:
/usr/lib/go/src/web-service/internal/auth (from $GOROOT)
/home/miloertas/Packages/go/src/web-service/internal/auth (from $GOPATH)
src/endpoints.go:3:8: cannot find package "web-service/internal/handlers" in any of:
/usr/lib/go/src/web-service/internal/handlers (from $GOROOT)
/home/miloertas/Packages/go/src/web-service/internal/handlers (from $GOPATH)
Важно, чтобы мой исходный код оставался в этом src
каталоге.
Не менее важно, чтобы я мог run
и build
мой код из корня моего проекта (например .env
, файл расположен в корне репозитория).
Поэтому я ищу способ run
или build
мой код в src
каталоге из корня моего проекта.
Я попытался переместить go.mod
в корень проекта и запустить и запустить go run ./src
, но это вызывает собственные проблемы:
- Теперь
go
команда не может найти все подпакеты вinternal
иpkg
- VSCode теперь потерян, и выполнение тестов невозможно по некоторым причинам (в основном потому, что не найдены все подпакеты).
Комментарии:
1. Я не знаю, почему на самом деле вопрос был сильно отклонен. Хотя в нем отсутствует то, что можно было бы назвать базовыми знаниями о том, что делать и не делать, я бы сказал, что он довольно хорошо сформулирован и четко показывает, что OP провел свои исследования перед публикацией.
2. Можно было бы ожидать, что что-то вроде
go build ./src/...
сработает, или что будет общий вариант, означающий «это корень проекта, где находится мой go.mod, работайте отсюда» ,go build --root src ./...
но, очевидно, я живу в стране фантазий. Возможно, вернитесь к старому добромуMakefile
и закодируйте там свои цели и команды, завернутые в(cd src; go build ./...)
.
Ответ №1:
Начиная с Go 1.18, теперь этого можно достичь с помощью рабочих пространств Go.
Используя следующую структуру каталогов
parent-dir/
└─ go.work
hello-world/
├─ go.mod
└─ main.go
Вы можете запустить hello-world
модуль из parent-dir
using go run hello-world
.
go.work
go 1.18
use ./hello-world
go.mod
module hello-world
go 1.18
Примечание: это возможно, но не рекомендуется, как указано @Volker
Ответ №2:
Важно, чтобы мой исходный код оставался в этом каталоге src. Не менее важно, чтобы я мог запускать и создавать свой код из корня моего проекта (например, файл .env расположен в корне репозитория).
Эти два требования противоречат друг другу. Вы должны отпустить его.
Особенно второй необоснованный: не используйте go run, используйте go build. Сделайте путь для поиска файла .env параметром командной строки для вашей программы (Go — это не PHP или JavaScript, просто нет проекта или исходного кода для исполняемого двоичного файла). Или создайте исполняемый файл где-нибудь, но запустите его в корне вашего проекта.
Обратите внимание, что наличие src
папки, мягко говоря, необычно.
Я попытался переместить go.mod в корень проекта и запустить и запустить go run ./src, но это вызывает собственные проблемы:
Ну, начните с go run
того, что вообще не используйте, используйте go build
. А затем попробуйте создать фактический основной пакет. Все инструменты go лучше всего работают с пакетами, а не с папками файловой системы. Если ваш модуль назван playing.hardball/for-unspecific-reasons
, а пакет main находится в src
try go build playing.hardball/for-unspecific-reasons/src
.
Выводы, даже если это работает не так, как вы хотите:
- Не используйте
go run
. Причин много, полезно запускать однофайловые скрипты и загруженный footgun практически для любого другого варианта использования. go
Инструмент работает с путями импорта . В простых случаях путь импорта может быть выведен из файловой системы.- Скомпилированный исполняемый файл не имеет понятия «каталог проекта», «источник», «путь к классу» или что-то еще, это автономный исполняемый файл, который можно запускать везде и полностью отделен от его источников.
- Сделайте весь путь поиска файловой системы параметром конфигурации (флаг командной строки или переменная среды); укажите практические значения по умолчанию (например
./
); используйте это при запуске вашего исполняемого файла, чтобы сообщить, где найти статические вещи, такие как env-файлы, шаблоны, значки, css-файлы и т. Д.
Комментарии:
1. Я хотел узнать, возможно ли это, как в «Есть ли способ». Я знаю, что мой выбор дизайна очень необычен и не является «лучшей практикой», но это не моя точка зрения. В любом случае спасибо.
2. Хорошо: Нет, нет способа сделать это именно так, как вы хотите. Вы должны перепроектировать хотя бы некоторые аспекты вашего решения.
3. Хорошо, я думаю, что я собираюсь изменить свой макет. Спасибо. Я предлагаю вам указать, что это не может быть достигнуто в верхней части вашего ответа, чтобы избежать путаницы.
4. «Обратите внимание, что наличие папки src, мягко говоря, необычно». — вероятно, потому, что инструментарий go настолько упрям и негибок, что это практически невозможно, как обнаружил OP. Предлагаемый макет имеет смысл, если вы живете в разнородном мире многомодульной разработки.