fradrive/Makefile

387 lines
13 KiB
Makefile

export SHELL=bash
# MAKE=make -f Makefile-loggingsymbols
# MAKE=make -d
# System information
export CPU_CORES = $(shell cat /proc/cpuinfo | grep '^processor' | wc -l)
export CONTAINER_COMMAND ?= podman
export CONTAINER_BGRUN ?= $(CONTAINER_COMMAND) run -dit --network=host --replace
export CONTAINER_FGRUN ?= $(CONTAINER_COMMAND) run -it --network=host --replace
export IMAGE_REGISTRY = docker.io
export MEMCACHED_IMAGE = $(IMAGE_REGISTRY)/memcached:latest
export MINIO_IMAGE = $(IMAGE_REGISTRY)/minio/minio:latest
export MAILDEV_IMAGE = $(IMAGE_REGISTRY)/maildev/maildev:latest # TODO: needs different port than 1025 to avoid conflicts
export POSTGRES_IMAGE = $(IMAGE_REGISTRY)/library/postgres:12
export LOCAL_CONTAINERFILE
export IN_CONTAINER ?= false
export IN_CI ?= false
export CONTAINER_FILE
export CONTAINER_IDENT
export CF_PREFIX
export DEVELOP
export CONTAINER_ATTACHED
export CONTAINER_INIT
export CONTAINER_CLEANUP
export PROJECT_DIR=/fradrive
export SERVICE
export SERVICE_VARIANT ?= $(SERVICE)
export JOB
export IMAGE
export MAKECALL
export ENTRYPOINT
export EXEC_OPTS
export STACK_CORES = $(shell echo $(($(CPU_CORES)/2)))
export BASE_PORTS
export UNIWORXDB_OPTS ?= -cf
export PROD ?= false
export SRC
ifeq ($(PROD),true)
export --DEVELOPMENT=--flag uniworx:-dev
else
export --DEVELOPMENT=--flag uniworx:dev
endif
export DATE := $(shell date +'%Y-%m-%dT%H-%M-%S')
export CURR_DEV = $(shell cat develop/.current 2>/dev/null)
export SET_DEVELOP = $(eval DEVELOP=develop/$$(CURR_DEV))
export NEW_DEVELOP = $(eval DEVELOP=develop/$$(DATE))
.PHONY: help
# HELP: print out this help message
help:
@if [ -z "$$(which perl 2>/dev/null)" ] ; then \
$(CONTAINER_FGRUN) .:/mnt 'debian:12.5' '/mnt/utils/makehelp.pl' '/mnt/Makefile' ; \
else \
utils/makehelp.pl Makefile ; \
fi
.PHONY: clean
# HELP: stop all running containers and remove all compilation results in the directory (but leave images including dependencies unharmed)
clean:
rm -rf develop
-rm -rf frontend/node_modules .npm .cache frontend/assets/icons frontend/assets/favicons frontend/static well-known config/manifest.json frontend/src/env.sass
-rm -rf .stack-work .stack-work.lock
-rm -rf bin .Dockerfile develop
-$(CONTAINER_COMMAND) container prune --force
.PHONY: clean-images
# HELP: stop all running containers and clean all images from local repositories
clean-images:
rm -rf develop
sleep 5
-$(CONTAINER_COMMAND) system prune --all --force --volumes
-$(CONTAINER_COMMAND) image prune --all --force
-$(CONTAINER_COMMAND) volume prune --force
.PHONY: clean-all
# HELP: like clean but with full container, image, and volume prune
clean-all: clean
-rm -rf .stack
$(CONTAINER_COMMAND) system reset --force
.PHONY: release
# HELP: create, commit and push a new release
# TODO: only release when build and tests are passing!!!
release:
VERSION=`./utils/version.pl -changelog CHANGELOG.md -v` ; \
git add CHANGELOG.md ; \
git commit -m "chore(release): $${VERSION}" ; \
git push ; \
git tag $${VERSION} ; \
git push origin $${VERSION}
.PHONY: compile
# HELP: perform full compilation (frontend and backend)
compile:
$(MAKE) compile-frontend
$(MAKE) compile-backend
.PHONY: start
# HELP: start complete development environment with a fresh test database
start:
$(MAKE) start-postgres
$(MAKE) start-memcached
$(MAKE) start-minio
$(MAKE) compile-frontend
$(MAKE) compile-uniworxdb
$(MAKE) start-backend
.PHONY: %-backend
%-backend: SERVICE=backend
%-backend: SERVICE_VARIANT=backend
%-backend: LOCAL_CONTAINERFILE=true
%-backend: IMAGE=localhost/fradrive/backend
%-backend: BASE_PORTS = "DEV_PORT_HTTP=3000" "DEV_PORT_HTTPS=3443"
.PHONY: %-uniworxdb
%-uniworxdb: SERVICE=backend
%-uniworxdb: SERVICE_VARIANT=uniworxdb
%-uniworxdb: IMAGE=localhost/fradrive/backend
%-uniworxdb: LOCAL_CONTAINERFILE=true
.PHONY: %-ghci
%-ghci: SERVICE=backend
%-ghci: SERVICE_VARIANT=ghci
%-ghci: IMAGE=localhost/fradrive/backend
%-ghci: LOCAL_CONTAINERFILE=true
.PHONY: %-hoogle
%-hoogle: SERVICE=backend
%-hoogle: SERVICE_VARIANT=hoogle
%-hoogle: BASE_PORTS = "HOOGLE_PORT=8081"
%-hoogle: IMAGE=localhost/fradrive/backend
%-hoogle: LOCAL_CONTAINERFILE=true
--start-hoogle:
HOOGLE_PORT=`cat $(CONTAINER_FILE) | grep 'HOOGLE_PORT=' | sed 's/HOOGLE_PORT=//'` ; \
stack $(STACK_CORES) hoogle -- server --local --port $${HOOGLE_PORT}
.PHONY: %-frontend
%-frontend: SERVICE=frontend
%-frontend: SERVICE_VARIANT=frontend
%-frontend: LOCAL_CONTAINERFILE=true
%-frontend: IMAGE=localhost/fradrive/frontend
.PHONY: %-postgres
%-postgres: SERVICE=postgres
%-postgres: SERVICE_VARIANT=postgres
%-postgres: BASE_PORTS = "PGPORT=5432"
%-postgres: IMAGE=--env POSTGRES_HOST_AUTH_METHOD=trust -v ./docker/postgres/pg_hba.conf:/tmp/pg_hba.conf -v ./docker/postgres/postgresql.conf:/tmp/postgresql.conf -v ./docker/postgres/pgconfig.sh:/docker-entrypoint-initdb.d/_pgconfig.sh -v ./docker/postgres/schema.sql:/docker-entrypoint-initdb.d/schema.sql $$(POSTGRES_IMAGE)
%-postgres: LOCAL_CONTAINERFILE=false
.PHONY: %-memcached
%-memcached: SERVICE=memcached
%-memcached: SERVICE_VARIANT=memcached
%-memcached: IMAGE=$$(MEMCACHED_IMAGE) --port=11211
%-memcached: LOCAL_CONTAINERFILE=false
%-memcached: BASE_PORTS = "MEMCACHED_PORT=11211"
.PHONY: %-maildev
%-maildev: SERVICE=maildev
%-maildev: SERVICE_VARIANT=maildev
%-maildev: IMAGE=$$(MAILDEV_IMAGE) --port=1025
%-maildev: LOCAL_CONTAINERFILE=false
%-maildev: BASE_PORTS = "MAILDEV_PORT=1025"
.PHONY: %-release
%-release: PROD=true
%-release: SERVICE=fradrive
%-release: SERVICE_VARIANT=fradrive
%-release: IMAGE=localhost/fradrive/fradrive
%-release: LOCAL_CONTAINERFILE=true
.PHONY: %-minio
%-minio: SERVICE=minio
%-minio: SERVICE_VARIANT=minio
%-minio: IMAGE=$$(MINIO_IMAGE) -- server /tmp/minio
%-minio: LOCAL_CONTAINERFILE=false
%-minio: BASE_PORTS = "UPLOAD_S3_PORT=9000"
.PHONY: start-%
start-%: JOB=start
start-%: CF_PREFIX = start-
start-%: CONTAINER_ATTACHED = false
start-%: --act ;
.PHONY: compile-%
compile-%: JOB=compile
compile-%: CF_PREFIX = compile-
compile-%: CONTAINER_ATTACHED = true
compile-%: --act ;
.PHONY: dependencies-%
dependencies-%: JOB=dependencies
dependencies-%: CF_PREFIX = dependencies-
dependencies-%: CONTAINER_ATTACHED = true
dependencies-%: --act ;
.PHONY: test-%
test-%: JOB=test
test-%: CF_PREFIX = test-
test-%: CONTAINER_ATTACHED = true
test-%: --act ;
.PHONY: lint-%
lint-%: JOB=lint
lint-%: CF_PREFIX = lint-
lint-%: CONTAINER_ATTACHED = true
lint-%: --act ;
.PHONY: shell-%
# HELP(shell-$SERVICE): launch (bash) shell inside a new $SERVICE container
shell-%: JOB=shell
shell-%: CF_PREFIX=shell-
shell-%: CONTAINER_ATTACHED=true
shell-%: --act ;
.PHONY: ghci
# HELP(ghci): launch new backend instance and enter interactive ghci shell
ghci: shell-ghci;
.PHONY: rebuild-%
# HELP(rebuild-{backend,frontend,database,memcached,minio}): force-rebuild a given container image
rebuild-%:
echo "TODO rebuild to be reimplemented"
--act:
echo "TODO new act is currently WIP"
docker compose run --remove-orphans $(SERVICE) make -- --$(JOB)-$(SERVICE_VARIANT)
# For Reverse Proxy Problem see: https://groups.google.com/g/yesodweb/c/2EO53kSOuy0/m/Lw6tq2VYat4J
# HELP(start-backend): start development instance
--start-backend: --dependencies-backend
export YESOD_IP_FROM_HEADER=true; \
export DEV_PORT_HTTP=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTP=' | sed 's/DEV_PORT_HTTP=//'`; \
export DEV_PORT_HTTPS=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTPS=' | sed 's/DEV_PORT_HTTPS=//'`; \
export HOST=127.0.0.1 ; \
export PORT=$${PORT:-$${DEV_PORT_HTTP}} ; \
export DETAILED_LOGGING=$${DETAILED_LOGGING:-true} ; \
export LOG_ALL=$${LOG_ALL:-false} ; \
export LOGLEVEL=$${LOGLEVEL:-info} ; \
export DUMMY_LOGIN=$${DUMMY_LOGIN:-true} ; \
export SERVER_SESSION_ACID_FALLBACK=$${SERVER_SESSION_ACID_FALLBACK:-true} ; \
export SERVER_SESSION_COOKIES_SECURE=$${SERVER_SESSION_COOKIES_SECURE:-false} ; \
export COOKIES_SECURE=$${COOKIES_SECURE:-false} ; \
export ALLOW_DEPRECATED=$${ALLOW_DEPRECATED:-true} ; \
export ENCRYPT_ERRORS=$${ENCRYPT_ERRORS:-false} ; \
export RIBBON=$${RIBBON:-$${HOST:-localhost}} ; \
export APPROOT=$${APPROOT:-http://localhost:$${DEV_PORT_HTTP}} ; \
export AVSPASS=$${AVSPASS:-nopasswordset} ; \
stack $(STACK_CORES) exec --local-bin-path $$(pwd)/bin --copy-bins -- yesod devel -p "$${DEV_PORT_HTTP}" -q "$${DEV_PORT_HTTPS}"
# HELP(compile-backend): compile backend binaries
--compile-backend: --dependencies-backend
stack build $(STACK_CORES) --fast --profile --library-profiling --executable-profiling --flag uniworx:-library-only $(--DEVELOPMENT) --local-bin-path $$(pwd)/bin --copy-bins
# HELP(dependencies-backend): (re-)build backend dependencies
--dependencies-backend: #uniworx.cabal
chown -R `id -un`:`id -gn` "$(PROJECT_DIR)"; \
stack install hpack; stack install yesod-bin; \
stack build -j2 --only-dependencies
# HELP(lint-backend): lint backend
--lint-backend:
stack build $(STACK_CORES) --test --fast --flag uniworx:library-only $(--DEVELOPMENT) uniworx:test:hlint
# HELP(test-backend): test backend
--test-backend:
stack build $(STACK_CORES) --test --coverage --fast --flag uniworx:library-only $(--DEVELOPMENT)
# uniworx.cabal:
# stack exec -- hpack --force
# HELP(compile-frontend): compile frontend frontend/assets
--%-frontend:
cd ./frontend && make $*
--start-frontend: --compile-frontend;
frontend/%:
cd ./frontend && $(MAKE) $*
# --lint-frontend: --compile-frontend
# npm run lint
# --test-frontend: --compile-frontend
# npm run test
# HELP(compile-uniworxdb): clear and fill database. requires running postgres instance (use "make start-postgres" to start one)
# TODO (db-m-$MIGRATION-backend): apply migration (see src/Model/Migration/Definition.hs for list of available migrations)
--compile-uniworxdb: --compile-backend
SERVER_SESSION_ACID_FALLBACK=${SERVER_SESSION_ACID_FALLBACK:-true} ; \
AVSPASS=${AVSPASS:-nopasswordset} ; \
./bin/uniworxdb $(UNIWORXDB_OPTS)
# HELP(shell-ghci): enter ghci shell. Use "make ghci SRC=<MODULE_FILE.hs>" to load specific source modules."
--shell-ghci:
stack ghci -- $(SRC)
# --main-is uniworx:exe:uniworx
# HELP(shell-{backend,frontend,memcached,minio,postgres}): enter (bash) shell inside a new container of a given service
--shell-%:
/bin/bash
# HELP(start-minio): start minio service
.PHONY: status
# HELP: print develop status: running containers, used ports
status:
@./utils/develop-status.pl -a
.PHONY: log-%
# HELP(log-$(JOB)-$(SERVICE)): inspect output of a given service. The service must be currently running When a service supports multiple running instances in one develop (i.e. backend), you need to specify the exact instance by its associated file (e.g. backend-1, backend-2, etc.), please check the contents of the develop/ directory for a list of running instances.
log-%:
DEVELOP=develop/`cat develop/.current` ; \
SEARCH_FILE="$${DEVELOP}/$*" ; \
if [[ ! -e "$${SEARCH_FILE}" ]] ; then \
SEARCH_FILE="$${DEVELOP}/.exited.$*" ; \
fi ; \
if [[ -e "$${SEARCH_FILE}" ]] ; then \
$(CONTAINER_COMMAND) logs --follow `cat "$${SEARCH_FILE}" | grep CONTAINER_ID= | sed 's/^CONTAINER_ID=//'` ; \
else \
>&2 echo "Cannot show log: No develop file found for '$*'" ; \
exit 1 ; \
fi
.PHONY: enter
# HELP: launch (bash) shell inside a currently running container. Use ./enter shell wrapper for more convenient usage, possibly with tab-completion in the future
enter: --ensure-develop
$(MAKE) -- --enter
.PHONY: psql
# HELP: enter psql (postgresql) cli inside a currently running database container
psql: ENTRYPOINT=/usr/bin/psql -d uniworx
psql: EXEC_OPTS=--user postgres
psql: --ensure-develop
$(MAKE) -- --enter CONTAINER_FILE=develop/`cat develop/.current`/start-postgres
--enter:
CONTAINER_ID=`cat $(CONTAINER_FILE) | grep 'CONTAINER_ID=' | sed 's/CONTAINER_ID=//'` ; \
$(CONTAINER_COMMAND) exec -it $(EXEC_OPTS) $${CONTAINER_ID} $(if $(ENTRYPOINT),$(ENTRYPOINT),/bin/bash)
.PHONY: stop
# HELP: stop all currently running develop instances
stop:
rm -rf develop
.PHONY: stop-%
# HELP(stop-SERVICE): stop all currently running develop instances of a given service (i.e. backend,frontend,uniworxdb,hoogle,postgres,...)
# HELP(stop-JOB): stop all currently running develop instances of a given job (i.e. compile,start,test,lint)
stop-compile: CF_PREFIX=compile-
stop-start: CF_PREFIX=start-
stop-test: CF_PREFIX=test-
stop-lint: CF_PREFIX=lint-
stop-%: --stop;
--stop:
$(SET_DEVELOP)
ifdef CF_PREFIX
rm -rf $(DEVELOP)/$(CF_PREFIX)*
endif
ifdef SERVICE_VARIANT
rm -rf $(DEVELOP)/*-$(SERVICE_VARIANT)
endif
.PHONY: new-develop
# HELP: instantiate new development bundle, i.e. create new directory under develop/
new-develop:
$(NEW_DEVELOP)
mkdir -p $(DEVELOP)
$(MAKE) develop/.current
.PHONY: switch-develop
# HELP: switch current develop instance to DEVELOP=...
switch-develop:
if ! [ -e develop/$(DEVELOP) ]; then \
echo "Specified develop $(DEVELOP) does not exist! Not switching." ; \
exit 1 ; \
fi ; \
echo "$(DEVELOP)" > develop/.current
--ensure-develop:
if ! [[ -e develop ]]; then \
$(MAKE) new-develop; \
fi
$(MAKE) develop/.current
$(SET_DEVELOP)
.PHONY: develop/.current
develop/.current:
ls -1 develop | tail -n1 > develop/.current
.PHONY: --%
.SUFFIXES: # Delete all default suffixes