# ------------------------------------------ # Makefile # # Consistent set of targets to support local development of Clojure # and build the Clojure service during CI deployment # # Requirements # - cljstyle # - Clojure CLI aliases # - `:env/dev` to include `dev` directory on class path # - `:env/test` to include `test` directory and libraries to support testing # - `:test/run` to run kaocha kaocha test runner and supporting paths and dependencies # - `:repl/rebel` to start a Rebel terminal UI # - `:package/uberjar` to create an uberjar for the service # - docker # - mega-linter-runner # ------------------------------------------ # .PHONY: ensures target used rather than matching file name # https://makefiletutorial.com/#phony .PHONY: all lint deps dist install deploy pre-commit-check repl test test-ci test-watch clean # ------- Makefile Variables --------- # # run help if no target specified .DEFAULT_GOAL := help # Column the target description is printed from HELP-DESCRIPTION-SPACING := 24 # Tool variables MEGALINTER_RUNNER = npx mega-linter-runner --flavor java --env "'MEGALINTER_CONFIG=.github/config/megalinter.yaml'" --remove-container CLOJURE_TEST_RUNNER = clojure -M:test/env:test/run CLOJURE_EXEC_TEST_RUNNER = clojure -X:test/env:test/run DOCKER-BUILD-LOGFILE := docker-build-log-$(shell date +%y-%m-%d-%T).org # Makefile file and directory name wildcard # EDN-FILES := $(wildcard *.edn) # ------------------------------------ # # ------- Help ----------------------- # # Source: https://nedbatchelder.com/blog/201804/makefile_help_target.html help: ## Describe available tasks in Makefile @grep '^[a-zA-Z]' $(MAKEFILE_LIST) | \ sort | \ awk -F ':.*?## ' 'NF==2 {printf "\033[36m %-$(HELP-DESCRIPTION-SPACING)s\033[0m %s\n", $$1, $$2}' # ------------------------------------ # # ------- Clojure Development -------- # repl: ## Run Clojure REPL with rich terminal UI (Rebel Readline) $(info --------- Run Rebel REPL ---------) clojure -M:test/env:repl/reloaded deps: deps.edn ## Prepare dependencies for test and dist targets $(info --------- Download test and service libraries ---------) clojure -P -X:build dist: build-uberjar ## Build and package Clojure service $(info --------- Build and Package Clojure service ---------) install: build-jar $(info --------- install library jar ---------) clojure -T:build install deploy: build-jar $(info --------- install library jar ---------) clojure -T:build deploy publish: build-jar $(info --------- Build and Package Clojure lib ---------) # Remove files and directories after build tasks # `-` before the command ignores any errors returned clean: ## Clean build temporary files $(info --------- Clean Clojure classpath cache ---------) - rm -rf ./.cpcache ./.clj-kondo ./.lsp # ------------------------------------ # # ------- Testing -------------------- # test-config: ## Print Kaocha test runner configuration $(info --------- Runner Configuration ---------) $(CLOJURE_TEST_RUNNER) --print-config test-profile: ## Profile unit test speed, showing 3 slowest tests $(info --------- Runner Profile Tests ---------) $(CLOJURE_TEST_RUNNER) --plugin kaocha.plugin/profiling test: ## Run unit tests - stoping on first error $(info --------- Runner for unit tests ---------) $(CLOJURE_EXEC_TEST_RUNNER) test-all: ## Run all unit tests regardless of failing tests $(info --------- Runner for all unit tests ---------) $(CLOJURE_EXEC_TEST_RUNNER) :fail-fast? false test-watch: ## Run tests when changes saved, stopping test run on first error $(info --------- Watcher for unit tests ---------) $(CLOJURE_EXEC_TEST_RUNNER) :watch? true test-watch-all: ## Run all tests when changes saved, regardless of failing tests $(info --------- Watcher for unit tests ---------) $(CLOJURE_EXEC_TEST_RUNNER) :fail-fast? false :watch? true # ------------------------------------ # # -------- Build tasks --------------- # build-config: ## Pretty print build configuration $(info --------- View current build config ---------) clojure -T:build/task config build-jar: ## Build a jar archive of Clojure project $(info --------- Build library jar ---------) clojure -T:build/task jar build-uberjar: ## Build a uberjar archive of Clojure project & Clojure runtime $(info --------- Build service Uberjar ---------) clojure -T:build/task uberjar build-clean: ## Clean build assets or given directory $(info --------- Clean Build ---------) clojure -T:build/task clean # ------------------------------------ # # ------- Code Quality --------------- # pre-commit-check: format-check lint test ## Run format, lint and test targets format-check: ## Run cljstyle to check the formatting of Clojure code $(info --------- cljstyle Runner ---------) cljstyle check format-fix: ## Run cljstyle and fix the formatting of Clojure code $(info --------- cljstyle Runner ---------) cljstyle fix lint: ## Run MegaLinter with custom configuration (node.js required) $(info --------- MegaLinter Runner ---------) $(MEGALINTER_RUNNER) lint-fix: ## Run MegaLinter with applied fixes and custom configuration (node.js required) $(info --------- MegaLinter Runner ---------) $(MEGALINTER_RUNNER) --fix lint-clean: ## Clean MegaLinter report information $(info --------- MegaLinter Clean Reports ---------) - rm -rf ./megalinter-reports # ------------------------------------ # # ------- Docker Containers ---------- # docker-build: ## Build Clojure project and run with docker compose $(info --------- Docker Compose Build ---------) docker compose up --build --detach docker-build-log: ## Build Clojure project and run with docker compose - log to file $(info --------- Docker Compose Build ---------) docker compose up --build --detach &> $(DOCKER-BUILD-LOGFILE) | tee $(DOCKER-BUILD-LOGFILE) docker-build-clean: ## Build Clojure project and run with docker compose, removing orphans $(info --------- Docker Compose Build - remove orphans ---------) docker compose up --build --remove-orphans --detach docker-down: ## Shut down containers in docker compose $(info --------- Docker Compose Down ---------) docker compose down swagger-editor: ## Start Swagger Editor in Docker $(info --------- Run Swagger Editor at locahost:8282 ---------) docker compose -f swagger-editor.yml up -d swagger-editor swagger-editor-down: ## Stop Swagger Editor in Docker $(info --------- Run Swagger Editor at locahost:8282 ---------) docker compose -f swagger-editor.yml down # ------------------------------------ # # ------ Continuous Integration ------ # # .DELETE_ON_ERROR: halts if command returns non-zero exit status # https://makefiletutorial.com/#delete_on_error # TODO: focus runner on ^:integration` tests test-ci: deps ## Test runner for integration tests $(info --------- Runner for integration tests ---------) clojure -P -X:test/env:test/run # Run tests, build & package the Clojure code and clean up afterward # `make all` used in Docker builder stage .DELETE_ON_ERROR: all: test-ci dist clean ## Call test-ci dist and clean targets, used for CI # ------------------------------------ #