Unify *-install rules in Makefile #9

Open
opened 2025-03-03 08:37:13 +00:00 by a-savchuk · 3 comments
Member

When working on #6, I noticed that the Makefile is missing a goimports-install rule. Currently, we have many similar rules *-install for installing tools for linting and formatting. We use make to write simple shell scripts, even though make has great metaprogramming capabilities. For example:

STATICCHECK_VERSION ?= 2024.1.1
STATICCHECK_URL = honnef.co/go/tools/cmd/staticcheck

GOFUMPT_VERSION ?= v0.7.0
GOFUMPT_URL = mvdan.cc/gofumpt

LINT_VERSION ?= v1.63.4
LINT_URL = github.com/golangci/golangci-lint/cmd/golangci-lint

GOPLS_VERSION ?= v0.17.1
GOPLS_URL = golang.org/x/tools/gopls

IMPORTS_VERSION ?= latest
IMPORTS_URL = golang.org/x/tools/cmd/goimports

bin = $(abspath bin)
tools = staticcheck gofumpt lint gopls imports

define install_tool_template
$(eval rule_name = $(1))
$(eval var_name = $(shell echo $(rule_name) | tr "[:lower:]" "[:upper:]"))
$(eval tool_version = $$($(var_name)_VERSION))
$(eval tool_url = $$($(var_name)_URL))
$(eval tool_name = $$(lastword $(subst /, ,$(tool_url))))
$(eval tool_dir = $(bin)/$(tool_name))
$(eval tool_version_dir = $(tool_dir)/$(tool_version))

.PHONY: $(rule_name)-install
$(rule_name)-install:
	@rm -rf $(tool_dir)
	@mkdir -p $(tool_dir)
	@echo "⇒ Installing $(tool_name)@$(tool_version)"
	@GO_ENABLED=1 GOBIN=$(tool_version_dir) go install $(tool_url)@$(tool_version)
endef

$(foreach tool,$(tools),$(eval $(call install_tool_template,$(tool))))

.PHONY: tools-install
# Install all tools
tools-install: $(addsuffix -install,$(tools))

Possible problems

  • The Makefile becomes harder to read and maintain for unexperienced make users
  • It's difficult or almost impossible to create a help rule that lists all available rules with their descriptions
When working on #6, I noticed that the Makefile is missing a `goimports-install` rule. Currently, we have many similar rules `*-install` for installing tools for linting and formatting. We use `make` to write simple shell scripts, even though `make` has great metaprogramming capabilities. For example: ```make STATICCHECK_VERSION ?= 2024.1.1 STATICCHECK_URL = honnef.co/go/tools/cmd/staticcheck GOFUMPT_VERSION ?= v0.7.0 GOFUMPT_URL = mvdan.cc/gofumpt LINT_VERSION ?= v1.63.4 LINT_URL = github.com/golangci/golangci-lint/cmd/golangci-lint GOPLS_VERSION ?= v0.17.1 GOPLS_URL = golang.org/x/tools/gopls IMPORTS_VERSION ?= latest IMPORTS_URL = golang.org/x/tools/cmd/goimports bin = $(abspath bin) tools = staticcheck gofumpt lint gopls imports define install_tool_template $(eval rule_name = $(1)) $(eval var_name = $(shell echo $(rule_name) | tr "[:lower:]" "[:upper:]")) $(eval tool_version = $$($(var_name)_VERSION)) $(eval tool_url = $$($(var_name)_URL)) $(eval tool_name = $$(lastword $(subst /, ,$(tool_url)))) $(eval tool_dir = $(bin)/$(tool_name)) $(eval tool_version_dir = $(tool_dir)/$(tool_version)) .PHONY: $(rule_name)-install $(rule_name)-install: @rm -rf $(tool_dir) @mkdir -p $(tool_dir) @echo "⇒ Installing $(tool_name)@$(tool_version)" @GO_ENABLED=1 GOBIN=$(tool_version_dir) go install $(tool_url)@$(tool_version) endef $(foreach tool,$(tools),$(eval $(call install_tool_template,$(tool)))) .PHONY: tools-install # Install all tools tools-install: $(addsuffix -install,$(tools)) ``` ## Possible problems - The Makefile becomes harder to read and maintain for unexperienced `make` users - It's difficult or almost impossible to create a help rule that lists all available rules with their descriptions
a-savchuk added the
discussion
internal
labels 2025-03-03 08:37:13 +00:00
Owner

Refs TrueCloudLab/frostfs-node#389

This repo could serve as a prototype.
I would manage all tools in separate files, including them in Makefile.
See https://git.frostfs.info/TrueCloudLab/basic/src/branch/master/mk

Makefile:

include ci/golangci-lint.mk
include ci/gopls.mk
...

ci/gopls.mk:

include tool.mk

GOPLS_VERSION ?= v0.17.1
GOPLS_URL = golang.org/x/tools/gopls

$(call install_tool_template,gopls)

ci/tool.mk:

define install_tool_template
...
Refs TrueCloudLab/frostfs-node#389 This repo could serve as a prototype. I would manage all tools in separate files, including them in `Makefile`. See https://git.frostfs.info/TrueCloudLab/basic/src/branch/master/mk Makefile: ``` include ci/golangci-lint.mk include ci/gopls.mk ... ``` ci/gopls.mk: ``` include tool.mk GOPLS_VERSION ?= v0.17.1 GOPLS_URL = golang.org/x/tools/gopls $(call install_tool_template,gopls) ``` ci/tool.mk: ``` define install_tool_template ... ```
fyrchik added the
Infrastructure
label 2025-03-03 08:44:24 +00:00
Owner

Maybe we should move to go tool approach, where available?

Maybe we should move to [go tool](https://go.dev/doc/modules/managing-dependencies#tools) approach, where available?
Owner

go tool requires go1.24, we could move this summer
In some cases (golanci-lint with plugins), research is required.

`go tool` requires go1.24, we could move this summer In some cases (golanci-lint with plugins), research is required.
Sign in to join this conversation.
No description provided.