Open4

dependabotとCLIツール

sanematsanemat

goプロジェクトで 単一のgo.mod に寄せる場合, go install版

install-tools:
	go install github.com/x-motemen/gobump/cmd/gobump@$(go list -m -f '{{ .Version }}' github.com/x-motemen/gobump) \

あんまりまじめに調べてない

pros

  • 一番easy

cons

  • よくわからないdev-depsがたくさんになる
    • Node.js npmのdevDependencies, Ruby rubygemsのdevelopment dependencies と思えば別にいいかも
  • 使われる側のツールだとdev-depsを自身の依存に入れたくない
sanematsanemat

go プロジェクトで go.modを分けたい, go install版

tools ディレクトリを作る

tools/tools.go

//go:build tools

package tools

import (
	_ "github.com/x-motemen/gobump"
)

コンパイラにはいっぱい怒られるが特に問題はない

tools/makefile

MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))

.PHONY: install/gobump
install/gobump:
	go install github.com/x-motemen/gobump/cmd/gobump@$(shell cd $(MAKEFILE_DIR) && go list -m -f '{{ .Version }}' github.com/x-motemen/gobump)

.PHONY: install-tools
install-tools: install/gobump

.github/dependabot.yml

version: 2
updates:
- package-ecosystem: gomod
  directory: "/tools"
  schedule:
    interval: daily
    time: "22:00"
  open-pull-requests-limit: 10

pros

  • プロジェクトの依存と分割できる

cons

  • あんまり馴染みがないのかも
  • コンパイラ怒られの消し方がわからない
  • makeがわからない

refs

How to use go run to manage tool dependencies – Alex Edwards https://www.alexedwards.net/blog/using-go-run-to-manage-tool-dependencies
Manage Go tools via Go modules | Marco Franssen https://marcofranssen.nl/manage-go-tools-via-go-modules

sanematsanemat

WIP: go プロジェクトで go.modを分けたい, バイナリインストール編

go installは自前でbuildするわけで、バイナリがあるならバイナリインストールしたい。自前でビルドするのが難しいツールもあるし、rust製ツールとかもバイナリインストールしたい。

まずはなにをしなければいけないのかを makeで書き下してみる

むずい

tools/gobump.mk

MAKEFILE_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
TOOL_VERSION := $(shell cd $(MAKEFILE_DIR) && go list -m -f '{{ .Version }}' github.com/x-motemen/gobump)
BASE_URL := https://github.com/x-motemen/gobump/releases/download
PROJECT_ROOT := $(PWD)
GO_INSTALL_URL := github.com/x-motemen/gobump/cmd/gobump@$(TOOL_VERSION)

# Detect platform and architecture.
PLATFORM ?= $(shell uname -s)
ARCH ?= $(shell uname -m)

# Decide filepath from arch
ifeq ($(ARCH),x86_64)
    ARCHPATH := amd64
else ifeq ($(ARCH),aarch64)
    ARCHPATH := arm64
else ifeq ($(ARCH),i686)
    ARCHPATH := x86
else ifeq ($(ARCH),i386)
    ARCHPATH := x86
endif

# Platform-specific settings.
ifeq ($(PLATFORM),Darwin)
    TARGET_PATH := $(TOOL_VERSION)/gobump_$(TOOL_VERSION)_darwin_$(ARCHPATH).zip
    EXTRACT_DIR := $(MAKEFILE_DIR)$(shell mktemp --dry-run tempXXXXXX)
    TEMP_ARCHIVE_FILE := $(MAKEFILE_DIR)$(shell mktemp --dry-run tempXXXXXX.zip)
    UNPACK_CMD := unzip $(TEMP_ARCHIVE_FILE) -d $(EXTRACT_DIR)
    FILE_IN_ARCHIVE := gobump_$(TOOL_VERSION)_darwin_$(ARCHPATH)/gobump
    BIN_NAME := gobump
else ifeq ($(PLATFORM),Linux)
    TARGET_PATH := $(TOOL_VERSION)/gobump_$(TOOL_VERSION)_linux_$(ARCHPATH).tar.gz
    EXTRACT_DIR := $(MAKEFILE_DIR)$(shell mktemp --dry-run tempXXXXXX)
    TEMP_ARCHIVE_FILE := $(MAKEFILE_DIR)$(shell mktemp --dry-run tempXXXXXX.tar.gz)
    UNPACK_CMD := tar -xzvf $(TEMP_ARCHIVE_FILE) -C $(EXTRACT_DIR)
    FILE_IN_ARCHIVE := gobump_$(TOOL_VERSION)_linux_$(ARCHPATH)/gobump
    BIN_NAME := gobump
else ifneq (,$(or $(findstring CYGWIN,$(PLATFORM)), $(findstring MINGW,$(PLATFORM)), $(findstring MSYS,$(PLATFORM))))
    TARGET_PATH := $(TOOL_VERSION)/gobump_$(TOOL_VERSION)_windows_$(ARCHPATH).zip
    EXTRACT_DIR := $(MAKEFILE_DIR)temp%RANDOM%_$(shell date +%s%N)
    TEMP_ARCHIVE_FILE := $(MAKEFILE_DIR)temp%RANDOM%_$(shell date +%s%N).zip
    UNPACK_CMD := unzip $(TEMP_ARCHIVE_FILE) -d $(EXTRACT_DIR)
    FILE_IN_ARCHIVE := gobump_$(TOOL_VERSION)_windows_$(ARCHPATH)/gobump.exe
    BIN_NAME := gobump.exe
endif

# Set download command.
DOWNLOAD_CMD := curl -L -o $(TEMP_ARCHIVE_FILE) $(BASE_URL)/$(TARGET_PATH)

install:
	@if [ -z "$(PLATFORM)" ] || [ -z "$(ARCH)" ] || [ -z "$(ARCHPATH)" ]; then \
		echo "Missing PLATFORM or ARCH, defaulting to 'go install'."; \
		go install $(GO_INSTALL_URL); \
		exit 0; \
	fi; \
	if $(DOWNLOAD_CMD); then \
        mkdir -p $(EXTRACT_DIR); \
		$(UNPACK_CMD); \
		mkdir -p $(PROJECT_ROOT)/bin; \
		mv $(EXTRACT_DIR)/$(FILE_IN_ARCHIVE) $(PROJECT_ROOT)/bin/$(BIN_NAME); \
		rm -rf $(EXTRACT_DIR); \
		rm -f $(TEMP_ARCHIVE_FILE); \
	else \
		echo "Failed to download. Falling back to 'go install'."; \
		go install $(GO_INSTALL_URL); \
	fi