# Go

## Cheatsheet/References

The following have now been implemented in a GitHub repository that can be found at:

{% embed url="<https://github.com/zephinzer/template-go-service>" %}

### Dockerfile

Pair the following with the Makefile below

```
ARG GO_VERSION=1.21
FROM golang:${GO_VERSION}-alpine AS build
RUN apk add --no-cache ca-certificates git g++ make
WORKDIR /go/src/app
COPY ./go.mod ./go.sum ./
RUN go mod download -x
COPY ./*.go ./
COPY ./cmd ./cmd
COPY ./internal ./internal
ENV CGO_ENABLED=0
RUN make install-swaggo-ci
RUN make docs-swaggo
RUN make deps
RUN make binary
RUN sha256sum ./bin/app > ./bin/app.sha256

FROM scratch AS final
COPY --from=build /go/src/app/bin/app /app
COPY --from=build /go/src/app/bin/app.sha256 /app.sha256
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
ENTRYPOINT ["/app"]
```

### Makefile

This Makefile contains generic-use recipes for a standard Go project

```
APP_NAME := app
BIN_PATH := ./bin
CMD_PATH := ./cmd
IMAGE_PATH := ${APP_NAME}/${APP_NAME}
IMAGE_REGISTRY := docker.io
IMAGE_TAG := latest

# everything before this next line is configurable in the Makefile.properties
-include Makefile.properties
# everything after this line is a derived value from the above variables
IMAGE_URL := ${IMAGE_REGISTRY}/${IMAGE_PATH}

ifeq ("${GOOS}", "windows")
BINARY_EXT := ".exe"
endif

binary:
	@echo "building binary for ${APP_NAME} for os/arch $$(go env GOOS)/$$(go env GOARCH)..."
	@mkdir -p "${BIN_PATH}"
	@go build \
		-ldflags "\
			-extldflags 'static' -s -w \
			-X ${APP_NAME}/internal/constants.AppName=${APP_NAME} \
			-X ${APP_NAME}/internal/constants.BuildTimestamp=$$(date --utc +'%Y-%m-%dT%H:%M:%S') \
			-X ${APP_NAME}/internal/constants.Version=$$(git rev-parse --abbrev-ref HEAD)-$$(git rev-parse HEAD | head -c 6) \
		" \
		-o "${BIN_PATH}/${APP_NAME}${BINARY_EXT}" \
		"${CMD_PATH}/${APP_NAME}"
	@cp "${BIN_PATH}/${APP_NAME}${BINARY_EXT}" "${BIN_PATH}/${APP_NAME}_$$(go env GOOS)_$$(go env GOARCH)${BINARY_EXT}"

deps:
	@echo "updating dependencies..."
	@go mod tidy
	@go mod vendor

docs-swaggo: 
	@echo "generating documentation package..."
	swag init \
		--generalInfo "./internal/api/api.go" \
		--output "${DOCS_OUTPUT_PATH}" \
		--parseInternal \
		--parseDependency \
		--parseDepth 8

image:
	@echo "building image ${IMAGE_URL}:${IMAGE_TAG}..."
	docker build -t ${IMAGE_URL}:${IMAGE_TAG} .

test:
	@echo "running tests..."
	@go test -v -coverpkg=./... -coverprofile=./tests/cover.out ./...
	@go tool cover -func ./tests/cover.out
	@go tool cover -html ./tests/cover.out -o ./tests/cover.html

install-swaggo:
	@echo "installing swag from ${SWAGGO_URL}..."
	go get -u ${SWAGGO_URL}/cmd/swag@latest

install-swaggo-ci:
	@echo "installing swag from ${SWAGGO_URL}..."
	go install ${SWAGGO_URL}/cmd/swag@latest

```

## Useful packages

<table><thead><tr><th width="148.33333333333331">Name</th><th width="310">Description</th><th data-hidden>Link</th></tr></thead><tbody><tr><td>cobra</td><td>CLI structure</td><td><a href="https://github.com/spf13/cobra">https://github.com/spf13/cobra</a></td></tr><tr><td>gofiber</td><td>HTTP server</td><td><a href="https://gofiber.io/">https://gofiber.io/</a></td></tr><tr><td>logrus</td><td>Logger utilities tool</td><td><a href="https://github.com/sirupsen/logrus">https://github.com/sirupsen/logrus</a></td></tr><tr><td>viper</td><td>Configuration management</td><td><a href="https://github.com/spf13/viper">https://github.com/spf13/viper</a></td></tr></tbody></table>
