Go Makefile Patterns
Go 프로젝트에서 Makefile을 구성하는 일반적인 패턴을 정리한다.
1. 기본 구조
APP_NAME := myapp
VERSION := $(shell git describe --tags --always --dirty)
COMMIT := $(shell git rev-parse --short HEAD)
LDFLAGS := -X main.version=$(VERSION) -X main.commit=$(COMMIT)
.PHONY: all build test lint clean
all: lint test build
build:
CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o bin/$(APP_NAME) ./cmd/$(APP_NAME)
test:
go test -race -cover ./...
lint:
go vet ./...
golangci-lint run
clean:
rm -rf bin/
tidy:
go mod tidy
git diff --exit-code go.mod go.sum
.PHONY는 해당 target이 파일이 아니라 명령어라는 선언이다. 같은 이름의 파일이 있어도 항상 실행된다.
2. 자주 쓰는 Target
run — 로컬 실행
run:
go run ./cmd/$(APP_NAME)
fmt — 코드 포맷팅
fmt:
gofumpt -l -w .
gofmt보다 gofumpt가 더 엄격한 포맷팅을 적용한다.
generate — 코드 생성
generate:
go generate ./...
protobuf, mock, sqlc 등 코드 생성 도구를 실행한다.
coverage — 커버리지 리포트
coverage:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
docker — 컨테이너 빌드
DOCKER_IMAGE := myapp
DOCKER_TAG := $(VERSION)
docker:
docker build -t $(DOCKER_IMAGE):$(DOCKER_TAG) .
3. Migration Target
DB migration 도구와 연동하는 패턴.
MIGRATE := migrate
DB_URL := mysql://user:pass@tcp(localhost:3306)/mydb
migrate-up:
$(MIGRATE) -path migrations -database "$(DB_URL)" up
migrate-down:
$(MIGRATE) -path migrations -database "$(DB_URL)" down 1
migrate-create:
$(MIGRATE) create -ext sql -dir migrations -seq $(name)
make migrate-create name=create_users_table
make migrate-up
make migrate-down
4. 환경별 변수
ENV ?= local
include config/$(ENV).env
export
run:
go run ./cmd/$(APP_NAME)
make run # config/local.env 사용
make run ENV=staging # config/staging.env 사용
?=는 변수가 이미 설정되어 있지 않을 때만 기본값을 할당한다.
5. 실전 예시 (풀 Makefile)
APP_NAME := aap-coordinator
VERSION := $(shell git describe --tags --always --dirty)
COMMIT := $(shell git rev-parse --short HEAD)
LDFLAGS := -X main.version=$(VERSION) -X main.commit=$(COMMIT)
ENV ?= local
.PHONY: all build run test lint fmt tidy clean generate docker migrate-up migrate-down
all: tidy fmt lint test build
build:
CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o bin/$(APP_NAME) ./cmd/$(APP_NAME)
run:
go run ./cmd/$(APP_NAME)
test:
go test -race -cover ./...
lint:
go vet ./...
golangci-lint run
fmt:
gofumpt -l -w .
tidy:
go mod tidy
clean:
rm -rf bin/ coverage.out coverage.html
generate:
go generate ./...
docker:
docker build -t $(APP_NAME):$(VERSION) .
coverage:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
migrate-up:
migrate -path migrations -database "$(DB_URL)" up
migrate-down:
migrate -path migrations -database "$(DB_URL)" down 1
사용
make # all (tidy → fmt → lint → test → build)
make build # 빌드만
make test # 테스트만
make lint # 정적 분석
make run # 로컬 실행
make docker # Docker 이미지 빌드
make migrate-up # DB migration 적용