我想将retool替换为go模块tools.go“工具作为依赖项”。但是,当我的开发人员和CI env都使用不同的操作系统时,我很难理解它是如何工作的。
我想确保每个环境使用的工具版本完全相同。
举一个具体的例子,我的应用程序要求protoc编译器通过github.com/golang/protobuf/protoc-gen-go生成go代码。我有3个操作系统,都需要使用protoc-gen-go插件/生成器来执行protoc:
我目前正在使用retool来确保所有环境都锁定在相同版本的工具上(此前为protoc-gen-go):
retool do build/bin/protoc -Ibuild/protoc/include -I. rpc/platform/platform.proto --go_out=.
我的新go模块/“依赖工具”设置
tools.go:
// +build tools
package tools
import (
_ "github.com/golang/protobuf/protoc-gen-go"
)
设置go install
将使用的路径:
export GOBIN=$PWD/bin
安装:
go install github.com/golang/protobuf/protoc-gen-go
如果Ryan运行go install ..
,则会创建bin/protoc-gen-go
MacOS可执行文件。
问题:
protoc-gen-go
工具版本(或git hash)未在go.mod中列出? protoc
如何知道在protoc-gen-go
目录中使用./bin
可执行文件生成器?答案 0 :(得分:1)
在Twirp之后,我能够为协议(和Go Modules tools guidelines之类的插件)完成供应商的工具构建,并为protoc二进制文件添加一点Makefile-Fu。
可以在Aspiration Labs pyggpot repo中找到完整的工作示例。以下是基本细节。值得一提的是:为某些工具正确设置导入路径非常轻松,但最终成功了。
对于protoc
本身,我在Makefile中提供了二进制发行版,并将其设置为tools/bin
目录:
TOOLS_DIR := ./tools
TOOLS_BIN := $(TOOLS_DIR)/bin
# protoc
PROTOC_VERSION := 3.7.1
PROTOC_PLATFORM := osx-x86_64
PROTOC_RELEASES_PATH := https://github.com/protocolbuffers/protobuf/releases/download
PROTOC_ZIP := protoc-$(PROTOC_VERSION)-$(PROTOC_PLATFORM).zip
PROTOC_DOWNLOAD := $(PROTOC_RELEASES_PATH)/v$(PROTOC_VERSION)/$(PROTOC_ZIP)
PROTOC := $(TOOLS_BIN)/protoc
# protoc
$(PROTOC): $(TOOLS_DIR)/$(PROTOC_ZIP)
unzip -o -d "$(TOOLS_DIR)" $< && touch $@ # avoid Prerequisite is newer than target `tools/bin/protoc'.
$(TOOLS_DIR)/$(PROTOC_ZIP):
curl --location $(PROTOC_DOWNLOAD) --output $@
PROTOC_PLATFORM
字符串可以通过类似OS detecting makefile的方式自动执行。我们使用的版本为https://github.com/aspiration-labs/pyggpot/blob/master/build/makefiles/osvars.mk。
开始构建执行工具。创建类似{p>的tools.go
// +build tools
package tools
import (
// protocol buffer compiler plugins
_ "github.com/golang/protobuf/protoc-gen-go"
_ "github.com/twitchtv/twirp/protoc-gen-twirp"
_ "github.com/twitchtv/twirp/protoc-gen-twirp_python"
_ "github.com/thechriswalker/protoc-gen-twirp_js"
)
注意:// +build tools
标签将阻止go build
避免在最终版本中导入过度构建的工具。
最后,一些make代码可以构建您的go工具:
# go installed tools.go
GO_TOOLS := github.com/golang/protobuf/protoc-gen-go \
github.com/twitchtv/twirp/protoc-gen-twirp \
github.com/twitchtv/twirp/protoc-gen-twirp_python \
github.com/thechriswalker/protoc-gen-twirp_js \
# tools
GO_TOOLS_BIN := $(addprefix $(TOOLS_BIN), $(notdir $(GO_TOOLS)))
GO_TOOLS_VENDOR := $(addprefix vendor/, $(GO_TOOLS))
setup_tools: $(GO_TOOLS_BIN)
$(GO_TOOLS_BIN): $(GO_TOOLS_VENDOR)
GOBIN="$(PWD)/$(TOOLS_BIN)" go install -mod=vendor $(GO_TOOLS)
最后,有一个make setup
目标可以运行go mod vendor
并处理上述目标。
setup: setup_vendor $(TOOLS_DIR) $(PROTOC) setup_tools
# vendor
setup_vendor:
go mod vendor
$(TOOLS_DIR):
mkdir -v -p $@
答案 1 :(得分:0)
Go模块可用于导入.go文件。如果他们找到导入,他们将自动下载满足您要求的最新版本。您必须阅读https://github.com/golang/go/wiki/Modules并了解自Go 1.11及更高版本以来模块如何工作。
这时,为什么go.mod中未列出protoc-gen-go工具版本(或git hash)?
这是因为就Go模块而言,protoc-gen-go只是一个外部工具。您无需导入golang/protobuf/tree/master/protoc-gen-go
,但可以导入它生成的代码。
Joe克隆应用程序仓库时,他如何获得和编译Ryan使用的相同版本的protoc-gen-go?
使用:
GIT_TAG="v1.2.0" # change as needed
go get -d -u github.com/golang/protobuf/protoc-gen-go
git -C "$(go env GOPATH)"/src/github.com/golang/protobuf checkout $GIT_TAG
go install github.com/golang/protobuf/protoc-gen-go
在用户的每台计算机上安装特定版本。可能编写一个使该过程自动化的构建脚本。
protoc如何知道在我的./bin目录中使用protoc-gen-go可执行文件生成器?
从github文档中: 除非设置了$ GOBIN,否则编译器插件protoc-gen-go将安装在$ GOPATH / bin中。协议编译器protoc必须在您的$ PATH中才能找到它。