Skip to content
Snippets Groups Projects
Makefile 27.13 KiB
#-------------------------------------------------------------------------------
# MASTER MAKEFILE FOR MENTAT-NG PROJECT
#
# This file is part of Mentat system (https://mentat.cesnet.cz/).
#
# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
# Author: Jan Mach <jan.mach@cesnet.cz>
# Use of this source is governed by an MIT license, see LICENSE file.
#-------------------------------------------------------------------------------


#
# Default make target, alias for 'help', you must explicitly choose the target.
#
default: help


#===============================================================================


PROJECT_ID   = mentat
PROJECT_NAME = Mentat

DIR_BIN       = bin
DIR_DOC       = doc
DIR_LIB       = lib
DIR_LIB_HAWAT = lib/hawat

DIR_TEMPLATES_INFORMANT = conf/templates/informant
DIR_TEMPLATES_REPORTER  = conf/templates/reporter
DIR_TEMPLATES_UTEST     = conf/templates/utest

DIR_EVENT_CLASSES = conf/event_classes

BIN_FILES := $(wildcard bin/mentat-*.py)
LIB_FILES := $(shell find $(DIR_LIB) -name '*.py' | grep -v 'test_')

VENV_PYTHON ?= python3
VENV_PATH   ?= venv

PYTHON      = python3
PIP         = pip
NOSETESTS   = nosetests
COVERAGE    = coverage
TWINE       = twine
PYBABEL     = pybabel

CURRENT_DIR = $(shell pwd)

DEV_SERVER      = localhost
DEV_PORT        = 5000
DEV_MAIL_SERVER = localhost
DEV_MAIL_PORT   = 8025

#
# Include common makefile configurations.
#
include Makefile.inc

#
# Include local customized configurations.
#
include Makefile.cfg

#
# Populate certain variables with appropriate default values.
#
BUILD_NUMBER ?= 0
BUILD_SUITE  ?= 'development'

#===============================================================================


#
# Display extensive help information page.
#
help:
	@echo ""
	@echo "                 ███╗   ███╗███████╗███╗   ██╗████████╗ █████╗ ████████╗"
	@echo "                 ████╗ ████║██╔════╝████╗  ██║╚══██╔══╝██╔══██╗╚══██╔══╝"
	@echo "                 ██╔████╔██║█████╗  ██╔██╗ ██║   ██║   ███████║   ██║"
	@echo "                 ██║╚██╔╝██║██╔══╝  ██║╚██╗██║   ██║   ██╔══██║   ██║"
	@echo "                 ██║ ╚═╝ ██║███████╗██║ ╚████║   ██║   ██║  ██║   ██║"
	@echo "                 ╚═╝     ╚═╝╚══════╝╚═╝  ╚═══╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝"
	@echo "                        $(FAINT)Copyright (C) since 2011 CESNET, z.s.p.o$(NC)"
	@echo ""
	@echo " $(GREEN)$(BOLD)╔══════════════════════════════════════════════════════════════════════════════════╗$(NC)"
	@echo " $(GREEN)$(BOLD)║                          LIST OF AVAILABLE MAKE TARGETS                          ║$(NC)"
	@echo " $(GREEN)$(BOLD)╚══════════════════════════════════════════════════════════════════════════════════╝$(NC)"
	@echo ""
	@echo "  $(BLUE)$(BOLD)MAIN TARGETS$(NC)"
	@echo "  $(BLUE)$(BOLD)────────────$(NC)"
	@echo "  * $(GREEN)default$(NC): alias for help, you have to pick a target"
	@echo "  * $(GREEN)help$(NC): print this help message and exit"
	@echo "  * $(GREEN)show-version$(NC): show current project version"
	@echo "  * $(GREEN)show-envstamp$(NC): show information about current development environment"
	@echo "  * $(GREEN)venv [VENV_PYTHON=python3] [VENV_PATH=venv]$(NC): install Python virtual environment for local development"
	@echo "  * $(GREEN)develop$(NC): install and configure project locally for development"
	@echo "  * $(GREEN)deps$(NC): install project dependencies"
	@echo "  * $(GREEN)clean$(NC): cleanup development and build environment"
	@echo "  * $(GREEN)docs$(NC): generate project documentation"
	@echo "  * $(GREEN)check$(NC): perform all checks and tests"
	@echo "  * $(GREEN)build-whl$(NC): perform local build of Python distribution package"
	@echo "  * $(GREEN)build-deb$(NC): perform local build of Debian distribution package"
	@echo ""
	@echo "  $(BLUE)$(BOLD)HELPER TARGETS$(NC)"
	@echo "  $(BLUE)$(BOLD)──────────────$(NC)"
	@echo "  * $(GREEN)deps-prerequisites$(NC): check for development prerequisites"
	@echo "  * $(GREEN)deps-lwchroot$(NC): creating local lightweight chroot subdirectory structure"
	@echo "  * $(GREEN)deps-python$(NC): install Python dependencies"
	@echo "  * $(GREEN)deps-python-dev$(NC): install Python development dependencies"
	@echo "  * $(GREEN)deps-python-upgrade$(NC): upgrade Python dependencies to latest versions"
	@echo "  * $(GREEN)deps-python-upgrade-dev$(NC): upgrade Python development dependencies to latest versions"
	@echo "  * $(GREEN)deps-webui$(NC): install web interface dependencies"
	@echo "  * $(GREEN)deps-webui-upgrade$(NC): upgrade web interface dependencies"
	@echo "  * $(GREEN)deps-geoip$(NC): install geolocation databases"
	@echo "  * $(GREEN)deps-negistry$(NC): install negistry whois database"
	@echo "  * $(GREEN)deps-postgresql$(NC): configure required PostgreSQL user accounts and databases"
	@echo "  * $(GREEN)deps-translations$(NC): compile all available translations"
	@echo ""
	@echo "  * $(GREEN)run-mentat-dev$(NC): run development version of Mentat system"
	@echo "  * $(GREEN)run-webui-dev$(NC): run development web server with development configuration on $(DEV_SERVER):$(DEV_PORT)"
	@echo "  * $(GREEN)run-mailserver-dev$(NC): run development mail server on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)"
	@echo ""
	@echo "  * $(GREEN)ctrl-mentat-dev COMMAND=cmd$(NC): execute mentat-controller.py with given command $(FAINT)cmd$(NC)"
	@echo ""
	@echo "  * $(GREEN)clean-pycs$(NC): clean up Python compiled files"
	@echo "  * $(GREEN)clean-build-docs$(NC): clean up documentation build directories"
	@echo "  * $(GREEN)clean-build-python$(NC): clean up Python build directories"
	@echo "  * $(GREEN)clean-build-debian$(NC):  clean up Debian build directories"
	@echo ""
	@echo "  * $(GREEN)docs-sync$(NC): synchronize documentation from submodules"
	@echo "  * $(GREEN)docs-sphinx$(NC): generate local project documentation"
	@echo "  * $(GREEN)docs-view$(NC): view local project documentation"
	@echo "  * $(GREEN)presentations$(NC): project presentations"
	@echo ""
	@echo "  * $(GREEN)pybabel-patch$(NC): patch babel library"
	@echo "  * ${GREEN}cpybabel-init INIT_LOCALE=lc${NC}: extract and init event_classes translations for given locale $(FAINT)lc$(NC)"
	@echo "  * $(GREEN)cpybabel-update$(NC): extract and update event_classes translations"
	@echo "  * $(GREEN)cpybabel-compile$(NC): compile event_classes translations"
	@echo "  * ${GREEN}hpybabel-init INIT_LOCALE=lc${NC}: extract and init Hawat translations for given locale $(FAINT)lc$(NC)"
	@echo "  * $(GREEN)hpybabel-update$(NC): extract and update Hawat translations"
	@echo "  * $(GREEN)hpybabel-compile$(NC): compile Hawat translations"
	@echo "  * ${GREEN}mpybabel-init INIT_LOCALE=lc${NC}: extract and init Mentat translations for given locale $(FAINT)lc$(NC)"
	@echo "  * $(GREEN)mpybabel-update$(NC): extract and update Mentat translations"
	@echo "  * $(GREEN)mpybabel-compile$(NC): compile Mentat translations"
	@echo "  * $(GREEN)translations-compile$(NC): compile all available translations"
	@echo ""
	@echo "  * $(GREEN)pyflakes$(NC): check project with pyflakes"
	@echo "  * $(GREEN)pylint$(NC): check project with pylint"
	@echo "  * $(GREEN)test$(NC): run unit tests with nosetest"
	@echo "  * $(GREEN)coverage$(NC): check test code coverage with nosetest and coverage"
	@echo ""
	@echo "  * $(GREEN)build-webui$(NC): setup web interface locally"
	@echo "  * $(GREEN)build-package-whl$(NC): actually generate Python package"
	@echo "  * $(GREEN)build-package-deb$(NC): actually generate Debian package"
	@echo ""
	@echo "  * $(GREEN)install-whl-dev$(NC): installing project for development in editable mode"
	@echo ""
	@echo " $(GREEN)════════════════════════════════════════════════════════════════════════════════════$(NC)"
	@echo ""


#-------------------------------------------------------------------------------


#
# Install and configure Python virtual environment for local project development.
#
venv: FORCE
	@echo "\n$(GREEN)*** Installing Python virtual environment for local development ***$(NC)\n"
	@echo "Requested version: $(VENV_PYTHON)"
	@echo "Path to binary:    `which $(VENV_PYTHON)`"
	@echo "Path to venv:      $(VENV_PATH)"
	@echo ""
	@if [ -d $(VENV_PATH) ]; then\
		echo "$(CYAN)Virtual environment already exists in '$(VENV_PATH)'.$(NC)";\
	else\
		$(VENV_PYTHON) -m venv $(VENV_PATH);\
		echo "$(CYAN)Virtual environment successfully created in '$(VENV_PATH)'.$(NC)";\
	fi
	@echo ""
	@echo "Upgrading 'pip' and 'wheel' within the virtual environment to latest versions"
	@echo ""
	@$(VENV_PATH)/bin/pip install --upgrade pip
	@$(VENV_PATH)/bin/pip install --upgrade wheel
	@echo ""
	@echo "Venv path: `. $(VENV_PATH)/bin/activate && python -c 'import sys; print(sys.prefix)'`"
	@echo "Python stuff versions:"
	@echo ""
	@$(VENV_PATH)/bin/python --version
	@$(VENV_PATH)/bin/pip --version
	@echo ""
	@ls -al $(VENV_PATH)/bin | grep python
	@ls -al $(VENV_PATH)/bin | grep pip

	@echo "\n$(CYAN)Your development environment is ready in `. $(VENV_PATH)/bin/activate && python -c 'import sys; print(sys.prefix)'`.$(NC)\n"
	@echo "Please activate it manually with following command:\n"
	@echo "\t$(ORANGE). $(VENV_PATH)/bin/activate$(NC)\n"
	@echo "Consider adding following alias to your ~/.bashrc file for easier environment activation:\n"
	@echo "\t$(ORANGE)alias entervenv='. venv/bin/activate'$(NC)\n"
	@echo "$(BOLD)!!! Please keep in mind, that all makefile targets except this one ('develop') leave it up to you to activate the correct virtual environment !!!$(NC)"
	@echo ""

#
# Install and configure project locally for development. This target will perform
# following tasks for you:
#   - check for development prerequisites
#   - create lightweight chroot directory structure
#   - install all Python requirements (conf/requirements.pip)
#   - install all Python development requirements (conf/requirements-dev.pip)
#   - install web interface libraries
#   - compile translations
#   - install Negistry whois database stub
#   - download IP geolocation databases
#   - install the project in editable mode
#
develop: deps install-whl-dev build-webui

deps: deps-prerequisites deps-lwchroot deps-python deps-python-dev deps-editable deps-webui deps-geoip deps-negistry deps-postgresql translations-compile

clean: clean-pycs clean-build-docs clean-build-python clean-build-debian

docs: docs-sync docs-sphinx

check: pyflakes pylint test

build-whl: clean build-webui build-package-whl

build-deb: clean build-package-deb

install-whl: FORCE
	@echo "\n${GREEN}*** Performing local installation of Python packages ***${NC}\n"
	@$(PIP) install dist/mentat-ng*.whl --upgrade --force-reinstall

install-whl-dev: FORCE
	@echo "\n${GREEN}*** Installing project locally for development in editable mode***${NC}\n"
	@$(PIP) install -e .

release-whl: FORCE
	@echo "\n${GREEN}*** Deploying packages to PyPI ***${NC}\n"
	@$(TWINE) upload dist/* --skip-existing


#===============================================================================


deps-build: deps-prerequisites deps-lwchroot deps-python deps-python-dev deps-editable deps-webui translations-compile
deps-build-whl: deps-build
deps-build-deb: deps-build


#
# Check for development prerequisites. The prerequisites are certain commands and
# applications that have to be already installed on local system, otherwise the
# installation can not proceed further. These prerequisites ussually require more
# complex installation process, or their installation is not straightforward, or
# there are multiple installation procedures and it is not possible to choose the
# best option. In any case, it is best to leave the installation to the user.
#
deps-prerequisites: FORCE
	@echo "\n$(GREEN)*** Checking for development prerequisites ***$(NC)\n"
	@for prereq in $(PYTHON) $(PIP) yarn grunt psql geoipupdate ; do \
		if command -v $$prereq >/dev/null 2>&1; then \
			echo "Prerequisite: $$prereq (`$$prereq --version 2>&1 | tr '\n' ',' | sed -e s/,$$//g;`)"; \
		else \
			echo "$(RED)PREREQUISITE: $$prereq (missing).$(NC)\n"; \
			echo "You have to install this prerequisite manually.\n"; \
			exit 1; \
		fi \
	done
	@echo ""

#
# Install project`s lightweight chroot.
#
deps-lwchroot: FORCE
	@echo "\n$(GREEN)*** Creating local lightweight chroot subdirectory structure ***$(NC)\n"
	@./scripts/lwchroot-init.sh

#
# Install project`s Python dependencies using pip requirements file. The dependencies
# are already listed in setup.py file and pip can install them automatically. It
# is however better to use requirements file directly, because its syntax enables
# users to provide addditonal options to pip binary and thus enable for example
# an installation of binary packages. It is much more powerfull than simple syntax
# of 'install_requires' keyword of 'setup.py'.
#
deps-python: FORCE
	@echo "\n$(GREEN)*** Installing Python dependencies ***$(NC)\n"
	@$(PIP) --version
	@$(PIP) install -r conf/requirements.pip
	@echo ""

#
# Install project`s Python development dependencies using pip requirements file.
# These dependencies are essential for development, but not required for production
# deployment. For more information on why to use pip requirements file explicitly
# instead of letting it install the dependencies from the list in 'setup.py' file
# please see the documentation of 'deps-python' target above.
#
deps-python-dev: FORCE
	@echo "\n$(GREEN)*** Installing Python development dependencies ***$(NC)\n"
	@$(PIP) --version
	@$(PIP) install -r conf/requirements-dev.pip
	@echo ""

#
# Install project in editable mode.
#
deps-editable: FORCE
	@echo "\n$(GREEN)*** Installing project in editable mode ***$(NC)\n"
	@$(PIP) install -e ".[dev]"

#
# Upgrade project`s Python dependencies using pip requirements file to latest
# versions.
#
deps-python-upgrade: FORCE
	@echo "\n$(GREEN)*** Upgrading Python dependencies to latest versions ***$(NC)\n"
	@$(PIP) --version
	@$(PIP) install -r conf/requirements-latest.pip --upgrade
	@echo ""

#
# Upgrade project`s Python development dependencies using pip requirements file
# to latest versions.
#
deps-python-upgrade-dev: FORCE
	@echo "\n$(GREEN)*** Upgrading Python development dependencies to latest versions ***$(NC)\n"
	@$(PIP) --version
	@$(PIP) install -r conf/requirements-latest-dev.pip --upgrade
	@echo ""

#
# Install project`s web interface dependencies using yarn.
#
deps-webui: FORCE
	@echo "\n$(GREEN)*** Installing web interface dependencies ***$(NC)\n"
	@yarn install
	@echo ""

#
# Upgrade project`s web interface dependencies using yarn to latest versions.
#
deps-webui-upgrade: FORCE
	@echo "\n$(GREEN)*** Upgrading web interface dependencies ***$(NC)\n"
	@yarn upgrade
	@echo ""

#
# Fetch and install IP geolocation databases.
#
deps-geoip: FORCE
	@echo "\n$(GREEN)*** Installing IP geolocation databases ***$(NC)\n"
	@mkdir -p ./chroot/usr/share/GeoIP
	@geoipupdate --verbose --database-directory $(shell realpath ./chroot/usr/share/GeoIP)
	@echo ""

#
# Fetch and install Negistry whois database.
#
deps-negistry: FORCE
	@echo "\n$(GREEN)*** Installing Negistry whois database ***$(NC)\n"
	@./scripts/fetch-negistry.sh --stub --target=$(shell realpath ./chroot/var/mentat/whois-negistry.json)
	@echo ""

#
# Create and configure required PostgreSQL user accounts and databases.
#
deps-postgresql: FORCE
	@echo "\n$(GREEN)*** Installing and configuring PostgreSQL database ***$(NC)\n"
	@./scripts/sqldb-init.sh
	@echo ""


#-------------------------------------------------------------------------------


ctrl-mentat-dev:
	#APP_ROOT_PATH=$(shell realpath ./chroot) mentat-controller.py --command $(COMMAND)
	mentat-controller.py --command $(COMMAND)

run-mentat-dev:
	@echo "\n$(GREEN)*** Running development version of Mentat system ***$(NC)\n"
	#APP_ROOT_PATH=$(shell realpath ./chroot) mentat-controller.py --command start
	mentat-controller.py --command start

run-webui-dev:
	@echo "\n$(GREEN)*** Running development web server with development configuration on $(DEV_SERVER):$(DEV_PORT) ***$(NC)\n"
	#APP_ROOT_PATH=$(shell realpath ./chroot) hawat-cli run --host $(DEV_SERVER) --port $(DEV_PORT)
	hawat-cli run --host $(DEV_SERVER) --port $(DEV_PORT)

run-mailserver-dev:
	@echo "\n$(GREEN)*** Running development mail server on $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT) ***$(NC)\n"
	$(PYTHON) -m smtpd -n -c DebuggingServer $(DEV_MAIL_SERVER):$(DEV_MAIL_PORT)


#-------------------------------------------------------------------------------


clean-pycs: FORCE
	@echo "\n$(GREEN)*** Cleaning up Python precompiled files ***$(NC)\n"
	@find . -name '*.pyc' -delete
	@find . -name '*.pyo' -delete
	@find . -name '*~' -delete
	@echo ""

clean-build-docs: FORCE
	@echo "\n$(GREEN)*** Cleaning up documentation build directories ***$(NC)\n"
	@cd $(DIR_DOC)/sphinx && make clean
	@echo ""

clean-build-python: FORCE
	@echo "\n$(GREEN)*** Cleaning up Python build directories ***$(NC)\n"
	@rm --force --recursive build/
	@rm --force --recursive dist/
	@rm --force --recursive *.egg-info
	@echo ""

clean-build-debian: FORCE
	@echo "\n$(GREEN)*** Cleaning up Debian build directories ***$(NC)\n"
	@rm -rf ./debdist
	@rm -rf ./packaging/debian/mentat-ng
	@rm -f ./packaging/debian/mentat-ng.debhelper.log
	@rm -f ./packaging/debian/mentat-ng.substvars
	@echo ""


#-------------------------------------------------------------------------------


docs-sync: FORCE
	@echo "\n$(GREEN)*** Synchronizing documentation source code from submodules ***$(NC)\n"
	@cd ./submodules/pynspect/ && make docs
	@cd ./submodules/pyzenkit/ && make docs
	@rsync -r --progress --archive --update --delete --force ./submodules/pynspect/doc/_doclib/api_*.rst ./doc/sphinx/_doclib/apidoc/
	@rsync -r --progress --archive --update --delete --force ./submodules/pyzenkit/doc/_doclib/apidoc/pyzenkit.*.rst ./doc/sphinx/_doclib/apidoc/
	@rsync -r --progress --archive --update --delete --force ./submodules/pyzenkit/doc/_doclib/_inc*.rst ./doc/sphinx/_doclib/
	@echo ""

docs-sphinx: FORCE
	@echo "\n$(GREEN)*** Generating project API documentation ***$(NC)\n"
	@cd $(DIR_DOC)/sphinx && make apidoc
	@echo ""

	@echo "\n$(GREEN)*** Generating project documentation - HTML ***$(NC)\n"
	@cd $(DIR_DOC)/sphinx && make html
	@echo ""

docs-view: FORCE
	@echo "\n$(GREEN)*** Displaying project documentation ***$(NC)\n"
	@x-www-browser $(DIR_DOC)/sphinx/_build/html/manual.html

presentations: FORCE
	@echo "\n$(GREEN)*** Generating project presentations ***$(NC)\n"
	@for presdir in $(DIR_DOC)/presentations/*; do \
		if [ -d $$presdir ]; then \
			echo "────────────────────────────────────────────────────────────────────────────────"; \
			echo " $$presdir"; \
			echo "────────────────────────────────────────────────────────────────────────────────"; \
			cd $$presdir; \
			make; \
			cd $(CURRENT_DIR); \
			echo; \
		fi; \
	done


#-------------------------------------------------------------------------------


#
# This patch solves following issue: https://github.com/python-babel/flask-babel/issues/43
# Apply when necessary.
#
pybabel-patch: FORCE
	@echo "\n$(GREEN)*** Patching babel library ***$(NC)\n"
	@cp util/babel.messages.frontend.py.patch /var/tmp/
	@cd / && patch -p0 -i /var/tmp/babel.messages.frontend.py.patch

cpybabel-init: FORCE
	@echo "\n$(GREEN)*** Initializing translations for new locale for event_classes ***$(NC)\n"
	@echo "Locale name: $(INIT_LOCALE)"
	@for class in $(DIR_EVENT_CLASSES)/*/; do \
		$(PYBABEL) extract -F $(DIR_EVENT_CLASSES)/babel.cfg -o ${class}messages.pot -k lazy_gettext -k tr_ --no-location $${class}; \
		$(PYBABEL) init -i $${class}messages.pot -d $${class}translations -l $(INIT_LOCALE); \
	done
cpybabel-update: FORCE
	@echo "\n$(GREEN)*** Updating translations for event_classes ***$(NC)\n"
	@for class in $(DIR_EVENT_CLASSES)/*/; do \
		$(PYBABEL) extract -F $(DIR_EVENT_CLASSES)/babel.cfg -o $${class}messages.pot --no-location $${class}; \
		$(PYBABEL) update -i $${class}messages.pot -d $${class}translations; \
	done

cpybabel-compile: FORCE
	@echo "\n$(GREEN)*** Compiling translations for event_classes ***$(NC)\n"
	@for class in $(DIR_EVENT_CLASSES)/*/; do \
		$(PYBABEL) compile -d $${class}translations; \
	done

#\
# Alternative solution that uses the hawat-cli utility:
#   APP_ROOT_PATH=$(shell realpath ./chroot) hawat-cli intl init $(INIT_LOCALE)
#
hpybabel-init: cpybabel-init
	@echo "\n$(GREEN)*** Initializing translations for new locale for Hawat user interface ***$(NC)\n"
	@echo "Locale name: $(INIT_LOCALE)"
	@$(PYBABEL) extract -F $(DIR_LIB_HAWAT)/babel.cfg -o $(DIR_LIB_HAWAT)/messages.pot -k lazy_gettext -k tr_ $(DIR_LIB)
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_REPORTER)/babel.cfg -o $(DIR_TEMPLATES_REPORTER)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) init -i $(DIR_LIB_HAWAT)/messages.pot -d $(DIR_LIB_HAWAT)/translations -l $(INIT_LOCALE)
	@$(PYBABEL) init -i $(DIR_TEMPLATES_REPORTER)/messages.pot -d $(DIR_TEMPLATES_REPORTER)/translations -l $(INIT_LOCALE)

#
# Alternative solution that uses the hawat-cli utility:
#   APP_ROOT_PATH=$(shell realpath ./chroot) hawat-cli intl update
#
hpybabel-update: cpybabel-update
	@echo "\n$(GREEN)*** Updating translations for Hawat user interface ***$(NC)\n"
	@$(PYBABEL) extract -F $(DIR_LIB_HAWAT)/babel.cfg -o $(DIR_LIB_HAWAT)/messages.pot -k lazy_gettext -k tr_ $(DIR_LIB)
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_REPORTER)/babel.cfg -o $(DIR_TEMPLATES_REPORTER)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) update -i $(DIR_LIB_HAWAT)/messages.pot -d $(DIR_LIB_HAWAT)/translations
	@$(PYBABEL) update -i $(DIR_TEMPLATES_REPORTER)/messages.pot -d $(DIR_TEMPLATES_REPORTER)/translations -l cs

#
# Alternative solution that uses the hawat-cli utility:
#   APP_ROOT_PATH=$(shell realpath ./chroot) hawat-cli intl compile
#
hpybabel-compile: cpybabel-compile
	@echo "\n$(GREEN)*** Compiling translations for Hawat user interface ***$(NC)\n"
	@$(PYBABEL) compile -d $(DIR_LIB_HAWAT)/translations
	@$(PYBABEL) compile -d $(DIR_TEMPLATES_REPORTER)/translations


mpybabel-init: cpybabel-init
	@echo "\n$(GREEN)*** Initializing translations for new locale for Mentat ***$(NC)\n"
	@echo "Locale name: $(INIT_LOCALE)"
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_INFORMANT)/babel.cfg -o $(DIR_TEMPLATES_INFORMANT)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_REPORTER)/babel.cfg -o $(DIR_TEMPLATES_REPORTER)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_UTEST)/babel.cfg -o $(DIR_TEMPLATES_UTEST)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) init -i $(DIR_TEMPLATES_INFORMANT)/messages.pot -d $(DIR_TEMPLATES_INFORMANT)/translations -l $(INIT_LOCALE)
	@$(PYBABEL) init -i $(DIR_TEMPLATES_REPORTER)/messages.pot -d $(DIR_TEMPLATES_REPORTER)/translations -l $(INIT_LOCALE)
	@$(PYBABEL) init -i $(DIR_TEMPLATES_UTEST)/messages.pot -d $(DIR_TEMPLATES_UTEST)/translations -l $(INIT_LOCALE)

mpybabel-update: cpybabel-update
	@echo "\n$(GREEN)*** Updating translations for Mentat ***$(NC)\n"
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_INFORMANT)/babel.cfg -o $(DIR_TEMPLATES_INFORMANT)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_REPORTER)/babel.cfg -o $(DIR_TEMPLATES_REPORTER)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) extract -F $(DIR_TEMPLATES_UTEST)/babel.cfg -o $(DIR_TEMPLATES_UTEST)/messages.pot -k lazy_gettext -k tr_ --no-location .
	@$(PYBABEL) update -i $(DIR_TEMPLATES_INFORMANT)/messages.pot -d $(DIR_TEMPLATES_INFORMANT)/translations
	@$(PYBABEL) update -i $(DIR_TEMPLATES_REPORTER)/messages.pot -d $(DIR_TEMPLATES_REPORTER)/translations
	@$(PYBABEL) update -i $(DIR_TEMPLATES_UTEST)/messages.pot -d $(DIR_TEMPLATES_UTEST)/translations

mpybabel-compile: cpybabel-compile
	@echo "\n$(GREEN)*** Compiling translations for Mentat ***$(NC)\n"
	@$(PYBABEL) compile -d $(DIR_TEMPLATES_INFORMANT)/translations --statistics
	@$(PYBABEL) compile -d $(DIR_TEMPLATES_REPORTER)/translations --statistics
	@$(PYBABEL) compile -d $(DIR_TEMPLATES_UTEST)/translations --statistics

#
# Compile all available translations.
#
translations-compile: hpybabel-compile mpybabel-compile


#-------------------------------------------------------------------------------


pyflakes: FORCE
	@echo "\n$(GREEN)*** Checking executables with pyflakes ***$(NC)\n"
	@echo "Python version: `$(PYTHON) --version`"
	@echo ""
	$(PYTHON) -m pyflakes $(DIR_BIN)

	@echo "\n$(GREEN)*** Checking library with pyflakes ***$(NC)\n"
	@echo "Python version: `$(PYTHON) --version`"
	@echo ""
	$(PYTHON) -m pyflakes $(DIR_LIB)

pylint: FORCE
	@echo "\n$(GREEN)*** Checking executables with pylint ***$(NC)\n"
	@echo "Python version: `$(PYTHON) --version`"
	@echo ""
	-PYTHONPATH=$(DIR_LIB) $(PYTHON) -m pylint --rcfile .pylintrc-bin $(DIR_BIN)

	@echo "\n$(GREEN)*** Checking library with pylint ***$(NC)\n"
	@echo "Python version: `$(PYTHON) --version`"
	@echo ""
	-PYTHONPATH=$(DIR_LIB) $(PYTHON) -m pylint --rcfile .pylintrc-lib $(DIR_LIB)

test:
	@echo "\n$(GREEN)*** Checking code with nosetests ***$(NC)\n"
	@echo "Python version: `$(PYTHON) --version`"
	APP_ROOT_PATH=$(shell realpath ./chroot) PYTHONPATH=$(DIR_LIB) $(NOSETESTS)

coverage:
	@echo "\n$(GREEN)*** Checking test code coverage with nosetests and coverage ***$(NC)\n"
	@echo "Python version: `$(PYTHON) --version`"
	APP_ROOT_PATH=$(shell realpath ./chroot) PYTHONPATH=$(DIR_LIB) $(COVERAGE) run -m nose


#-------------------------------------------------------------------------------


build-webui: FORCE
	@echo "\n${GREEN}*** Building web interface environment ***${NC}\n"
	grunt webui
	@echo ""

build-package-whl: FORCE
	@echo "\n${GREEN}*** Building Python packages ***${NC}\n"
	@echo "Python version: `$(PYTHON) --version`"
	@echo ""
	$(PYTHON) setup.py sdist bdist_wheel
	@echo ""

#
# Resources:
#	https://wiki.debian.org/BuildingTutorial
#	https://github.com/phusion/debian-packaging-for-the-modern-developer
#
build-package-deb: FORCE
	@echo "\n${GREEN}*** Building Debian packages ***${NC}\n"
	mkdir -p debdist
	cd packaging && fakeroot make -f debian/rules clean
	cd packaging && fakeroot make -f debian/rules build
	cd packaging && fakeroot make -f debian/rules binary BUILD_NUMBER=$(BUILD_NUMBER) BUILD_SUITE=$(BUILD_SUITE)
	@echo ""


# Empty rule as dependency will force make to always perform target
# Source: https://www.gnu.org/software/make/manual/html_node/Force-Targets.html
FORCE: