############################################################################################# ############################################################################################# ## ## PROJECT-DEFINITIONS ## ############################################################################################# ############################################################################################# COPYRIGHT_TEXT := © 2021 schukai GmbH, Released under the AGPL 3.0 License. ############################################################################################# ############################################################################################# ## ## more general block with standard definitions ## ############################################################################################# ############################################################################################# # get Makefile directory name: http://stackoverflow.com/a/5982798/376773 THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)/ THIS_MAKEFILE:=$(THIS_DIR)$(THIS_MAKEFILE_PATH) # colors BLACK := $(shell tput -Txterm setaf 0) RED := $(shell tput -Txterm setaf 1) GREEN := $(shell tput -Txterm setaf 2) YELLOW := $(shell tput -Txterm setaf 3) LIGHTPURPLE := $(shell tput -Txterm setaf 4) PURPLE := $(shell tput -Txterm setaf 5) BLUE := $(shell tput -Txterm setaf 6) WHITE := $(shell tput -Txterm setaf 7) RESET := $(shell tput -Txterm sgr0) INFO := $(GREEN) COMMENT := $(YELLOW) # Output control and standard outputs MARKER := $(BLUE)[+]$(RESET) ERRORMARKER := $(RED)[-]$(RESET) ## Deactivate the QUIET mode by overwriting the value with space ifndef DEBUG QUIET = @ else QUIET = endif ifndef DONTOPENBROWSER OPENBROWSER = true else OPENBROWSER = false endif ECHO := @echo ECHOMARKER := @echo "$(MARKER) $0" ECHOERRORMARKER := @echo "$(ERRORMARKER) $0" # Use bash instead of sh ## Sets the shell used SHELL = bash # path and binaries AWK := awk CP := cp CD := cd KILL := /bin/kill M4 := m4 MV := mv RM := rm -f MKDIR := mkdir -p SED := sed FIND := find SORT := sort TOUCH := touch WGET := wget CHMOD := chmod RSYNC := rsync DOCKER := docker NPX := npx AWS := aws XARGS := xargs GREP := grep NPM := npm make := make GIT := git NPX := npx NODE := node # Executable Programs the Installed be have to EXECUTABLES = $(AWK) $(CP) $(KILL) $(M4) $(MV) rm mkdir $(SED) $(SORT) $(TOUCH) $(WGET) $(CHMOD) $(NPX) $(FIND) $(XARGS) $(GREP) $(NPM) $(GIT) $(NPX); K := $(foreach exec,$(EXECUTABLES),\ $(if $(shell which $(exec)),some string,$(error "Missing $(exec) in PATH; please install"))) check_defined = \ $(strip $(foreach 1,$1, \ $(call __check_defined,$1,$(strip $(value 2)),$3))) __check_defined = \ $(if $(value $1),, \ $(ECHOERRORMARKER) $(if $2, $2, $1)) ############################################################################################# ############################################################################################# ## ## DEFAULT-TARGETS ## ############################################################################################# ############################################################################################# # @see .PHONY https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets .DEFAULT_GOAL := help .PHONY: print print: $(ECHO) "THIS_MAKEFILE: $(THIS_MAKEFILE)" $(ECHO) "THIS_MAKEFILE_PATH: $(THIS_MAKEFILE_PATH)" $(ECHO) "THIS_DIR: $(THIS_DIR)" # Add a comment to the public targets so that it appears # in this help Use two # characters for a help comment .PHONY: help help: @printf "${COMMENT}Usage:${RESET}\n" @printf " make [target] [arg=\"val\"...]\n\n" @printf "${COMMENT}Available targets:${RESET}\n" @awk '/^[a-zA-Z\-_0-9\.@]+:/ { \ helpMessage = match(lastLine, /^## (.*)/); \ if (helpMessage) { \ helpCommand = substr($$1, 0, index($$1, ":")); \ helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ printf " ${INFO}%-22s${RESET} %s\n", helpCommand, helpMessage; \ } \ } \ { lastLine = $$0 }' $(MAKEFILE_LIST) @printf "\n${COMMENT}Available arguments:${RESET}\n" @printf "\n ${INFO}DONTOPENBROWSER${RESET} disable open chrome" @printf "\n ${INFO}NEXTVERSION${RESET} see target release => 0 – major, 1 – minor (default), 2 – patch\n" @awk '/^(([a-zA-Z\-_0-9\.@]+)\s=)/ { \ helpMessage = match(lastLine, /^## (.*)/); \ if (helpMessage) { \ helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ printf " ${INFO}%-22s${RESET} %s (Default: %s)\n", $$1, helpMessage, $$3; \ } \ } \ { lastLine = $$0 }' $(MAKEFILE_LIST) @printf "\n" .PHONY: variables ## Print all Variables variables: @$(foreach v, $(.VARIABLES), $(if $(filter file,$(origin $(v))), $(info $(INFO)$(v)$(RESET)=$($(v))$(RESET)))) ############################################################################################# ############################################################################################# ## ## DIRECTORIES ## ############################################################################################# ############################################################################################# SCRIPT_PATH := $(THIS_DIR)scripts/ ############################################################################################# ############################################################################################# ## ## GIT-TARGETS ## ############################################################################################# ############################################################################################# ## Current Branch-Tag TAG := - ## Git Commit Message for git-push MESSAGE := current status .PHONY: git-branch ## create new branch (use TAG-Variable) git-branch: ifeq (, $(shell command -v uuidgen)) $(error "No uuidgen in PATH, consider doing apt-get install uuidgen") endif $(QUIET) export BRANCH="MONSTER/$(TAG)/$(shell uuidgen --random)" ; \ $(GIT) checkout -b $${BRANCH} && \ RESULT=$$($(GIT) push origin $$BRANCH 2>&1) && \ RESULT2=$$($(GIT) branch --set-upstream-to=origin/$$BRANCH $$BRANCH) && \ GITLABURL=$$(echo "$$RESULT" | tr '\n' '\#' | grep -o 'remote\:\s*https:\/\/gitlab\.schukai\.com[^ ]*' | cut -d " " -f2-9 | sed -e 's/^[ \t]*//') && \ if $(OPENBROWSER) ; then google-chrome --profile-directory="Default" $$GITLABURL ; fi .PHONY: git-to-master ## git checkout master, fetch and merge git-to-master: $(GIT) checkout master && $(GIT) fetch -pP && $(GIT) merge .PHONY: git-push-to-server ## git push changes to server git-push-to-server: $(GIT) add -A $(GIT) commit -m"$(MESSAGE)" $(GIT) push .PHONY: git-push ## git create branch and push changes to server git-push: git-branch git-push-to-server .PHONY: git-tag ## git create version tag git-tag: $(GIT) tag -a "$(MONSTER_CORE_VERSION)" -m "release $(MONSTER_CORE_VERSION)" ############################################################################################# ############################################################################################# ## ## DEFAULT-DEFINITIONS ## ############################################################################################# ############################################################################################# NODE_MODULES_DIR := $(THIS_DIR)node_modules/ NODE_MODULES_BIN_DIR := $(NODE_MODULES_DIR).bin/ WEBPACK := $(NODE_MODULES_BIN_DIR)webpack BABEL := $(NODE_MODULES_BIN_DIR)babel EXORCIST := $(NODE_MODULES_BIN_DIR)exorcist UGLIFYJS := $(NODE_MODULES_BIN_DIR)uglifyjs C8 := $(NODE_MODULES_BIN_DIR)c8 MOCHA := $(NODE_MODULES_BIN_DIR)mocha JSDOC := $(NODE_MODULES_BIN_DIR)jsdoc $(NODE_MODULES_DIR): $(THIS_DIR)package.json $(QUIET) $(NPM) install ############################################################################################# ## UNTILITIES ############################################################################### ############################################################################################# .PHONY: new-package ## init new package structure new-package: $(QUIET) $(call check_defined, NAME, the variable NAME must be set) $(QUIET) if [ ! -n "$(NAME)" ] ; then exit 3 ; fi $(QUIET) $(MKDIR) $(THIS_DIR)packages/$(NAME)/ $(QUIET) $(CP) -r $(THIS_DIR)templates/* $(THIS_DIR)packages/$(NAME)/ $(QUIET) $(GREP) -rl '%%NAME%%' $(THIS_DIR)packages/$(NAME)/ | xargs sed -i 's/%%NAME%%/$(NAME)/g' ############################################################################################# ## MONSTER CORE ############################################################################# ############################################################################################# ## Name of the subpackage; ex. dom SUBPACKAGE = ifneq ($(strip $(PACKAGE)),) SUBPACKAGE=-$(PACKAGE) endif MONSTER_CORE_DIR := $(THIS_DIR)packages/monster/ MONSTER_DIR := $(THIS_DIR)packages/monster$(SUBPACKAGE)/ MONSTER_TUTORIAL_DIR := $(THIS_DIR)tutorials/ MONSTER_SOURCE_DIR := $(MONSTER_DIR)source/ MONSTER_SOURCE_FILES := $(shell find $(MONSTER_SOURCE_DIR) -name '*.js') MONSTER_RELATIVE_SOURCE_FILES := $(shell find $(MONSTER_SOURCE_DIR) -name '*.js' -exec realpath --relative-to $(THIS_DIR) {} \; ) MONSTER_DIST_DIR := $(MONSTER_DIR)dist/ MONSTER_DIST_MODULE_DIR := $(MONSTER_DIST_DIR)modules/ MONSTER_DIST_MODULES_FILES := $(subst $(MONSTER_SOURCE_DIR), $(MONSTER_DIST_MODULE_DIR), $(MONSTER_SOURCE_FILES)) MONSTER_TEST_DIR := $(MONSTER_DIR)test/ MONSTER_TEST_CASE_DIR := $(MONSTER_TEST_DIR)cases/ MONSTER_BUILD_TEST_BROWSER_DIR := $(SCRIPT_PATH)builds/monster/test-browser/ MONSTER_BUILD_LIB_DIR := $(SCRIPT_PATH)builds/monster/library/ MONSTER_BUILD_LIB_DEV_DIR := $(SCRIPT_PATH)builds/monster/library-dev/ MONSTER_TUTORIALS_FILES_WITHVERSION := $(shell grep -l -r -E "monster($(SUBPACKAGE))?@[0-9]+\.[0-9]+\.[0-9]+" $(MONSTER_TUTORIAL_DIR)) MONSTER_FILES_WITHVERSION := $(shell grep -l -r -E "monster($(SUBPACKAGE))?@[0-9]+\.[0-9]+\.[0-9]+" $(MONSTER_SOURCE_FILES)) $(MONSTER_TEST_CASE_DIR)monster.js $(MONSTER_DIR)README.md $(MONSTER_TUTORIALS_FILES_WITHVERSION) $(MONSTER_SOURCE_DIR)/types/version.js MONSTER_CORE_VERSION := $(shell jq -r ".version" $(MONSTER_CORE_DIR)package.json) MONSTER_VERSION := $(shell jq -r ".version" $(MONSTER_DIR)package.json) LICENSE_C_COMMENT := Monster $(MONSTER_VERSION), $(COPYRIGHT_TEXT) $(MONSTER_DIST_DIR): $(ECHOMARKER) "make directory $(MONSTER_DIST_DIR)" $(QUIET) $(MKDIR) $(MONSTER_DIST_DIR) $(MONSTER_BUILD_TEST_BROWSER_DIR)node_modules/: $(MONSTER_BUILD_TEST_BROWSER_DIR)/package.json $(QUIET) $(CD) $(MONSTER_BUILD_TEST_BROWSER_DIR) ; $(NPM) install ; cd - $(MONSTER_BUILD_LIB_DIR)node_modules/: $(MONSTER_BUILD_LIB_DIR)/package.json $(QUIET) $(CD) $(MONSTER_BUILD_LIB_DIR) ; $(NPM) install ; cd - $(MONSTER_BUILD_LIB_DEV_DIR)node_modules/: $(MONSTER_BUILD_LIB_DEV_DIR)/package.json $(QUIET) $(CD) $(MONSTER_BUILD_LIB_DEV_DIR) ; $(NPM) install ; cd - .PHONY: version-monster version-monster: $(MONSTER_TEST_CASE_DIR)monster.js $(MONSTER_SOURCE_DIR)/types/version.js $(MONSTER_DIR)README.md $(MONSTER_FILES_WITHVERSION) $(MONSTER_TUTORIALS_FILES_WITHVERSION) $(MONSTER_FILES_WITHVERSION): $(MONSTER_DIR)package.json $(MONSTER_CORE_DIR)package.json $(ECHOMARKER) "write $@ monster version $(MONSTER_VERSION) and monster core version $(MONSTER_CORE_VERSION)" $(QUIET) $(SED) -i -E "s/(\/monster$(SUBPACKAGE)@)([0-9]+\.[0-9]+\.[0-9]+)\//\1$(MONSTER_VERSION)\//gi" $@ $(QUIET) $(SED) -i -E "s/(\/monster@)([0-9]+\.[0-9]+\.[0-9]+)\//\1$(MONSTER_CORE_VERSION)\//gi" $@ $(QUIET) $(SED) -i -E "s/(monsterjs\.org\/en\/doc\/)([0-9]+\.[0-9]+\.[0-9]+)\//\1$(MONSTER_CORE_VERSION)\//gi" $@ $(QUIET) $(AWK) -i inplace -v start='/**#@+' -v end='/**#@-*/' -v repl=" /**#@+ dont touch, replaced by make with package.json version */\n monsterVersion = new Version('$(MONSTER_VERSION)')\n /**#@-*/" '$$1 == start{del=2} $$1 == end{$$1 = repl; del=0} !del' $@ $(MONSTER_DIST_DIR)monster.dev.js: $(MONSTER_SOURCE_FILES) $(QUIET) if [ -f $(MONSTER_DIST_DIR)monster.dev.js ] ; then $(RM) $(MONSTER_DIST_DIR)monster.dev.js ; fi; $(QUIET) $(CD) $(MONSTER_BUILD_LIB_DEV_DIR); $(WEBPACK) ; $(CD) - $(QUIET) $(SED) -i '1 i /** $(LICENSE_C_COMMENT) */' $(MONSTER_DIST_DIR)monster.dev.js $(MONSTER_DIST_MODULES_FILES): $(MONSTER_SOURCE_FILES) $(QUIET) $(BABEL) --config-file $(THIS_DIR).babelrc.json --no-comments --out-file $@ --minified --presets @babel/preset-modules $(subst $(MONSTER_DIST_MODULE_DIR), $(MONSTER_SOURCE_DIR), $@) $(QUIET) $(SED) -i '1 i /** $(LICENSE_C_COMMENT) */' $@ .PHONY: uglifyjs-monster uglifyjs-monster: $(MONSTER_DIST_MODULES_FILES) $(ECHOMARKER) "uglifyjs monster modules" $(QUIET) $(UGLIFYJS) --validate --compress --mangle --comments 'schukai' --in-situ $(MONSTER_DIST_MODULES_FILES) $(MONSTER_DIST_DIR)monster.js: $(MONSTER_SOURCE_FILES) $(ECHOMARKER) "build monster" $(CD) $(MONSTER_BUILD_LIB_DIR); $(WEBPACK) ; $(CD) - $(QUIET) $(SED) -i '1 i /** $(LICENSE_C_COMMENT) */' $(MONSTER_DIST_DIR)monster.js .PHONY: build-monster ## create packages build-monster: $(MONSTER_BUILD_LIB_DEV_DIR)node_modules/ $(MONSTER_BUILD_LIB_DIR)node_modules/ $(NODE_MODULES_DIR) version-monster $(MONSTER_DIST_DIR) $(MONSTER_DIST_DIR)monster.js $(MONSTER_DIST_DIR)monster.dev.js $(MONSTER_DIST_MODULES_FILES) .PHONY: test-browser-monster ## create test-browser-monster test-browser-monster: $(MONSTER_BUILD_TEST_BROWSER_DIR)node_modules/ create-polyfill-monster $(ECHOMARKER) "create browser test and start chrome" $(QUIET) $(FIND) $(MONSTER_TEST_CASE_DIR) -type f | $(SED) "s|^$(MONSTER_TEST_CASE_DIR)||" > $(MONSTER_TEST_DIR)web/import.js $(QUIET) $(SED) -i 's|^|import "../cases/|' $(MONSTER_TEST_DIR)web/import.js $(QUIET) $(SED) -i 's|$$|";|' $(MONSTER_TEST_DIR)web/import.js $(QUIET) $(SED) -i "1 i import \"./prepare.js\";" $(MONSTER_TEST_DIR)web/import.js $(QUIET) $(SED) -i "1 i /** this file was created automatically by the make target test-browser-monster */" $(MONSTER_TEST_DIR)web/import.js $(QUIET) $(CD) $(MONSTER_BUILD_TEST_BROWSER_DIR); $(WEBPACK) ; $(CD) - $(QUIET) $(SED) -i -E "/<h1/s_.*_ <h1 style='margin-bottom: 0.1em;'>Monster $(MONSTER_CORE_VERSION)</h1>_" $(MONSTER_TEST_DIR)web/test.html $(MONSTER_TEST_DIR)web/monster.html $(MONSTER_TEST_DIR)web/monster-dev.html $(QUIET) $(SED) -i -E "/id=\"lastupdate\"/s_.*_ <div id=\"lastupdate\" style='font-size:0.7em'>last update $(shell date)</div>_" $(MONSTER_TEST_DIR)web/test.html $(MONSTER_TEST_DIR)web/monster.html $(MONSTER_TEST_DIR)web/monster-dev.html $(QUIET) $(SED) -i -E "s_src=\"([\"]*)\.js.*\"_src=\"\1.js?r=$(shell date +"%T")\"_" $(MONSTER_TEST_DIR)web/test.html $(MONSTER_TEST_DIR)web/monster.html $(MONSTER_TEST_DIR)web/monster-dev.html $(QUIET) $(SED) -i -E "s_dist/([0-9]+\.[0-9]+\.[0-9]+)*/dist/monster_dist/$(MONSTER_CORE_VERSION)/dist/monster_" $(MONSTER_TEST_DIR)web/monster.html $(MONSTER_TEST_DIR)web/monster-dev.html $(QUIET) if $(OPENBROWSER) ; then google-chrome --profile-directory="Default" $(MONSTER_TEST_DIR)web/test.html ; fi .PHONY: test-monster ## test library test-monster: build-monster $(ECHOMARKER) "test monster" $(QUIET) $(NPX) flow $(QUIET) $(MOCHA) --recursive $(MONSTER_TEST_CASE_DIR)** .PHONY: coverage-monster ## coverage library coverage-monster: test-monster $(ECHOMARKER) "coverage monster" $(QUIET) $(C8) --config=$(MONSTER_DIR).c8rc.json $(MOCHA) $(MONSTER_TEST_CASE_DIR)** $(QUIET) if $(OPENBROWSER) ; then google-chrome --profile-directory="Default" $(MONSTER_DIR)coverage/index.html ; fi .PHONY: npm-publish-monster ## publish library to npm npm-publish-monster: build-monster $(ECHOMARKER) "publish monster" $(QUIET) $(CD) $(MONSTER_DIR) ; \ $(NPM) publish --access public ; \ $(CD) - .PHONY: clean-monster ## clean repos clean-monster: $(QUIET) $(RM) --recursive $(MONSTER_DIST_DIR) .PHONY: clean-all-monster ## clean repos complete clean-all-monster: $(QUIET) $(RM) --recursive $(MONSTER_DIST_DIR) $(QUIET) $(RM) --recursive $(MONSTER_DIST_MODULES_FILES) $(QUIET) $(RM) --recursive $(MONSTER_BUILD_TEST_BROWSER_DIR)node_modules/ $(QUIET) $(RM) --recursive $(MONSTER_BUILD_LIB_DIR)node_modules/ $(QUIET) $(RM) --recursive $(MONSTER_BUILD_LIB_DEV_DIR)node_modules/ .PHONY: transfer-monster ## transfer-monster to aws transfer-monster: $(ECHOMARKER) "upload aws" $(QUIET) $(AWS) s3 --only-show-errors cp --recursive $(MONSTER_DIR)/ s3://monsterjs.org/dist/$(MONSTER_CORE_VERSION)/ .PHONY: release-monster ## release monster repos with new version (use NEXTVERSION) release-monster: $(ECHOMARKER) "release monster" $(QUIET) $(SCRIPT_PATH)increase-version.sh "$(MONSTER_CORE_DIR)package.json" $(MONSTER_CORE_VERSION) $(NEXTVERSION) $(QUIET) $(MAKE) clean $(QUIET) $(MAKE) build-monster $(QUIET) $(MAKE) uglifyjs-monster $(QUIET) $(MAKE) test-monster $(QUIET) $(MAKE) coverage-monster DONTOPENBROWSER=true $(QUIET) $(MAKE) test-browser-monster DONTOPENBROWSER=true $(QUIET) $(MAKE) doc-2-aws $(QUIET) $(MAKE) doc-build-versions-dropdown $(QUIET) $(MAKE) git-tag $(QUIET) $(MAKE) transfer-monster $(QUIET) $(MAKE) npm-publish-monster .PHONY: create-polyfill-monster ## create polyfill.io url create-polyfill-monster: $(MONSTER_SOURCE_FILES) $(ECHOMARKER) "create and replace polyfill" $(QUIET) $(SCRIPT_PATH)create-polyfill.sh $(MONSTER_RELATIVE_SOURCE_FILES) ############################################################################################# .PHONY: clean ## clean clean: $(QUIET) $(RM) --recursive $(THIS_DIR)docs/ $(QUIET) $(MAKE) clean-monster .PHONY: clean-all ## clean-all clean-all: $(QUIET) $(RM) --recursive $(NODE_MODULES_DIR) $(QUIET) $(RM) --recursive $(THIS_DIR)docs/ $(QUIET) $(MAKE) clean-all-monster .PHONY: build ## create all packages build: $(QUIET) $(MAKE) build-monster ## make build-monster PACKAGE=dom .PHONY: test ## test all packages test: $(QUIET) $(MAKE) test-monster .PHONY: coverage ## coverage all packages coverage: $(QUIET) $(MAKE) coverage-monster .PHONY: release ## release all packages release: $(QUIET) $(MAKE) release-monster .PHONY: doc ## generate docs doc: test create-polyfill-monster $(THIS_DIR)jsdoc.json $(ECHOMARKER) "create doc" $(QUIET) $(JSDOC) --tutorials $(THIS_DIR)tutorials/ -c $(THIS_DIR)jsdoc.json $(THIS_DIR)README.md # $(QUIET) $(GREP) -rl 'Documentation generated by' $(THIS_DIR)docs/ | $(XARGS) sed -i '/Documentation generated by/d' doc-2-aws: doc doc-build-versions-dropdown $(QUIET) $(AWS) s3 --only-show-errors cp --recursive $(THIS_DIR)docs/ s3://monsterjs.org/en/doc/$(MONSTER_CORE_VERSION)/ .PHONY: doc-build-versions-dropdown doc-build-versions-dropdown: $(THIS_DIR)docs/monster-versions.js $(THIS_DIR)docs/monster-versions.js: $(THIS_DIR)package.json $(MONSTER_CORE_DIR)package.json $(QUIET) $(NODE) $(SCRIPT_PATH)build-versions-dropdown.js $(QUIET) $(AWS) s3 --only-show-errors cp $(THIS_DIR)docs/monster-versions.js s3://monsterjs.org/js/doc/monster-versions.js