go模块如何与可安装的命令一起使用?

时间:2018-09-20 15:08:15

标签: go

我最近开始使用Go 1.11,并且喜欢这些模块。除了运行时依赖之外,我还需要在构建过程中使用go模块,例如在go generate期间。

如何安装特定的构建依赖项(例如github.com/aprice/embed/cmd/embed)并从哪个文件夹运行该特定工具? go get是这样做的正确工具吗?

5 个答案:

答案 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

最佳方法可能是运行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 resetrm -rf ~/go/pkg/mod; mkdir ~/go/pkg/mod,发现go mod tidy本身表现得很好。

供应商

为了真正利用项目中的模块缓存,您需要复制源代码

go mod vendor

这将从go.mod中获取所有依赖项

您还需要更改几乎所有的go命令,以在任何-mod=vendorMakefile或其他脚本中使用Dockerfile

go fmt -mod=vendor ./...
go generate -mod=vendor ./...
go build -mod=vendor ./...

其中包括go buildgo getgo 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

然后将这些工具像往常一样安装在其中之一中

  • $ GOBIN
  • $ GOPATH / bin
  • $ HOME / go / bin

您可能还想遵循https://github.com/golang/go/issues/27653,它讨论了将来对工具的明确支持。