export SHELL=bash 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 IN_CONTAINER ?= false export IN_CI ?= false export CONTAINER_FILE export CF_PREFIX export DEVELOP export MOUNT_DIR=/mnt/fradrive export SERVICE export SERVICE_VARIANT ?= $(SERVICE) export SERVICE_PARALLEL ?= false export JOB export JOB_ID export CONTAINER_CMD export BASE_PORTS export UNIWORXDB_OPTS ?= -cf export PROD ?= false ifneq ($(PROD),true) export --DEVELOPMENT=--flag uniworx:dev endif export DATE := $(shell date +'%Y-%m-%dT%H-%M-%S') export CURR_DEV = $(shell cat develop/.current) 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 node_modules .npm .cache assets/icons assets/favicons static well-known config/manifest.json -rm -rf .stack-work .stack-work-run .stack-work-test .stack-work-doc .stack-work.lock -rm -rf bin .Dockerfile develop -$(CONTAINER_COMMAND) container 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 prune --all --force --volumes -$(CONTAINER_COMMAND) image prune --all --force -$(CONTAINER_COMMAND) volume prune --force .PHONY: release # HELP: create, commit and push a new release release: ./.gitlab-ci/version.pl -changelog CHANGELOG.md git add CHANGELOG.md VERSION=`.gitlab-ci/version.pl` git tag $${VERSION} git commit -m "chore(release): $${VERSION}" # git push .PHONY: compile compile: $(MAKE) compile-frontend $(MAKE) compile-backend .PHONY: start start: start-postgres start-memcached start-minio start-frontend start-backend; .PHONY: %-backend %-backend: SERVICE=backend %-backend: SERVICE_VARIANT=backend %-backend: SERVICE_PARALLEL=true %-backend: CONTAINER_CMD=localhost/fradrive/backend %-backend: BASE_PORTS = "DEV_PORT_HTTP=3000" "DEV_PORT_HTTPS=3443" .PHONY: %-uniworxdb %-uniworxdb: SERVICE=backend %-uniworxdb: SERVICE_VARIANT=uniworxdb %-uniworxdb: CONTAINER_CMD=localhost/fradrive/backend .PHONY: %-hoogle %-hoogle: SERVICE=backend %-hoogle: SERVICE_VARIANT=hoogle %-hoogle: BASE_PORTS = "HOOGLE_PORT=8081" %-hoogle: CONTAINER_CMD=localhost/fradrive/backend --start-hoogle: HOOGLE_PORT=`cat $(CONTAINER_FILE) | grep 'HOOGLE_PORT=' | sed 's/HOOGLE_PORT=//'` ; \ stack --work-dir=.stack-work-doc hoogle -- server --local --port $${HOOGLE_PORT} .PHONY: %-frontend %-frontend: SERVICE=frontend %-frontend: CONTAINER_CMD=localhost/fradrive/frontend .PHONY: %-postgres %-postgres: SERVICE=postgres %-postgres: BASE_PORTS = "PGPORT=5432" %-postgres: CONTAINER_CMD=localhost/fradrive/postgres .PHONY: %-memcached %-memcached: SERVICE=memcached %-memcached: CONTAINER_CMD=$(MEMCACHED_IMAGE) --port=`cat $(CONTAINER_FILE) | grep 'MEMCACHED_PORT=' | sed 's/MEMCACHED_PORT=//'` %-memcached: BASE_PORTS = "MEMCACHED_PORT=11211" .PHONY: %-minio %-minio: SERVICE=minio %-minio: CONTAINER_CMD=$(MINIO_IMAGE) -- server `mktemp` --address=:`cat $(CONTAINER_FILE) | grep 'UPLOAD_S3_PORT=' | sed 's/UPLOAD_S3_PORT=//'`: %-minio: BASE_PORTS = "UPLOAD_S3_PORT=9000" .PHONY: start-% start-%: JOB=start start-%: CF_PREFIX = "start-" start-%: --act ; .PHONY: compile-% compile-%: JOB=compile compile-%: CF_PREFIX = "compile-" compile-%: --act ; .PHONY: test-% test-%: JOB=test test-%: CF_PREFIX = "test-" test-%: --act ; .PHONY: lint-% lint-%: JOB=lint lint-%: CF_PREFIX = "lint-" lint-%: --act ; --act: --develop_containerized; --develop_%: PORTS = $(foreach PORT,$(BASE_PORTS),$(shell utils/next_free_port.pl $(PORT))) --develop_%: --ensure-develop echo "$(SERVICE_PARALLEL)" ; \ if [[ "$(SERVICE_PARALLEL)" == "false" ]] ; then \ CONTAINER_FILE=$(DEVELOP)/$(CF_PREFIX)$(SERVICE_VARIANT) ; \ JOB_ID=$(JOB) ; \ if [[ -e $${CONTAINER_FILE} ]]; then \ >&2 echo "Another $* service is already running! Use \"make new-develop\" to start a new develop instance despite currently running services." ; \ exit 1 ; \ fi ; \ else \ DEVDIR=$(DEVELOP)/$(SERVICE_VARIANT) ; \ I=`ls $(DEVELOP) | grep '$(SERVICE_VARIANT)' | sed 's/$(SERVICE_VARIANT)-//' | sort -n | tail -n1` ; \ echo "$${I}" ; \ J=$$(($${I}+1)) ; \ CONTAINER_FILE=$${DEVDIR}-$${J} ; \ JOB_ID=$(JOB)-$${J} ; \ fi ; \ echo "$(PORTS)" | sed 's/ /\n/g' > $${CONTAINER_FILE} ; \ $(MAKE) -- --$* CONTAINER_FILE=$${CONTAINER_FILE} JOB_ID=$${JOB_ID} .PHONY: image-rebuild_% # HELP(image-rebuild_{backend,frontend,database,memcached,minio}): force-rebuild the stated docker image image-rebuild_%: $(MAKE) -- --image-build SERVICE=$* NO_CACHE=--no-cache --image-build: ifeq "$(CONTAINER_CMD)" "localhost/fradrive/$(SERVICE)" rm -f .Dockerfile ln -s docker/$(SERVICE)/Dockerfile .Dockerfile MOUNT_DIR=/mnt/fradrive; \ PROJECT_DIR=/mnt/fradrive; \ if [ "$(IN_CI)" == "true" ] ; then \ PROJECT_DIR=/fradrive; \ fi; \ if [ "$(IN_CONTAINER)" == "false" ] ; then \ $(CONTAINER_COMMAND) build $(NO_CACHE) -v $(PWD):$${MOUNT_DIR} --env IN_CONTAINER=true --build-arg MOUNT_DIR=$(MOUNT_DIR) --build-arg PROJECT_DIR=$${PROJECT_DIR} --tag fradrive/$(SERVICE) --file $(PWD)/.Dockerfile ; \ fi else : endif --containerized: --image-build ./utils/watchcontainerrun.sh "$(CONTAINER_COMMAND)" "$(CONTAINER_FILE)" & \ CONTAINER_NAME=fradrive.$(CURR_DEV).$(SERVICE_VARIANT).$(JOB_ID) ; \ CONTAINER_ID=`$(CONTAINER_BGRUN) \ -v $(PWD):$(MOUNT_DIR) \ --env IN_CONTAINER=true \ --env FRADRIVE_MAKE_TARGET="--$(JOB)-$(SERVICE_VARIANT)" \ --env CONTAINER_FILE=$(CONTAINER_FILE) \ --env CONTAINER_NAME=$${CONTAINER_NAME} \ --name $${CONTAINER_NAME} \ $(CONTAINER_CMD) \ ` ; \ printf "CONTAINER_ID=$${CONTAINER_ID}" >> "$(CONTAINER_FILE)" # HELP(start-backend): start yesod-devel instance --start-backend: DEV_PORT_HTTP=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTP=' | sed 's/DEV_PORT_HTTP=//'`; \ DEV_PORT_HTTPS=`cat $(CONTAINER_FILE) | grep 'DEV_PORT_HTTPS=' | sed 's/DEV_PORT_HTTPS=//'`; \ stack --work-dir=.stack-work-run $(--DEVELOPMENT) exec -- yesod devel -p "$${DEV_PORT_HTTP}" -q "$${DEV_PORT_HTTPS}" # HELP(compile-backend): compile backend binaries --compile-backend: stack build --fast --profile --library-profiling --executable-profiling --flag uniworx:-library-only $(--DEVELOPMENT) --local-bin-path $$(pwd)/bin # HELP(lint-backend): lint backend --lint-backend: stack build --test --fast --work-dir=.stack-work-test --flag uniworx:library-only $(--DEVELOPMENT) uniworx:test:hlint # HELP(test-backend): test backend --test-backend: stack build --test --coverage --fast --work-dir=.stack-work-test --flag uniworx:library-only $(--DEVELOPMENT) # HELP(compile-frontend): compile frontend assets --compile-frontend: node_modules assets esbuild.config.mjs npm run build node_modules: package.json package-lock.json npm ci --cache .npm --prefer-offline package-lock.json: package.json npm install --cache .npm --prefer-offline assets: assets/favicons assets/icons; assets/favicons: ./utils/faviconize.pl assets/favicon.svg long assets/favicons assets/icons: node_modules assets/icons-src/fontawesome.json ./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/solid assets/icons-src/fontawesome.json assets/icons/fradrive ./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/regular assets/icons-src/fontawesome.json assets/icons/fradrive -cp assets/icons-src/*.svg assets/icons/fradrive static: node_modules assets esbuild.config.mjs npm run build well-known: static; # HELP(uniworxdb): clear and fill database. requires running postgres # TODO (db-m-$MIGRATION-backend): apply migration (see src/Model/Migration/Definition.hs for list of available migrations) --start-uniworxdb: SERVER_SESSION_ACID_FALLBACK=${SERVER_SESSION_ACID_FALLBACK:-true} ; \ AVSPASS=${AVSPASS:-nopasswordset} ; \ stack $(--DEVELOPMENT) exec uniworxdb -- $(UNIWORXDB_OPTS) # HELP(start-minio): start minio service .PHONY: status # HELP: print develop status: running containers, used ports status: @./utils/develop-status.pl -a # TODO: rework logs .PHONY: log-% # HELP(log-{database,memcached,minio,backend,frontend,hoogle}): inspect output of a given (currently running) service. 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-%: $(CONTAINER_COMMAND) logs --follow `cat $(DEVELOP)/$* | grep CONTAINER_ID= | sed 's/^CONTAINER_ID=//'` # TODO: rework shells .PHONY: %-shell # HELP: launch shell (bash) inside a currently running container %-shell: --%_shell; --shell: $(CONTAINER_COMMAND) exec -it $(EXEC_OPTS) fradrive.$(CURR_DEV).$* $(if $(ENTRYPOINT),$(ENTRYPOINT),/bin/bash) .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: --database-shell; # TODO: rework stops .PHONY: stop # HELP: stop all currently running develop instances stop: rm -rf develop .PHONY: stop-% # HELP(stop-{database,memcached,minio,backend,frontend,hoogle}): stop all currently running develop instances of a given type stop-%: $(SET_DEVELOP) rm -rf $(DEVELOP)/$* stop-container-by-file: rm $(CONTAINER_FILE) stop-container-by-id: $(CONTAINER_COMMAND) stop $(CONTAINER_ID) # CONTAINER_ID=`grep 'CONTAINER_ID=' $(CONTAINER_FILE) | sed 's/CONTAINER_ID=//'` ; \ # $(MAKE) stop-container-by-id CONTAINER_ID=$${CONTAINER_ID} .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