为了账号安全,请及时绑定邮箱和手机立即绑定

使用go模块将retool替换为tools.go,用于多开发人员和CI环境

使用go模块将retool替换为tools.go,用于多开发人员和CI环境

Go
翻阅古今 2023-06-26 16:25:51
我想用 go moduletools.go “工具作为依赖项”替换retool。然而,当我的开发人员和 CI 环境都使用不同的操作系统时,我很难理解这是如何工作的。我想确保每个环境使用完全相同版本的工具。举一个具体的例子,我的应用程序需要 protoc 编译器通过 github.com/golang/protobuf/protoc-gen-go 生成 go 代码。我有 3 个操作系统,都需要使用 protoc-gen-go 插件/生成器执行 protoc:Ryan:使用 MacOS乔:Linux(免费)CI:Linux(CentOS)我目前使用 retool 来确保所有环境都锁定在同一版本的工具上(本例中为 protoc-gen-go):retool do build/bin/protoc -Ibuild/protoc/include -I. rpc/platform/platform.proto --go_out=.我的新 go 模块/“工具作为依赖项”设置工具.go:// +build toolspackage toolsimport (    _ "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-goMacOS 可执行文件。问题:此时,为什么protoc-gen-gogo.mod 中没有列出工具版本(或 git hash)?当 Joe 克隆应用程序存储库时,他如何获取并编译 Ryan 使用的相同版本的 protoc-gen-go?如何protoc知道在我的目录中使用protoc-gen-go可执行文件生成器./bin?
查看完整描述

2 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

我能够按照Go Modules 工具指南以及用于protoc二进制文件的一点 Makefile-Fu完成 protoc 的供应商工具构建(以及Twirp等插件) 。

完整的工作示例可以在 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字符串可以通过诸如操作系统检测 makefile之类的东西来自动化。

继续构建 go 工具。创建一个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在最终构建中过度构建工具导入。


最后,一些代码来构建你的 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 $@


查看完整回答
反对 回复 2023-06-26
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

Go 模块可与 .go 文件的导入一起使用。如果他们找到导入,他们将自动下载满足您要求的最新版本。

此时,为什么 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 中。它必须位于您的 $PATH 中,协议编译器 protoc 才能找到它。


查看完整回答
反对 回复 2023-06-26
  • 2 回答
  • 0 关注
  • 138 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信