(Feat): Initial Commit
This commit is contained in:
494
Makefile
Normal file
494
Makefile
Normal file
@@ -0,0 +1,494 @@
|
||||
### -----------------------
|
||||
# --- Building
|
||||
### -----------------------
|
||||
|
||||
# first is default target when running "make" without args
|
||||
build: ##- Default 'make' target: sql, swagger, go-generate-handlers, go-format, go-build and lint.
|
||||
@$(MAKE) build-pre
|
||||
@$(MAKE) go-format
|
||||
@$(MAKE) go-build
|
||||
@$(MAKE) lint
|
||||
|
||||
# useful to ensure that everything gets resetuped from scratch
|
||||
all: clean init ##- Runs all of our common make targets: clean, init, build and test.
|
||||
@$(MAKE) build
|
||||
@$(MAKE) test
|
||||
@$(MAKE) trivy
|
||||
|
||||
info: info-db info-handlers info-go ##- Prints info about spec db, handlers, and go.mod updates, module-name and current go version.
|
||||
|
||||
info-db: ##- (opt) Prints info about spec db.
|
||||
@echo "[spec DB]" > tmp/.info-db
|
||||
@cat scripts/sql/info.sql | psql -q -d "${PSQL_DBNAME}" >> tmp/.info-db
|
||||
@cat tmp/.info-db
|
||||
|
||||
info-handlers: ##- (opt) Prints info about handlers.
|
||||
@echo "[handlers]" > tmp/.info-handlers
|
||||
@gsdev handlers check --print-all >> tmp/.info-handlers
|
||||
@echo "" >> tmp/.info-handlers
|
||||
@cat tmp/.info-handlers
|
||||
|
||||
info-go: ##- (opt) Prints go.mod updates, module-name and current go version.
|
||||
@echo "[go.mod]" > tmp/.info-go
|
||||
@$(MAKE) get-go-outdated-modules >> tmp/.info-go
|
||||
@$(MAKE) info-module-name >> tmp/.info-go
|
||||
@go version >> tmp/.info-go
|
||||
@cat tmp/.info-go
|
||||
|
||||
lint: check-gen-dirs check-script-dir check-handlers check-embedded-modules-go-not go-lint ##- Runs golangci-lint and make check-*.
|
||||
|
||||
# these recipies may execute in parallel
|
||||
build-pre: sql swagger go-generate ##- (opt) Runs pre-build related targets (sql, swagger, go-generate-handlers, go-generate).
|
||||
@$(MAKE) go-generate-handlers
|
||||
|
||||
go-format: ##- (opt) Runs go format.
|
||||
go fmt ./...
|
||||
|
||||
go-build: ##- (opt) Runs go build.
|
||||
go build -ldflags $(LDFLAGS) -o bin/app
|
||||
|
||||
go-lint: ##- (opt) Runs golangci-lint.
|
||||
golangci-lint run --timeout 5m
|
||||
|
||||
go-generate-handlers: ##- (opt) Generates the internal/api/handlers/handlers.go binding.
|
||||
gsdev handlers gen
|
||||
|
||||
go-generate: ##- Runs go generate.
|
||||
@go generate ./...
|
||||
|
||||
check-handlers: ##- (opt) Checks if implemented handlers match their spec (path).
|
||||
gsdev handlers check
|
||||
|
||||
# https://golang.org/pkg/cmd/go/internal/generate/
|
||||
# To convey to humans and machine tools that code is generated,
|
||||
# generated source should have a line that matches the following
|
||||
# regular expression (in Go syntax):
|
||||
# ^// Code generated .* DO NOT EDIT\.$
|
||||
check-gen-dirs: ##- (opt) Ensures internal/models|types only hold generated files.
|
||||
@echo "make check-gen-dirs"
|
||||
@find ./internal/types -name ".*" -prune -o -type f -print | xargs -L1 grep -L '// Code generated .* DO NOT EDIT\.' \
|
||||
|| (echo "Error: Non generated file(s) in ./internal/types!" && exit 1)
|
||||
@find ./internal/models -name ".*" -prune -o -type f -print | xargs -L1 grep -L '// Code generated .* DO NOT EDIT\.' \
|
||||
|| (echo "Error: Non generated file(s) in ./internal/models!" && exit 1)
|
||||
|
||||
check-script-dir: ##- (opt) Ensures all scripts/**/*.go files have the "//go:build scripts" build tag set.
|
||||
@echo "make check-script-dir"
|
||||
@find ./scripts -type f -name '*.go' | xargs -L1 grep -L '//go:build scripts' || (echo "Error: Found unset '//go:build scripts' in ./scripts/**/*.go!" && exit 1)
|
||||
|
||||
# https://github.com/gotestyourself/gotestsum#format
|
||||
# w/o cache https://github.com/golang/go/issues/24573 - see "go help testflag"
|
||||
# note that these tests should not run verbose by default (e.g. use your IDE for this)
|
||||
# TODO: add test shuffling/seeding when landed in go v1.15 (https://github.com/golang/go/issues/28592)
|
||||
# tests by pkgname
|
||||
test: ##- Run tests, output by package, print coverage.
|
||||
@$(MAKE) go-test-by-pkg
|
||||
@$(MAKE) go-test-print-coverage
|
||||
|
||||
# tests by testname
|
||||
test-by-name: ##- Run tests, output by testname, print coverage.
|
||||
@$(MAKE) go-test-by-name
|
||||
@$(MAKE) go-test-print-coverage
|
||||
|
||||
test-update-golden: ##- Refreshes all golden files / snapshot tests by running tests, output by package.
|
||||
@echo "Attempting to refresh all golden files / snapshot tests (TEST_UPDATE_GOLDEN=true)!"
|
||||
@echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} = y ]
|
||||
@TEST_UPDATE_GOLDEN=true gotestsum --hide-summary=skipped -- -race -count=1 ./...
|
||||
|
||||
# note that we explicitly don't want to use a -coverpkg=./... option, per pkg coverage take precedence
|
||||
go-test-by-pkg: ##- (opt) Run tests, output by package.
|
||||
gotestsum --format pkgname-and-test-fails --format-hide-empty-pkg --jsonfile /tmp/test.log -- -race -cover -count=1 -coverprofile=/tmp/coverage.out ./...
|
||||
|
||||
go-test-by-name: ##- (opt) Run tests, output by testname.
|
||||
gotestsum --format testname --jsonfile /tmp/test.log -- -race -cover -count=1 -coverprofile=/tmp/coverage.out ./...
|
||||
|
||||
go-test-print-coverage: ##- (opt) Print overall test coverage (must be done after running tests).
|
||||
@printf "coverage "
|
||||
@go tool cover -func=/tmp/coverage.out | tail -n 1 | awk '{$$1=$$1;print}'
|
||||
|
||||
go-test-print-slowest: ##- Print slowest running tests (must be done after running tests).
|
||||
gotestsum tool slowest --jsonfile /tmp/test.log --threshold 2s
|
||||
|
||||
# TODO: switch to "-m direct" after go 1.17 hits: https://github.com/golang/go/issues/40364
|
||||
get-go-outdated-modules: ##- (opt) Prints outdated (direct) go modules (from go.mod).
|
||||
@((go list -u -m -f '{{if and .Update (not .Indirect)}}{{.}}{{end}}' all) 2>/dev/null | grep " ") || echo "go modules are up-to-date."
|
||||
|
||||
watch-tests: ##- Watches *.go files and runs package tests on modifications.
|
||||
gotestsum --format testname --watch -- -race -count=1
|
||||
|
||||
test-scripts: ##- (opt) Run scripts tests (gsdev), output by package, print coverage.
|
||||
@$(MAKE) go-test-scripts-by-pkg
|
||||
@printf "coverage "
|
||||
@go tool cover -func=/tmp/coverage-scripts.out | tail -n 1 | awk '{$$1=$$1;print}'
|
||||
|
||||
go-test-scripts-by-pkg: ##- (opt) Run scripts tests (gsdev), output by package.
|
||||
gotestsum --format pkgname-and-test-fails --jsonfile /tmp/test.log -- $$(go list -tags scripts ./... | grep "${GO_MODULE_NAME}/scripts") -tags scripts -race -cover -count=1 -coverprofile=/tmp/coverage-scripts.out ./...
|
||||
|
||||
### -----------------------
|
||||
# --- Initializing
|
||||
### -----------------------
|
||||
|
||||
init: ##- Runs make modules, tools and tidy.
|
||||
@$(MAKE) modules
|
||||
@$(MAKE) tools
|
||||
@$(MAKE) tidy
|
||||
|
||||
# cache go modules (locally into .pkg)
|
||||
modules: ##- (opt) Cache packages as specified in go.mod.
|
||||
go mod download
|
||||
|
||||
tools: ##- (opt) Install tools.
|
||||
@go install tool
|
||||
|
||||
tidy: ##- (opt) Tidy our go.sum file.
|
||||
go mod tidy
|
||||
|
||||
### -----------------------
|
||||
# --- SQL
|
||||
### -----------------------
|
||||
|
||||
sql-reset: ##- Wizard to drop and create our development database.
|
||||
@echo "DROP & CREATE database:"
|
||||
@echo " PGHOST=${PGHOST} PGDATABASE=${PGDATABASE}" PGUSER=${PGUSER}
|
||||
@echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} = y ]
|
||||
psql -d postgres -c 'DROP DATABASE IF EXISTS "${PGDATABASE}";'
|
||||
psql -d postgres -c 'CREATE DATABASE "${PGDATABASE}" WITH OWNER ${PGUSER} TEMPLATE "template0";'
|
||||
|
||||
sql-drop-all: ##- Wizard to drop ALL databases: spec, development and tracked by integresql.
|
||||
@echo "DROP ALL:"
|
||||
TO_DROP=$$(psql -qtz0 -d postgres -c "SELECT 'DROP DATABASE \"' || datname || '\";' FROM pg_database WHERE datistemplate = FALSE AND datname != 'postgres';")
|
||||
@echo "$$TO_DROP"
|
||||
@echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} = y ]
|
||||
@echo "Resetting integresql..."
|
||||
curl --fail -X DELETE http://integresql:5000/api/v1/admin/templates
|
||||
@echo "Drop databases..."
|
||||
echo $$TO_DROP | psql -tz0 -d postgres
|
||||
@echo "Done. Please run 'make sql-reset && make sql-spec-reset && make sql-spec-migrate' to reinitialize."
|
||||
|
||||
# This step is only required to be executed when the "migrations" folder has changed!
|
||||
sql: ##- Runs sql format, all sql related checks and finally generates internal/models/*.go.
|
||||
@$(MAKE) sql-format
|
||||
@$(MAKE) sql-regenerate
|
||||
|
||||
sql-regenerate: ##- (opt) Runs sql related checks and finally generates internal/models/*.go.
|
||||
@$(MAKE) sql-check-files
|
||||
@$(MAKE) sql-spec-reset
|
||||
@$(MAKE) sql-spec-migrate
|
||||
@$(MAKE) sql-check-and-generate
|
||||
|
||||
sql-check-and-generate: sql-check-structure sql-boiler ##- (opt) Runs make sql-check-structure and sql-boiler.
|
||||
|
||||
sql-boiler: ##- (opt) Runs sql-boiler introspects the spec db to generate internal/models/*.go.
|
||||
@echo "make sql-boiler"
|
||||
sqlboiler psql
|
||||
|
||||
sql-format: ##- (opt) Formats all *.sql files.
|
||||
@echo "make sql-format"
|
||||
@find ${PWD} -path "*/tmp/*" -prune -name ".*" -prune -o -type f -iname "*.sql" -print \
|
||||
| grep --invert "/app/dumps/" \
|
||||
| grep --invert "/app/test/" \
|
||||
| xargs -i pg_format --inplace {}
|
||||
|
||||
sql-check-files: sql-check-syntax sql-check-migrations-unnecessary-null ##- (opt) Check syntax and unnecessary use of NULL keyword.
|
||||
|
||||
# check syntax via the real database
|
||||
# https://stackoverflow.com/questions/8271606/postgresql-syntax-check-without-running-the-query
|
||||
sql-check-syntax: ##- (opt) Checks syntax of all *.sql files.
|
||||
@echo "make sql-check-syntax"
|
||||
@find ${PWD} -path "*/tmp/*" -prune -name ".*" -prune -path ./dumps -prune -false -o -type f -iname "*.sql" -print \
|
||||
| grep --invert "/app/dumps/" \
|
||||
| grep --invert "/app/test/" \
|
||||
| xargs -i sed '1s#^#DO $$SYNTAX_CHECK$$ BEGIN RETURN;#; $$aEND; $$SYNTAX_CHECK$$;' {} \
|
||||
| psql -d postgres --quiet -v ON_ERROR_STOP=1
|
||||
|
||||
sql-check-migrations-unnecessary-null: ##- (opt) Checks migrations/*.sql for unnecessary use of NULL keywords.
|
||||
@echo "make sql-check-migrations-unnecessary-null"
|
||||
@(grep -R "NULL" ./migrations/ | grep --invert "DEFAULT NULL" | grep --invert "NOT NULL" | grep --invert "WITH NULL" | grep --invert "NULL, " | grep --invert ", NULL" | grep --invert "RETURN NULL" | grep --invert "SET NULL") \
|
||||
&& exit 1 || exit 0
|
||||
|
||||
sql-spec-reset: ##- (opt) Drop and creates our spec database.
|
||||
@echo "make sql-spec-reset"
|
||||
@psql --quiet -d postgres -c 'DROP DATABASE IF EXISTS "${PSQL_DBNAME}";'
|
||||
@psql --quiet -d postgres -c 'CREATE DATABASE "${PSQL_DBNAME}" WITH OWNER ${PSQL_USER} TEMPLATE "template0";'
|
||||
|
||||
sql-spec-migrate: ##- (opt) Applies migrations/*.sql to our spec database.
|
||||
@echo "make sql-spec-migrate"
|
||||
@sql-migrate up -env spec | xargs -i echo "[spec DB]" {}
|
||||
|
||||
sql-check-structure: sql-check-structure-fk-missing-index sql-check-structure-default-zero-values ##- (opt) Runs make sql-check-structure-*.
|
||||
|
||||
sql-check-structure-fk-missing-index: ##- (opt) Ensures spec database objects have FK-indices set.
|
||||
@echo "make sql-check-structure-fk-missing-index"
|
||||
@cat scripts/sql/fk_missing_index.sql | psql -qtz0 --no-align -d "${PSQL_DBNAME}" -v ON_ERROR_STOP=1
|
||||
|
||||
sql-check-structure-default-zero-values: ##- (opt) Ensures spec database objects default values match go zero values.
|
||||
@echo "make sql-check-structure-default-zero-values"
|
||||
@cat scripts/sql/default_zero_values.sql | psql -qtz0 --no-align -d "${PSQL_DBNAME}" -v ON_ERROR_STOP=1
|
||||
|
||||
dumpfile := /app/dumps/development_$(shell date '+%Y-%m-%d-%H-%M-%S').sql
|
||||
sql-dump: ##- Dumps the development database to '/app/dumps/development_YYYY-MM-DD-hh-mm-ss.sql'.
|
||||
@mkdir -p /app/dumps
|
||||
@pg_dump development --format=p --clean --if-exists > $(dumpfile)
|
||||
@echo "Dumped '$(dumpfile)'. Use 'cat $(dumpfile) | psql' to restore"
|
||||
|
||||
watch-sql: ##- Watches *.sql files in /migrations and runs 'make sql-regenerate' on modifications.
|
||||
@echo Watching /migrations. Use Ctrl-c to stop a run or exit.
|
||||
watchexec -p -w migrations --exts sql $(MAKE) sql-regenerate
|
||||
|
||||
### -----------------------
|
||||
# --- Swagger
|
||||
### -----------------------
|
||||
|
||||
swagger: ##- Runs make swagger-concat and swagger-server.
|
||||
@$(MAKE) swagger-concat
|
||||
@$(MAKE) swagger-server
|
||||
|
||||
# Any sibling elements of a $ref are ignored. This is because $ref works by replacing itself and everything on its level with the definition it is pointing at.
|
||||
# https://swagger.io/docs/specification/using-ref/
|
||||
swagger-lint-ref-siblings: ##- (opt) Checks api/**/*.[yml|yaml] for invalid usage of $ref (no siblings).
|
||||
@echo "make swagger-lint-ref-siblings"
|
||||
@rm -f /tmp/swagger-lint-ref-siblings-errors.log && touch /tmp/swagger-lint-ref-siblings-errors.log
|
||||
@find api -type f -name "*.yml" -o -name "*.yaml" \
|
||||
| { \
|
||||
while read ymlfile; \
|
||||
do \
|
||||
ref_siblings=$$(yq e '.. | select(has("$$ref") and length != 1)' $$ymlfile); \
|
||||
([[ -z "$$ref_siblings" ]] \
|
||||
|| (echo "Error: Found invalid \$$ref siblings within $$ymlfile:" \
|
||||
&& (yq -P e '[.. | select(has("$$ref") and length != 1)]' $$ymlfile) \
|
||||
&& (echo $$ymlfile >> /tmp/swagger-lint-ref-siblings-errors.log))); \
|
||||
done \
|
||||
};
|
||||
@[[ "$$(cat /tmp/swagger-lint-ref-siblings-errors.log | wc -l)" -eq "0" ]] \
|
||||
|| (echo "Error: $$(cat /tmp/swagger-lint-ref-siblings-errors.log | wc -l) files have \$$ref(s) with siblings!" \
|
||||
&& false)
|
||||
|
||||
swagger-lint:
|
||||
@echo "make swagger-lint"
|
||||
@spectral lint --fail-severity=warn api/swagger.yml
|
||||
|
||||
# https://goswagger.io/usage/mixin.html
|
||||
# https://goswagger.io/usage/flatten.html
|
||||
swagger-concat: ##- (opt) Regenerates api/swagger.yml based on api/paths/*.
|
||||
@echo "make swagger-concat"
|
||||
@mkdir -p api/tmp
|
||||
@rm -rf api/tmp/*
|
||||
@swagger mixin \
|
||||
--output=api/tmp/tmp.yml \
|
||||
--format=yaml \
|
||||
--keep-spec-order \
|
||||
api/config/main.yml api/paths/* \
|
||||
-q
|
||||
@swagger flatten api/tmp/tmp.yml \
|
||||
--output=api/swagger.yml \
|
||||
--format=yaml \
|
||||
-q
|
||||
@sed -i '1s@^@# // Code generated by "make swagger"; DO NOT EDIT.\n@' api/swagger.yml
|
||||
|
||||
swagger-server: swagger-generate swagger-lint-ref-siblings swagger-validate swagger-lint ##- (opt) Lint/validate api/swagger.yml and generate /internal/types.
|
||||
|
||||
# https://goswagger.io/generate/server.html
|
||||
# Note that we first flag all files to delete (as previously generated), regenerate, then delete all still flagged files
|
||||
# This allows us to ensure that any filewatchers (VScode) don't panic as these files are removed.
|
||||
# --keep-spec-order is broken (/tmp spec resolving): https://github.com/go-swagger/go-swagger/issues/2216
|
||||
swagger-generate: ##- (opt) Generate swagger /internal/types.
|
||||
@echo "make swagger-generate"
|
||||
@rm -rf tmp/testdata/types
|
||||
@mkdir -p tmp/testdata/types
|
||||
@swagger generate server \
|
||||
--allow-template-override \
|
||||
--template-dir=api/templates \
|
||||
--spec=api/swagger.yml \
|
||||
--server-package=tmp/testdata/types \
|
||||
--model-package=tmp/testdata/types \
|
||||
--exclude-main \
|
||||
--skip-validation \
|
||||
--config-file=api/config/go-swagger-config.yml \
|
||||
-q
|
||||
@find tmp/testdata/types -type f -exec sed -i "s|${GO_MODULE_NAME}/tmp/testdata/types|${GO_MODULE_NAME}/internal/types|g" {} \;
|
||||
rsync -au --ignore-times --delete tmp/testdata/types/ internal/types/
|
||||
|
||||
swagger-validate: ##- (opt) Validate api/swagger.yml.
|
||||
@echo "make swagger-validate"
|
||||
@swagger validate --skip-warnings --stop-on-error -q api/swagger.yml
|
||||
|
||||
watch-swagger: ##- Watches *.yml|yaml|gotmpl files in /api and runs 'make swagger' on modifications.
|
||||
@echo "Watching /api/**/*.yml|yaml|gotmpl. Use Ctrl-c to stop a run or exit."
|
||||
watchexec -p -w api -i tmp -i api/swagger.yml --exts yml,yaml,gotmpl $(MAKE) swagger
|
||||
|
||||
### -----------------------
|
||||
# --- Binary checks
|
||||
### -----------------------
|
||||
|
||||
# Got license issues with some dependencies? Provide a custom lichen --config
|
||||
# see https://github.com/uw-labs/lichen#config
|
||||
get-licenses: ##- Prints licenses of embedded modules in the compiled bin/app.
|
||||
lichen bin/app
|
||||
|
||||
get-embedded-modules: ##- Prints embedded modules in the compiled bin/app.
|
||||
go version -m -v bin/app
|
||||
|
||||
get-embedded-modules-count: ##- (opt) Prints count of embedded modules in the compiled bin/app.
|
||||
go version -m -v bin/app | grep $$'\tdep' | wc -l
|
||||
|
||||
check-embedded-modules-go-not: ##- (opt) Checks embedded modules in compiled bin/app against go.not, throws on occurrence.
|
||||
@echo "make check-embedded-modules-go-not"
|
||||
@(mkdir -p tmp 2> /dev/null && go version -m -v bin/app > tmp/.modules)
|
||||
grep -f go.not -F tmp/.modules && (echo "go.not: Found disallowed embedded module(s) in bin/app!" && exit 1) || exit 0
|
||||
|
||||
trivy-report: ##- Prints trivy report for all severities without failing
|
||||
@echo "make trivy-report"
|
||||
@trivy fs /app --exit-code 0 --quiet
|
||||
|
||||
trivy: ##- Runs trivy analysis and fails on HIGH, CRITICAL vulnerabilities.
|
||||
@echo "make trivy"
|
||||
@trivy fs /app --exit-code 1 --severity HIGH,CRITICAL --quiet
|
||||
|
||||
govulncheck: ##- Runs govulncheck.
|
||||
@echo "make govulncheck"
|
||||
@govulncheck /app/...
|
||||
|
||||
### -----------------------
|
||||
# --- Git related
|
||||
### -----------------------
|
||||
|
||||
# This is the default upstream go-starter branch we will use for our comparisons.
|
||||
# You may use a different tag/branch/commit like this:
|
||||
# - Merge with a specific tag, e.g. `go-starter-2021-10-19`: `GIT_GO_STARTER_TARGET=go-starter-2021-10-19 make git-merge-go-starter`
|
||||
# - Merge with a specific branch, e.g. `mr/housekeeping`: `GIT_GO_STARTER_TARGET=go-starter/mr/housekeeping make git-merge-go-starter` (heads up! it's `go-starter/<branchname>`)
|
||||
# - Merge with a specific commit, e.g. `e85bedb9`: `GIT_GO_STARTER_TARGET=e85bedb94c3562602bc23d2bfd09fca3b13d1e02 make git-merge-go-starter`
|
||||
GIT_GO_STARTER_TARGET ?= go-starter/master
|
||||
GIT_GO_STARTER_BASE ?= $(GIT_GO_STARTER_TARGET:go-starter/%=%)
|
||||
|
||||
git-fetch-go-starter: ##- (opt) Fetches upstream GIT_GO_STARTER_TARGET (creating git remote 'go-starter').
|
||||
@echo "GIT_GO_STARTER_TARGET=${GIT_GO_STARTER_TARGET} GIT_GO_STARTER_BASE=${GIT_GO_STARTER_BASE}"
|
||||
@git config remote.go-starter.url >&- || git remote add go-starter https://github.com/allaboutapps/go-starter.git
|
||||
@git fetch go-starter ${GIT_GO_STARTER_BASE}
|
||||
|
||||
git-compare-go-starter: ##- (opt) Compare upstream GIT_GO_STARTER_TARGET to HEAD displaying commits away and git log.
|
||||
@$(MAKE) git-fetch-go-starter
|
||||
@echo "Commits away from upstream go-starter ${GIT_GO_STARTER_TARGET}:"
|
||||
git --no-pager rev-list --pretty=oneline --left-only --count ${GIT_GO_STARTER_TARGET}...HEAD
|
||||
@echo ""
|
||||
@echo "Git log:"
|
||||
git --no-pager log --left-only --pretty="%C(Yellow)%h %C(reset)%ad (%C(Green)%cr%C(reset))%x09 %C(Cyan)%an: %C(reset)%s" --abbrev-commit --count ${GIT_GO_STARTER_TARGET}...HEAD
|
||||
|
||||
git-merge-go-starter: ##- Merges upstream GIT_GO_STARTER_TARGET into current HEAD.
|
||||
@$(MAKE) git-compare-go-starter
|
||||
@(echo "" \
|
||||
&& echo "Attempting to execute 'git merge --no-commit --no-ff --allow-unrelated-histories ${GIT_GO_STARTER_TARGET}' into your current HEAD." \
|
||||
&& echo -n "Are you sure? [y/N]" \
|
||||
&& read ans && [ $${ans:-N} = y ]) || exit 1
|
||||
git merge --no-commit --no-ff --allow-unrelated-histories ${GIT_GO_STARTER_TARGET} || true
|
||||
@echo "Done. We recommend to run 'make force-module-name' to automatically fix all import paths."
|
||||
|
||||
### -----------------------
|
||||
# --- Helpers
|
||||
### -----------------------
|
||||
|
||||
clean: ##- Cleans ./tmp and ./api/tmp folder.
|
||||
@echo "make clean"
|
||||
@rm -rf tmp/* 2> /dev/null
|
||||
@rm -rf api/tmp/* 2> /dev/null
|
||||
|
||||
get-module-name: ##- Prints current go module-name (pipeable).
|
||||
@echo "${GO_MODULE_NAME}"
|
||||
|
||||
info-module-name: ##- (opt) Prints current go module-name.
|
||||
@echo "go module-name: '${GO_MODULE_NAME}'"
|
||||
|
||||
set-module-name: ##- Wizard to set a new go module-name.
|
||||
@rm -f tmp/.modulename
|
||||
@$(MAKE) info-module-name
|
||||
@echo "Enter new go module-name:" \
|
||||
&& read new_module_name \
|
||||
&& echo "new go module-name: '$${new_module_name}'" \
|
||||
&& echo -n "Are you sure? [y/N]" \
|
||||
&& read ans && [ $${ans:-N} = y ] \
|
||||
&& echo -n "Please wait..." \
|
||||
&& find . -not -path '*/\.*' -not -path './Makefile' -type f -exec sed -i "s|${GO_MODULE_NAME}|$${new_module_name}|g" {} \; \
|
||||
&& echo "new go module-name: '$${new_module_name}'!"
|
||||
@rm -f tmp/.modulename
|
||||
|
||||
force-module-name: ##- Overwrite occurrences of 'allaboutapps.dev/aw/go-starter' with current go module-name.
|
||||
find . -not -path '*/\.*' -not -path './Makefile' -type f -exec sed -i "s|allaboutapps.dev/aw/go-starter|${GO_MODULE_NAME}|g" {} \;
|
||||
|
||||
get-go-ldflags: ##- (opt) Prints used -ldflags as evaluated in Makefile used in make go-build
|
||||
@echo $(LDFLAGS)
|
||||
|
||||
help: ##- Show common make targets.
|
||||
@echo -e "usage: make \033[36m<target>\033[0m"
|
||||
@echo "note: use 'make help-all' to see all make targets."
|
||||
@awk 'BEGIN {FS = ":.*#\#-"; } /^[a-zA-Z_-]+:.*?/ && !/(opt)/ { printf " \033[36m%-40s\033[0m %s\n", $$1, $$2 } /^# --- / { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
help-all: ##- Show all make targets.
|
||||
@echo -e "usage: make \033[36m<target>\033[0m"
|
||||
@awk 'BEGIN {FS = ":.*#\#-"; } /^[a-zA-Z_-]+:.*?/ { printf " \033[36m%-40s\033[0m %s\n", $$1, $$2 } /^# --- / { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
### -----------------------
|
||||
# --- Changelog
|
||||
### -----------------------
|
||||
|
||||
changelog-prerelease: ##- Generates a changelog prerelease.
|
||||
@echo "make changelog-prerelease"
|
||||
@changie batch 0.0.0 --prerelease prerelease-$(shell date +%Y-%m-%d-%H%M%S) --move-dir prerelease
|
||||
@git add --all
|
||||
@git commit -m "PRERELEASE: $(shell date +%Y-%m-%d-%H%M%S)"
|
||||
|
||||
changelog-release: ##- Generates a changelog release using the $(VERSION) variable. Usage: make changelog-release VERSION=24.11.0
|
||||
@echo "make changelog-release with version $(VERSION)"
|
||||
@changie batch $(VERSION) --include prerelease --remove-prereleases
|
||||
@changie merge
|
||||
@git add --all
|
||||
@git commit -m "RELEASE: $(VERSION)"
|
||||
|
||||
### -----------------------
|
||||
# --- Make variables
|
||||
### -----------------------
|
||||
|
||||
# only evaluated if required by a recipe
|
||||
# http://make.mad-scientist.net/deferred-simple-variable-expansion/
|
||||
|
||||
# go module name (as in go.mod)
|
||||
GO_MODULE_NAME = $(eval GO_MODULE_NAME := $$(shell \
|
||||
(mkdir -p tmp 2> /dev/null && cat tmp/.modulename 2> /dev/null) \
|
||||
|| (gsdev modulename 2> /dev/null | tee tmp/.modulename) || echo "unknown" \
|
||||
))$(GO_MODULE_NAME)
|
||||
|
||||
# https://medium.com/the-go-journey/adding-version-information-to-go-binaries-e1b79878f6f2
|
||||
ARG_COMMIT = $(eval ARG_COMMIT := $$(shell \
|
||||
(git rev-list -1 HEAD 2> /dev/null) \
|
||||
|| (echo "unknown") \
|
||||
))$(ARG_COMMIT)
|
||||
|
||||
ARG_BUILD_DATE = $(eval ARG_BUILD_DATE := $$(shell \
|
||||
(date -Is 2> /dev/null || date 2> /dev/null || echo "unknown") \
|
||||
))$(ARG_BUILD_DATE)
|
||||
|
||||
# https://www.digitalocean.com/community/tutorials/using-ldflags-to-set-version-information-for-go-applications
|
||||
LDFLAGS = $(eval LDFLAGS := "\
|
||||
-X '$(GO_MODULE_NAME)/internal/config.ModuleName=$(GO_MODULE_NAME)'\
|
||||
-X '$(GO_MODULE_NAME)/internal/config.Commit=$(ARG_COMMIT)'\
|
||||
-X '$(GO_MODULE_NAME)/internal/config.BuildDate=$(ARG_BUILD_DATE)'\
|
||||
")$(LDFLAGS)
|
||||
|
||||
### -----------------------
|
||||
# --- Special targets
|
||||
### -----------------------
|
||||
|
||||
# https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
|
||||
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
|
||||
# ignore matching file/make rule combinations in working-dir
|
||||
.PHONY: test help
|
||||
|
||||
# https://unix.stackexchange.com/questions/153763/dont-stop-makeing-if-a-command-fails-but-check-exit-status
|
||||
# https://www.gnu.org/software/make/manual/html_node/One-Shell.html
|
||||
# required to ensure make fails if one recipe fails (even on parallel jobs) and on pipefails
|
||||
.ONESHELL:
|
||||
|
||||
# # normal POSIX bash shell mode
|
||||
# SHELL = /bin/bash
|
||||
# .SHELLFLAGS = -cEeuo pipefail
|
||||
|
||||
# wrapped make time tracing shell, use it via MAKE_TRACE_TIME=true make <target>
|
||||
SHELL = /app/rksh
|
||||
.SHELLFLAGS = $@
|
||||
Reference in New Issue
Block a user