有没有办法从另一个目录 运行 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 ./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
和 运行ning 和 运行 go run ./src
但这会导致其自身的问题:
go
命令现在无法定位 internal
和 pkg
中的所有子包
- VSCode现在由于某些原因丢失,无法执行测试(主要是没有找到所有子包)。
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-dir
的 hello-world
模块使用 go run hello-world
。
go.work
go 1.18
use ./hello-world
go.mod
module hello-world
go 1.18
注:有可能,@Volker指出不推荐
我有以下项目结构,在 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
和 运行ning 和 运行 go run ./src
但这会导致其自身的问题:
go
命令现在无法定位internal
和pkg
中的所有子包
- VSCode现在由于某些原因丢失,无法执行测试(主要是没有找到所有子包)。
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-dir
的 hello-world
模块使用 go run hello-world
。
go.work
go 1.18
use ./hello-world
go.mod
module hello-world
go 1.18
注:有可能,@Volker指出不推荐