我对 Makefile 进行了稍微修改,以帮助更好地解释情况:
include $(wildcard .env)
DB_URL=postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST):$(POSTGRES_PORT)/$(POSTGRES_DB)?sslmode=disable&pool_max_conns=10
test:
@echo $(DB_URL)
@cat .env
@-include .env
@echo "Running tests"
@DB=$(DB_URL) go test ./... -v -coverprofile=coverage.out
第一行显示正在创建的正确数据库 URL,因此它正在按预期导入
.env
文件。第二行也有效。第三行显示以下错误:
make: include: No such file or directory
make: [test] Error 1 (ignored)
现在,虽然我可以看到我的数据库 URL 存在,但我不明白为什么我看不到数据库中的任何内容。
go test
显示 DB 为空字符串。如果我导出硬编码的数据库 URL,一切都会按预期工作。
如果有人能帮助我理解为什么会发生这种情况,那就太好了。我正在使用 MacOS 索诺玛。我已经使用同一个 Makefile 几个星期了,并且从未更改过 .env 或 Makefile,但这在几个小时前就停止工作了。
在食谱之外,这......
include $(wildcard .env)
... 是对
make
的指令。
在食谱中,这......
@-include .env
是一个 shell 命令,以
@-
为模,抑制打印命令并且不会因错误而终止配方。但是 include
不是内置的 shell,并且毫不奇怪,可执行搜索路径中没有这样的命令,因此:
make: include: No such file or directory
你继续...
现在,虽然我可以看到我的数据库 URL 存在,但我不明白为什么我看不到数据库中的任何内容。
显示 DB 为空字符串。go test
引用时需要小心。
make
将 $(DB_URL)
扩展为:以 sslmode=disable&pool_max_conns=10
结尾的字符串。 &
对于 shell 作为命令分隔符非常重要(这会导致前面的命令作为后台作业运行)。所以是的,go test
在其环境中不会看到 DB
的值,或者至少不会因为配方设置了一个值。它对其环境的唯一添加是 pool_max_conns=10。
如果 URL 包含对 shell 有意义的其他字符,例如
;
或 $
等,则可能会出现其他类似问题。只要 URL 不包含任何 '
字符,您就应该能够执行以下操作:
DB='$(DB_URL)' go test ./... -v -coverprofile=coverage.out
旁注:永远不要抑制食谱中的命令回显,直到您确定它们正常工作。也许即使到那时也不会。