замените retool на tools.go для мульти-разработчиков и CI-сред, использующих модули go - PullRequest
2 голосов
/ 17 июня 2019

Я бы хотел заменить retool на модули go tools.go"Инструменты как зависимости".Однако я изо всех сил пытаюсь понять, как это работает, когда мои разработчики и окружающая среда CI используют разные операционные системы.

Я хочу убедиться, что в каждой среде используются одинаковые версии инструментов.

Дляконкретный пример, моему приложению требуется, чтобы компилятор protoc генерировал код go через github.com/golang/protobuf/protoc-gen-go.У меня есть 3 ОС, все для запуска protoc с плагином / генератором protoc-gen-go:

  1. Райан: использует MacOS
  2. Джо: Linux (Ubuntu)
  3. CI: Linux (CentOS)

В настоящее время я использую retool, чтобы убедиться, что ВСЕ среды заблокированы в одной и той же версии инструментов (protoc-gen-go в этом примере):

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

Мои новые модули go / «инструменты как зависимости» setup

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

Если Райан запускает, исполняемый файл go install .. a bin/protoc-gen-go MacOS создан.

Вопросы :

  1. На этом этапе, почему protoc-gen-go версия инструмента (или git-хэш) НЕ указана в go.mod?
  2. Когда Джо клонирует репозиторий приложения, как он получает и компилирует ту же версию protoc-gen-go, которую использовал Райан?
  3. Как protoc узнает, как использовать protoc-gen-goисполняемый генератор у меня ./bin dir?

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Я смог выполнить вендорную сборку инструментов для protoc (и плагинов типа Twirp ), следуя рекомендациям Go Modules для инструментов , плюс небольшой Makefile-Fu для protoc бинарный.

Полный рабочий пример можно найти в Aspiration Labs pyggpot repo .Ниже приведены основные детали.Стоит отметить: правильное определение пути импорта для некоторых инструментов было очень сложным, но в конечном итоге успешным.

Для самого protoc я продаю двоичный выпуск в Makefile и устанавливаю его в 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 $@

Строка PROTOC_PLATFORM может быть автоматизирована с помощью чего-то вроде OS, обнаруживающего make-файл .Версия, которую мы используем в https://github.com/aspiration-labs/pyggpot/blob/master/build/makefiles/osvars.mk.

On для сборки инструментов 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 $@
0 голосов
/ 18 июня 2019

Модули Go работают с импортом ваших файлов .go.Если они найдут импорт, они автоматически загрузят последнюю версию, которая соответствует вашим требованиям.Вы должны прочитать https://github.com/golang/go/wiki/Modules и понять, как работают модули начиная с Go 1.11 и более поздних версий.

На данном этапе, почему версия инструмента protoc-gen-go (или хэш git) НЕ указанав go.mod?

Это потому, что protoc-gen-go - это просто внешний инструмент для модулей Go.Вы импортируете не golang/protobuf/tree/master/protoc-gen-go, а код, который он генерирует.

Когда Джо клонирует репозиторий приложения, как он получает и компилирует ту же версию 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 узнает, как использовать исполняемый генератор protoc-gen-go в моем ./bin dir?

Fromgithub docs: плагин компилятора protoc-gen-go будет установлен в $ GOPATH / bin, если не установлен $ GOBIN.Он должен быть в вашем $ PATH для того, чтобы компилятор протокола protoc нашел его.

...