dplo59755 2019-06-17 17:59
浏览 72
已采纳

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

I'd like to replace retool with go modules tools.go "tools as dependencies". However I'm struggling to understand how this works when my developers and CI env all use different operating systems.

I want to make sure each environment uses the exact same version of tools.

For a concrete example, my app requires the protoc compiler to generate go code via github.com/golang/protobuf/protoc-gen-go. I have 3 OS, all needing to execute protoc with the protoc-gen-go plugin/generator:

  1. Ryan: uses MacOS
  2. Joe: Linux (Ubuntu)
  3. CI: Linux (CentOS)

I currently use retool to make sure ALL environments are locked in on the same version of tools (protoc-gen-go in this ex):

retool do build/bin/protoc -Ibuild/protoc/include -I. rpc/platform/platform.proto --go_out=.

My new go modules / "tools as dependencies" setup

tools.go:

// +build tools

package tools

import (
    _ "github.com/golang/protobuf/protoc-gen-go"
)

Set the path that go install will use:

export GOBIN=$PWD/bin

Install:

go install github.com/golang/protobuf/protoc-gen-go

If Ryan runs the go install .. a bin/protoc-gen-go MacOS executable is created.

Questions:

  1. At this point, why isprotoc-gen-go tool version (or git hash) NOT listed in go.mod?
  2. When Joe clones the app repo, how does he get and compile the same version of protoc-gen-go that Ryan used?
  3. How does protoc know to use the protoc-gen-go executable generator in my ./bin dir?
  • 写回答

2条回答 默认 最新

  • douhulao7642 2019-06-18 01:14
    关注

    I was able to accomplish vendored tools build for protoc (and plugins like Twirp) following the Go Modules tools guidelines, plus a little Makefile-Fu for the protoc binary.

    A complete working example can be found in the Aspiration Labs pyggpot repo. Following are the essential details. Worth noting: getting the import path right for some of the tools was very fiddly, but ultimately, successful.

    For protoc itself, I vendor the binary release in the Makefile and set it up into a tools/bin dir:

    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 $@
    

    The PROTOC_PLATFORM string can be automated with something like OS detecting makefile. The version of that we use is at https://github.com/aspiration-labs/pyggpot/blob/master/build/makefiles/osvars.mk.

    On to building the go tools. Create a tools.go something like

    // +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"
    )
    

    Note: the // +build tools tag will keep go build from over-building tools imports in your final build.

    Finally, some make code to build your go tools:

    # 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)
    

    And finally, a make setup target to run go mod vendor and process the targets above.

    setup: setup_vendor $(TOOLS_DIR) $(PROTOC) setup_tools
    
    # vendor
    setup_vendor:
        go mod vendor
    
    $(TOOLS_DIR):
        mkdir -v -p $@
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 多址通信方式的抗噪声性能和系统容量对比
  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据