我最近开始使用Go 1.11,并且喜欢这些模块。除了运行时依赖之外,我还需要在构建过程中使用go模块,例如在go generate
期间。
如何安装特定的构建依赖项(例如github.com/aprice/embed/cmd/embed)并从哪个文件夹运行该特定工具? go get
是这样做的正确工具吗?
答案 0 :(得分:3)
我没有看到要添加到go.mod的依赖项,但出现此错误:
tools/tools.go:6:5: import "github.com/UnnoTed/fileb0x" is a program, not an importable package
(fileb0x是我要添加的东西)
我不清楚修复它的事件顺序是什么,但我做了所有这些事情:
我建立了一个tools
目录:
mkdir -p tools
我将工具包放入其中(如上所述):
// +build tools
package tools
import (
_ "github.com/UnnoTed/fileb0x"
)
请注意,标签大多并不重要。您可以使用foo:
// +build foo
但是,您不能使用ignore
。那是一个特殊的预定义标签。
// +build ignore
// NO NO NO NO NO
// `ignore` is a special keyword which (surprise) will cause
// the file to be ignore, even for dependencies
最佳方法可能是运行go mod tidy
:
go mod tidy
但是,在执行此操作之前,我运行了许多命令,试图找出哪一个会导致它进入go.mod
:
go install github.com/UnnoTed/fileb0x # didn't seem to do the trick
go get
go generate ./...
go build ./...
go install ./...
go mod vendor
后来我做了一个git reset
和rm -rf ~/go/pkg/mod; mkdir ~/go/pkg/mod
,发现go mod tidy
本身表现得很好。
为了真正利用项目中的模块缓存,您需要复制源代码
go mod vendor
这将从go.mod中获取所有依赖项
您还需要更改几乎所有的go命令,以在任何-mod=vendor
,Makefile
或其他脚本中使用Dockerfile
。
go fmt -mod=vendor ./...
go generate -mod=vendor ./...
go build -mod=vendor ./...
其中包括go build
,go get
,go install
,以及go run
调用的任何go generate
(甚至是go generate
本身)>
//go:generate go run -mod=vendor github.com/UnnoTed/fileb0x b0x.toml
package main
// ...
答案 1 :(得分:1)
https://github.com/golang/go/issues/25922被证明对我有帮助,特别是
将仅构建依赖项与模块一起使用时,重点是版本选择(不安装它们)!
为避免安装,您可以将// go:generate指令修改为:
//go:generate go run golang.org/x/tools/cmd/stringer ARGS
还有最佳做法仓库:https://github.com/go-modules-by-example/index/blob/master/010_tools/README.md
答案 2 :(得分:1)
tools.go
是一个很好的解决方案。但是,如果您要构建库,则tools.go
仍会将依赖项泄漏给消耗您库的事物(您的工具仍以indirect
依赖项存在,go mod tidy
会将它们引入,因为它认为< em>所有可能的目标)。这不是世界末日,因为这些模块永远不会最终出现在消费者的实际内置二进制文件中,但这仍然很混乱。
https://github.com/myitcv/gobin/issues/44可能是解决此长期问题的最有前途的方法,但短期而言,我结合使用了https://github.com/izumin5210/gex中解释的“内部模块”方法。
首先,我在全局安装gex
:
GO111MODULE=off go get github.com/izumin5210/gex/cmd/gex
然后在实际使用gex之前我创建一个像这样的结构:
myproject/
\
- go.mod: module github.com/ysamlan/myproject
\
internal/
\
tools/
- go.mod: module github.com/ysamlan/myproject/tools
要安装仅构建工具,我只需cd internal/tools
并运行gex --add (sometool)
,它将该工具放入internal/tools/bin
中。 CI脚本和其他想要在本地构建我的东西的人只需要运行cd internal/tools && gex --build
即可可靠且可重复地填充工具二进制文件,但顶层go.mod不变。
其中的关键部分是使用与根项目使用的模块路径不同的 模块路径创建internal/tools/go.mod
文件,然后仅从该目录运行gex
。 / p>
答案 3 :(得分:0)
是的,go get github.com/aprice/embed
应该
$GOPATH/bin
中(应该在您的PATH
上,对吧?)有关更多信息,请参见go help get
。
答案 4 :(得分:0)
惯例是添加一个受构建约束保护的名为“ tools.go”的文件,并导入所有必需的工具:
// +build tools
package tools
import (
_ "github.com/aprice/embed/cmd/embed"
)
https://github.com/golang/go/issues/25922#issuecomment-412992431
然后将这些工具像往常一样安装在其中之一中
您可能还想遵循https://github.com/golang/go/issues/27653,它讨论了将来对工具的明确支持。