有没有办法从另一个目录 运行 Go 模块

Is there a way to run a Go module from another directory

我有以下项目结构,在 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 ./srcgo 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 目录中。 同样重要的是,我能够从项目的根目录 runbuild 我的代码(例如 .env 文件位于存储库的根目录)。

因此,我正在寻找一种方法 runbuild 我的代码在 src 目录中从我的项目的根目录。

我尝试移动项目根目录下的 go.mod 和 运行ning 和 运行 go run ./src 但这会导致其自身的问题:

It's important that my source code remains in this src directory. It is equally important that I am able to run and build my code from the root of my project (For example the .env file is located at the root of the repository).

这两个要求是矛盾的。你不得不放弃一个。

尤其是第二个是没有根据的:不要用go运行,用go build。使查找 .env 文件的路径成为程序的命令行选项(Go 不是 PHP 或 JavaScript,只是 没有项目或源执行二进制文件的根)。或者在某处构建可执行文件,但在项目根目录中执行它。

请注意,有一个 src 文件夹是 -- 委婉地说 -- 不常见

I tried moving the go.mod at the root of the project and running and ran go run ./src but this causes issues of its own:

嗯,从根本不使用 go run 开始,使用 go build。然后尝试构建实际的主包。所有 go 工具在 packages 上效果最好,而不是在文件系统文件夹上。如果您的模块名为 playing.hardball/for-unspecific-reasons 并且主程序包位于 src 中,请尝试 go build playing.hardball/for-unspecific-reasons/src.

即使这不是您想要的方式,也要注意事项:

  • 不要使用go run。原因是多方面的,对于 运行 单个 文件脚本和基本上所有其他用例的加载 footgun 都是有用的。
  • go 工具适用于 import paths。在简单的情况下,导入路径可以从文件系统中推断出来。
  • 已编译的可执行文件 没有 概念 “项目目录”、“源代码”、“类路径”或其他任何东西,它是独立可执行文件运行无处不在并且完全脱离其来源。
  • 使所有文件系统查找路径成为配置选项(命令行标志或环境变量);提供实用的默认值(例如 ./); 运行在您的可执行文件中使用它来宣布在哪里可以找到静态文件,如 .env 文件、模板、图标、css 文件等

Go 1.18, it's now possible to achieve this with Go workspaces.

使用以下目录结构

parent-dir/
└─ go.work
   hello-world/
   ├─ go.mod
   └─ main.go

您可以 运行 来自 parent-dirhello-world 模块使用 go run hello-world

go.work

go 1.18

use ./hello-world

go.mod

module hello-world

go 1.18

注:有可能,@Volker指出不推荐