Hard disagree.
GO_SRCS=$(shell find src -name '*.go' -not -name '*_test.go)
GO_TESTS=$(shell find src -name '*_test.go')
.PHONY: run
docker-run: target/image.target
docker run example
.PHONY: integration-test
integration-test: target/integration-test.target
.PHONY: test
test: target/test.target
target/bin: $(GO_SRCS)
mkdir -p $(@D)
GOOS=linux-amd64 go build -ldflags='-s -w' -o $@
target/context.target: Dockerfile target/bin
rm -fr $(@:.target=)
mkdir -p $(@:.target=)
cp Dockerfile target/bin $(@:.target=)
target/image.target: target/context.target
docker build -t example $(<:.target=)
target/integration-test.target: target/image.target
# TODO: test the docker image
target/test.target: $(GO_SRCS) $(GO_TESTS)
go test
What is your better thing?(The answer is Bazel, but if you think Make is a "supercar".......)
Most (all?) of your Makefile targets don't represent actual files to 'make'.
You're using make to run a bunch of tasks, including where tasks may depend on other tasks having been run before.
A task-runner tool like `just` is better suited to this task. https://github.com/casey/just
`just` has some nice UX improvements over `make`. (e.g. doesn't require soft tabs, can list recipes out of the box, recipes can take command line arguments, supports .env files, can be run from any subdirectory).