diff --git a/.env b/.env index 41a28d3..c1956e0 100644 --- a/.env +++ b/.env @@ -1,10 +1,6 @@ APP_NAME=bbrew APP_VERSION=0.0.1-local - -### Docker -DOCKER_IMAGE_NAME=bbrew - -### Build -BUILD_GOVERSION=1.20 +CONTAINER_IMAGE_NAME=bbrew +BUILD_GOVERSION=1.25 BUILD_GOOS=darwin BUILD_GOARCH=arm64 \ No newline at end of file diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index b9850e0..0eb4189 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -16,11 +16,11 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: stable + go-version: '1.25' - name: golangci-lint uses: golangci/golangci-lint-action@v8 with: - version: v2.1 + version: v2.5.0 skip-cache: true build: @@ -30,7 +30,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: stable + go-version: '1.25' - name: Get dependencies run: go mod download - name: Build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18a0995..93e9135 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: stable + go-version: '1.25' - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6 diff --git a/Dockerfile b/Containerfile similarity index 65% rename from Dockerfile rename to Containerfile index 09b3600..004b4a7 100644 --- a/Dockerfile +++ b/Containerfile @@ -1,7 +1,7 @@ -FROM golang:1.24 +FROM golang:1.25 # Install dependencies -RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.1.6 +RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0 RUN go install github.com/goreleaser/goreleaser/v2@latest WORKDIR /app \ No newline at end of file diff --git a/Makefile b/Makefile index 89eda1a..321a932 100644 --- a/Makefile +++ b/Makefile @@ -1,62 +1,126 @@ ############################## # VARIABLES ############################## -ifneq (,$(wildcard ./.env)) - include .env - export -endif -%:@ +# Load .env if exists (loaded first so defaults can override if not set) +-include .env + +# Default values (can be overridden by .env or command line) +APP_NAME ?= bbrew +APP_VERSION ?= 0.0.1-local +CONTAINER_IMAGE_NAME ?= bbrew +BUILD_GOVERSION ?= 1.25 +BUILD_GOOS ?= $(shell go env GOOS) +BUILD_GOARCH ?= $(shell go env GOARCH) + +# Container runtime command +CONTAINER_RUN = podman run --rm -v $(PWD):/app $(CONTAINER_IMAGE_NAME) ############################## -# DOCKER +# HELP ############################## -.PHONY: docker-build-image -docker-build-image: - @docker build -t $(DOCKER_IMAGE_NAME) . +.PHONY: help +help: ## Show this help message + @echo "Usage: make [target]" + @echo "" + @echo "Available targets:" + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-25s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort -docker-build-force-recreate: - @docker build --no-cache -t $(DOCKER_IMAGE_NAME) . +.DEFAULT_GOAL := help + +############################## +# CONTAINER +############################## +.PHONY: container-build-image +container-build-image: ## Build container image + @podman build -f Containerfile -t $(CONTAINER_IMAGE_NAME) . + +.PHONY: container-build-force +container-build-force: ## Force rebuild container image (no cache) + @podman build --no-cache -f Containerfile -t $(CONTAINER_IMAGE_NAME) . + +.PHONY: container-clean +container-clean: ## Remove container image + @podman rmi $(CONTAINER_IMAGE_NAME) 2>/dev/null || true ############################## # RELEASE ############################## .PHONY: release-snapshot -release-snapshot: docker-build-image # Builds the project in snapshot mode and releases it [This is used for testing releases] - @docker run --rm -v $(PWD):/app $(DOCKER_IMAGE_NAME) goreleaser release --snapshot --clean +release-snapshot: container-build-image ## Build and release snapshot (testing) + @$(CONTAINER_RUN) goreleaser release --snapshot --clean -.PHONY: build-snapshot # Builds the project in snapshot mode [This is used for testing releases] -build-snapshot: docker-build-image - @docker run --rm -v $(PWD):/app $(DOCKER_IMAGE_NAME) goreleaser build --snapshot --clean +.PHONY: build-snapshot +build-snapshot: container-build-image ## Build snapshot without release + @$(CONTAINER_RUN) goreleaser build --snapshot --clean ############################## # BUILD ############################## .PHONY: build -build: docker-build-image - @docker run --rm -v $(PWD):/app $(DOCKER_IMAGE_NAME) \ - env GOOS=$(BUILD_GOOS) GOARCH=$(BUILD_GOARCH) go build -o $(APP_NAME) ./cmd/$(APP_NAME) +build: container-build-image ## Build the application binary + @$(CONTAINER_RUN) env GOOS=$(BUILD_GOOS) GOARCH=$(BUILD_GOARCH) \ + go build -o $(APP_NAME) ./cmd/$(APP_NAME) + +.PHONY: build-local +build-local: ## Build locally without container (requires Go installed) + @go build -o $(APP_NAME) ./cmd/$(APP_NAME) .PHONY: run -run: build - ./$(APP_NAME) +run: build ## Build and run the application + @./$(APP_NAME) + +.PHONY: clean +clean: ## Clean build artifacts + @rm -f $(APP_NAME) + @rm -rf dist/ ############################## -# HELPER +# QUALITY ############################## .PHONY: quality -quality: docker-build-image - @docker run --rm -v $(PWD):/app $(DOCKER_IMAGE_NAME) golangci-lint run +quality: container-build-image ## Run linter checks + @$(CONTAINER_RUN) golangci-lint run + +.PHONY: quality-local +quality-local: ## Run linter locally (requires golangci-lint installed) + @golangci-lint run + +.PHONY: test +test: ## Run tests + @go test -v ./... + +.PHONY: test-coverage +test-coverage: ## Run tests with coverage + @go test -v -coverprofile=coverage.out ./... + @go tool cover -html=coverage.out -o coverage.html ############################## # WEBSITE ############################## .PHONY: build-site -build-site: +build-site: ## Build the static website @node build.js .PHONY: serve-site -serve-site: +serve-site: ## Serve the website locally @npx http-server docs -p 3000 .PHONY: dev-site -dev-site: build-site serve-site \ No newline at end of file +dev-site: build-site serve-site ## Build and serve the website + +############################## +# UTILITY +############################## +.PHONY: install +install: build-local ## Install binary to $GOPATH/bin + @go install ./cmd/$(APP_NAME) + +.PHONY: deps +deps: ## Download and tidy dependencies + @go mod download + @go mod tidy + +.PHONY: deps-update +deps-update: ## Update all dependencies + @go get -u ./... + @go mod tidy diff --git a/go.mod b/go.mod index 917f030..93d0983 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module bbrew -go 1.24 +go 1.25 require ( github.com/gdamore/tcell/v2 v2.8.1 github.com/rivo/tview v0.0.0-20250625164341-a4a78f1e05cb - golang.org/x/text v0.26.0 + golang.org/x/text v0.27.0 ) require ( @@ -13,6 +13,6 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/rivo/uniseg v0.4.7 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/term v0.32.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/term v0.33.0 // indirect ) diff --git a/go.sum b/go.sum index ece9794..1f862c3 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,12 @@ -github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= -github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= -github.com/gdamore/tcell/v2 v2.7.1 h1:TiCcmpWHiAU7F0rA2I3S2Y4mmLmO9KHxJ7E1QhYzQbc= -github.com/gdamore/tcell/v2 v2.7.1/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg= github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU= github.com/gdamore/tcell/v2 v2.8.1/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/rivo/tview v0.0.0-20241227133733-17b7edb88c57 h1:LmsF7Fk5jyEDhJk0fYIqdWNuTxSyid2W42A0L2YWjGE= -github.com/rivo/tview v0.0.0-20241227133733-17b7edb88c57/go.mod h1:02iFIz7K/A9jGCvrizLPvoqr4cEIx7q54RH5Qudkrss= github.com/rivo/tview v0.0.0-20250625164341-a4a78f1e05cb h1:n7UJ8X9UnrTZBYXnd1kAIBc067SWyuPIrsocjketYW8= github.com/rivo/tview v0.0.0-20250625164341-a4a78f1e05cb/go.mod h1:cSfIYfhpSGCjp3r/ECJb+GKS7cGJnqV8vfjQPwoXyfY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -55,36 +47,33 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= -golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=