429 lines
15 KiB
Makefile
429 lines
15 KiB
Makefile
include .gnumake/*.Mak
|
|
|
|
SHELL=bash
|
|
# MAKE=make -d
|
|
|
|
export CONTAINER_COMMAND ?= podman
|
|
export CONTAINER_BGRUN ?= $(CONTAINER_COMMAND) run -dit --network=host
|
|
export CONTAINER_FGRUN ?= $(CONTAINER_COMMAND) run -it --network=host
|
|
|
|
export CONTAINER_NAME ?= $(FRADRIVE_SERVICE)
|
|
|
|
export IN_CONTAINER ?= false
|
|
export IN_CI ?= false
|
|
|
|
export WATCH
|
|
export UNIWORXDB_OPTS ?= -cf
|
|
|
|
export CONTAINER_ID
|
|
export FRADRIVE_SERVICE
|
|
|
|
export DEV_PORT_HTTP
|
|
export DEV_PORT_HTTPS
|
|
export HOOGLE_PORT
|
|
|
|
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 DEVELOP
|
|
export CONTAINER_FILE
|
|
export CONTAINER_FILE_CONTENT
|
|
|
|
export PROD ?= false
|
|
export LOGSIZE ?= 1024
|
|
|
|
# HELP HEADER START
|
|
# To see the definition of all available targets, take a look into the Makefile.
|
|
# Targets starting with '--' are not meant to be directly called.
|
|
# If you want to do so anyway please use 'make -- [--target]' to avoid
|
|
# '[--target]' being treated as option to 'make'.
|
|
#
|
|
#
|
|
# Targets meant to be used by humans are:
|
|
# HELP HEADER END
|
|
|
|
###########################
|
|
##### GENERAL TARGETS #####
|
|
|
|
.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: remove all compilation results in the directory but leave containers and images unharmed
|
|
clean:
|
|
$(MAKE) stop
|
|
-rm -rf node_modules .npm .cache assets/icons assets/favicons static well-known
|
|
-rm -rf .stack-work .stack-work-build .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 container and image 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
|
|
|
|
# TODO: rewrite shell targets to enter shell inside currently running containers, do not just launch new containers!
|
|
.PHONY: %-shell
|
|
# HELP: launches bash-shell inside backend/frontend container
|
|
%-shell: ENTRYPOINT=/bin/bash
|
|
%-shell: --%-shell;
|
|
--%-shell:
|
|
MOUNT_DIR=/mnt/fradrive ; \
|
|
FRADRIVE_SERVICE=$* ; \
|
|
$(MAKE) -- --image-build FRADRIVE_SERVICE=$${FRADRIVE_SERVICE} ; \
|
|
$(CONTAINER_FGRUN) -v $(PWD):$${MOUNT_DIR} --env IN_CONTAINER=true --env CONTAINER_FILE=$(CONTAINER_FILE) --entrypoint $(ENTRYPOINT) --name fradrive.$${FRADRIVE_SERVICE}.interactive.$$(date +'%Y-%m-%dT%H-%M-%S') fradrive/$${FRADRIVE_SERVICE}
|
|
|
|
##### GENERAL TARGETS #####
|
|
###########################
|
|
|
|
|
|
############################################
|
|
##### UNIFIED FRONTEND/BACKEND TARGETS #####
|
|
|
|
.PHONY: start
|
|
# HELP: start database services, frontend and backend
|
|
start: new-develop start-database start-memcached start-minio start-frontend start-backend;
|
|
|
|
.PHONY: compile
|
|
# HELP: compile frontend and backend
|
|
compile:
|
|
$(MAKE) compile-frontend
|
|
$(MAKE) compile-backend
|
|
|
|
.PHONY: lint
|
|
# HELP: lint frontend and backend
|
|
lint: lint-frontend lint-backend;
|
|
|
|
.PHONY: test
|
|
# HELP: test frontend, backend, and check internationalization
|
|
test: start-database test-frontend test-backend i18n-check;
|
|
|
|
##### UNIFIED FRONTEND/BACKEND TARGETS #####
|
|
############################################
|
|
|
|
|
|
############################
|
|
##### FRONTEND TARGETS #####
|
|
|
|
.PHONY: %-frontend
|
|
%-frontend: FRADRIVE_SERVICE=frontend
|
|
%-frontend: --image-build --containerized---%-frontend;
|
|
|
|
--%-frontend: --containerized-static-frontend --containerized-well-known-frontend
|
|
|
|
--start-frontend: static
|
|
npm run start
|
|
|
|
# HELP(compile-frontend): compile frontend
|
|
--compile-frontend: static well-known;
|
|
|
|
# HELP(lint-frontend): lint frontend
|
|
--lint-frontend: eslint.config.js
|
|
npx -- eslint frontend/src $(FIX)
|
|
@echo Hooray! There are no hints.
|
|
|
|
# HELP(test-frontend): test frontend
|
|
--test-frontend: karma.conf.cjs
|
|
@echo Karma frontend tests are currently broken after npm update and have therefor been temporarily disabled.
|
|
# npx -- karma start --conf karma.conf.cjs $(WATCH)
|
|
|
|
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
|
|
./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/solid utils/rename-fa.json assets/icons/fradrive
|
|
./utils/renamer.pl node_modules/@fortawesome/fontawesome-free/svgs/regular utils/rename-fa.json assets/icons/fradrive
|
|
|
|
static: node_modules esbuild.config.mjs assets
|
|
npm run build
|
|
well-known: static;
|
|
|
|
##### FRONTEND TARGETS #####
|
|
############################
|
|
|
|
|
|
###########################
|
|
##### BACKEND TARGETS #####
|
|
|
|
.PHONY: %-backend
|
|
%-backend: FRADRIVE_SERVICE=backend
|
|
%-backend: --image-build --containerized---%-backend;
|
|
|
|
--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 exec -- yesod devel -p "$${DEV_PORT_HTTP}" -q "$${DEV_PORT_HTTPS}"
|
|
--start-hoogle-backend:
|
|
HOOGLE_PORT=`cat $(CONTAINER_FILE) | grep 'HOOGLE_PORT=' | sed 's/HOOGLE_PORT=//'` ; \
|
|
echo "${HOOGLE_PORT}" ; \
|
|
stack --work-dir .stack-work-doc hoogle -- -server --local --port $${HOOGLE_PORT}
|
|
|
|
# HELP(compile-backend): compile backend
|
|
--compile-backend:
|
|
stack build --fast --work-dir .stack-work-build --profile --library-profiling --executable-profiling --flag uniworx:-library-only --local-bin-path $$(pwd)/bin $(stackopts)
|
|
|
|
# HELP(lint-backend): lint backend
|
|
--lint-backend:
|
|
stack build --test --fast --work-dir .stack-work-test --flag uniworx:library-only uniworx:test:hlint $(stackopts)
|
|
|
|
# HELP(test-backend): test backend
|
|
--test-backend:
|
|
stack build --test --coverage --fast --work-dir .stack-work-test --flag uniworx:library-only $(stackopts)
|
|
|
|
# TODO: better name
|
|
.PHONY: db
|
|
# HELP: clear and fill database. requires running postgres
|
|
db: FRADRIVE_SERVICE=backend
|
|
db: CONTAINER_NAME=uniworxdb
|
|
db: --image-build --containerized---db;
|
|
# TODO (db-m-$MIGRATION-backend): apply migration (see src/Model/Migration/Definition.hs for list of available migrations)
|
|
--db-backend: .stack
|
|
SERVER_SESSION_ACID_FALLBACK=${SERVER_SESSION_ACID_FALLBACK:-true} ; \
|
|
AVSPASS=${AVSPASS:-nopasswordset} ; \
|
|
stack --work-dir .stack-work-build exec uniworxdb -- $(UNIWORXDB_OPTS)
|
|
|
|
.PHONY: .stack
|
|
.stack:
|
|
if [ "$(IN_CONTAINER)" == "true" ] ; then \
|
|
$(MAKE) -- --.stack ; \
|
|
else \
|
|
$(MAKE) -- --image-run---.stack ; \
|
|
fi
|
|
--.stack: stack.yaml stack.yaml.lock package.yaml
|
|
stack build --fast --only-dependencies $(stackopts)
|
|
|
|
##### BACKEND TARGETS #####
|
|
###########################
|
|
|
|
|
|
############################
|
|
##### DATABASE TARGETS #####
|
|
|
|
--containerized-database: FRADRIVE_SERVICE=database
|
|
# port forwarding is disabled in --network=host mode; nevertheless it is stated here for documentation reasons
|
|
--containerized-database: docker/database/initdb.sh docker/database/pg_hba.conf docker/database/postgresql.conf docker/database/schema.sql --image-build
|
|
if [ "$(IN_CONTAINER)" == "false" ] ; then \
|
|
$(CONTAINER_BGRUN) --name fradrive.$(FRADRIVE_SERVICE).$$(date +'%Y-%m-%dT%H-%M-%S') fradrive/$(FRADRIVE_SERVICE) ; \
|
|
fi
|
|
|
|
##### DATABASE TARGETS #####
|
|
############################
|
|
|
|
|
|
#############################
|
|
##### CONTAINER TARGETS #####
|
|
|
|
--containerized-%-frontend: FRADRIVE_SERVICE=frontend
|
|
--containerized-%-frontend: --image-build
|
|
$(MAKE) -- --image-run-$*-frontend
|
|
|
|
--containerized-%-backend: FRADRIVE_SERVICE=backend
|
|
--containerized-%-backend: --image-build
|
|
$(MAKE) -- --image-run-$*-backend
|
|
--containerized-%-hoogle: CONTAINER_NAME=hoogle
|
|
--containerized-%-hoogle: --containerized-%-hoogle-backend;
|
|
--containerized---db: CONTAINER_NAME=uniworxdb
|
|
--containerized---db: --containerized-db-backend;
|
|
|
|
--containerized-%-database: FRADRIVE_SERVICE=database
|
|
--containerized-%-database: --image-build
|
|
$(MAKE) -- --image-run-$*-database
|
|
|
|
# --containerized-%-minio: FRADRIVE_SERVICE=minio
|
|
# --containerized-%-minio: --image-build
|
|
# $(MAKE) -- --image-run-$*-minio
|
|
--containerized---start-minio:
|
|
UPLOAD_S3_PORT=`cat $(CONTAINER_FILE) | grep 'UPLOAD_S3_PORT=' | sed 's/UPLOAD_S3_PORT=//'`; \
|
|
MINIO_DIR=`mktemp` ; \
|
|
./utils/watchcontainerrun.sh "$(CONTAINER_COMMAND)" "$(CONTAINER_FILE)" "" "rm -rf $${MINIO_DIR}" & \
|
|
CONTAINER_ID=`$(CONTAINER_BGRUN) --name fradrive.minio.$$(date +'%Y-%m-%dT%H-%M-%S') $(MINIO_IMAGE) -- server $${MINIO_DIR} --address=:$${UPLOAD_S3_PORT}` ; \
|
|
printf "CONTAINER_ID=$${CONTAINER_ID}\nUPLOAD_S3_PORT=$${UPLOAD_S3_PORT}\nMINIO_DIR=$${MINIO_DIR}" >> $(CONTAINER_FILE)
|
|
|
|
# --containerized-%-memcached: FRADRIVE_SERVICE=memcached
|
|
# --containerized-%-memcached: --image-build
|
|
# $(MAKE) -- --image-run-$*-memcached
|
|
--containerized---start-memcached:
|
|
MEMCACHED_PORT=`cat $(CONTAINER_FILE) | grep 'MEMCACHED_PORT=' | sed 's/MEMCACHED_PORT=//'`; \
|
|
./utils/watchcontainerrun.sh "$(CONTAINER_COMMAND)" "$(CONTAINER_FILE)" & \
|
|
CONTAINER_ID=`$(CONTAINER_BGRUN) --name fradrive.memcached.$$(date +'%Y-%m-%dT%H-%M-%S') $(MEMCACHED_IMAGE) --port=$${MEMCACHED_PORT}` ; \
|
|
printf "CONTAINER_ID=$${CONTAINER_ID}\nMEMCACHED_PORT=$${MEMCACHED_PORT}" >> $(CONTAINER_FILE)
|
|
|
|
.PHONY: image-rebuild
|
|
# HELP(image-rebuild-{backend,frontend,database,memcached,minio}): force-rebuild the stated docker image
|
|
image-rebuild-%:
|
|
$(MAKE) -- --image-build FRADRIVE_SERVICE=$* NO_CACHE=--no-cache
|
|
--image-build:
|
|
rm -f .Dockerfile
|
|
ln -s docker/$(FRADRIVE_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/$(FRADRIVE_SERVICE) --file $(PWD)/.Dockerfile ; \
|
|
fi
|
|
|
|
--image-run-%: CONTAINER_NAME ?= $(FRADRIVE_SERVICE)
|
|
--image-run-%: docker/$(FRADRIVE_SERVICE)/Dockerfile
|
|
MOUNT_DIR=/mnt/fradrive; \
|
|
if [ "$(IN_CONTAINER)" == "true" ] ; then \
|
|
$(MAKE) -- $* ; \
|
|
else \
|
|
if [ -z "$(CONTAINER_FILE)" ] ; then \
|
|
$(CONTAINER_FGRUN) -v $(PWD):$${MOUNT_DIR} --env IN_CONTAINER=true --env FRADRIVE_MAKE_TARGET=$* --env CONTAINER_FILE=$(CONTAINER_FILE) --env CONTAINER_FILE_CONTENT=$(CONTAINER_FILE_CONTENT) --env WATCH=$(WATCH) --name fradrive.$(CONTAINER_NAME).$$(date +'%Y-%m-%dT%H-%M-%S') localhost/fradrive/$(FRADRIVE_SERVICE) ; \
|
|
else \
|
|
./utils/watchcontainerrun.sh "$(CONTAINER_COMMAND)" "$(CONTAINER_FILE)" & \
|
|
CONTAINER_ID=`$(CONTAINER_BGRUN) -v $(PWD):$${MOUNT_DIR} --env IN_CONTAINER=true --env FRADRIVE_MAKE_TARGET=$* --env CONTAINER_FILE=$(CONTAINER_FILE) --env CONTAINER_FILE_CONTENT=$(CONTAINER_FILE_CONTENT) --env WATCH=$(WATCH) --name fradrive.$(CONTAINER_NAME).$$(date +'%Y-%m-%dT%H-%M-%S') localhost/fradrive/$(FRADRIVE_SERVICE)` ; \
|
|
echo "CONTAINER_ID=$${CONTAINER_ID}" >> "$(CONTAINER_FILE)"; \
|
|
fi \
|
|
fi
|
|
|
|
|
|
# TODO: move starts below to respective entries, or leave together?
|
|
|
|
start-database: BASE_PORTS = "PGPORT=5432"
|
|
start-database: SINGLETON = true
|
|
|
|
start-memcached: BASE_PORTS = "MEMCACHED_PORT=11211"
|
|
start-memcached: SINGLETON = true
|
|
|
|
start-minio: BASE_PORTS = "UPLOAD_S3_PORT=9000"
|
|
start-minio: SINGLETON = true
|
|
|
|
start-backend: BASE_PORTS = "DEV_PORT_HTTP=3000" "DEV_PORT_HTTPS=3443"
|
|
start-backend: SINGLETON = false
|
|
start-backend: static
|
|
|
|
start-hoogle: BASE_PORTS = "HOOGLE_PORT=8081"
|
|
start-hoogle: SINGLETON = true
|
|
|
|
start-frontend: SINGLETON = false
|
|
start-frontend: WATCH = false
|
|
|
|
# HELP(start-database): start postgres server
|
|
# HELP(start-memcached): start memcached server
|
|
# HELP(start-minio): start minio server
|
|
# HELP(start-backend): serve yesod development site
|
|
# HELP(start-frontend): start frontend watcher. Watches frontend source files for changes and recompiles on change. (TODO: watcher functionality currently broken!)
|
|
# HELP(start-hoogle): serve local hoogle instance
|
|
start-%: FRADRIVE_SERVICE = %
|
|
start-%: PORTS = $(foreach PORT,$(BASE_PORTS),$(shell utils/next_free_port.pl $(PORT)))
|
|
start-%: --develop
|
|
echo "$*"
|
|
echo "$(DATE)"
|
|
echo "DEV $(DEVELOP)"
|
|
if [[ "$(SINGLETON)" = "true" ]]; then \
|
|
CONTAINER_FILE=$(DEVELOP)/$* ; \
|
|
if [[ -e $${CONTAINER_FILE} ]]; then \
|
|
>&2 echo "Another $* service is already running! Use \"make new-develop\" or \"make start\" to start a new develop instance despite currently running services." ; \
|
|
exit 1 ; \
|
|
fi \
|
|
else \
|
|
DEVDIR=$(DEVELOP)/$*; \
|
|
I=`ls $${DEVDIR} | sort -n | tail -n1`; \
|
|
echo "$${I}"; \
|
|
CONTAINER_FILE=$${DEVDIR}-$$(($${I}+1)); \
|
|
fi ; \
|
|
echo "$(PORTS)" | sed 's/ /\n/g' > $${CONTAINER_FILE} ; \
|
|
$(MAKE) -- --containerized---start-$* CONTAINER_FILE=$${CONTAINER_FILE}
|
|
|
|
.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: status
|
|
# HELP: print develop status: running containers, used ports
|
|
status:
|
|
@./utils/develop-status.pl
|
|
|
|
.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-%: --develop
|
|
$(CONTAINER_COMMAND) logs --follow --tail=$(LOGSIZE) `cat $(DEVELOP)/$* | grep CONTAINER_ID= | sed 's/^CONTAINER_ID=//'`
|
|
|
|
##### CONTAINER TARGETS #####
|
|
#############################
|
|
|
|
|
|
# TODO: move targets below to better location
|
|
|
|
DATE := $(shell date +'%Y-%m-%dT%H-%M-%S')
|
|
|
|
CURR_DEV = $(shell ls -1 develop | tail -n1)
|
|
SET_DEVELOP = $(eval DEVELOP=develop/$$(CURR_DEV))
|
|
NEW_DEVELOP = $(eval DEVELOP=develop/$$(DATE))
|
|
|
|
.PHONY: new-develop
|
|
new-develop:
|
|
$(NEW_DEVELOP)
|
|
mkdir -p $(DEVELOP)
|
|
$(MAKE) develop/.current
|
|
.PHONY: --develop
|
|
--develop:
|
|
if ! [[ -e develop ]]; then \
|
|
$(MAKE) new-develop; \
|
|
fi
|
|
$(SET_DEVELOP)
|
|
$(MAKE) develop/.current
|
|
.PHONY: develop/.current
|
|
develop/.current:
|
|
$(SET_DEVELOP)
|
|
echo "$(DEVELOP)" > develop/.current
|
|
|
|
# Some convenience aliases:
|
|
.PHONY: hoogle
|
|
# HELP: alias for start-hoogle
|
|
hoogle: start-hoogle;
|
|
|
|
.PHONY: i18n-check
|
|
# HELP: check internationalization
|
|
i18n-check: --image-run---i18n-check
|
|
--i18n-check:
|
|
./missing-translations.sh
|
|
@echo No missing translations.
|
|
|
|
%.lock:
|
|
[ -e $@ ] || touch $@
|
|
flock -en $@ true
|
|
|
|
.PHONY: --%
|
|
.SUFFIXES: # Delete all default suffixes
|