PYTHON_MODULES := {{python-pkg-name}}
PYTHONPATH := .
VENV := .venv
PYTEST := env PYTHONPATH=$(PYTHONPATH) PYTEST=1 $(VENV)/bin/py.test
PYLINT := env PYTHONPATH=$(PYTHONPATH) $(VENV)/bin/pylint --disable=I0011 --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}"
PEP8 := env PYTHONPATH=$(PYTHONPATH) $(VENV)/bin/pycodestyle --repeat --ignore=E202,E501,E402,W503,W504,E122,E129
PYTHON := env PYTHONPATH=$(PYTHONPATH) $(VENV)/bin/python
PIP := $(VENV)/bin/pip
# required system packages when installing python dependencies
#DEV_PKGS := python3-dev libpq-dev

DEFAULT_PYTHON ?= $(shell ./utils/choose_default_python.sh)
VIRTUALENV := $(wildcard ./utils/virtualenv-*/virtualenv.py)

REQUIREMENTS := -r requirements.txt
REQUIREMENTS_DEV := -r requirements-dev.txt

VERSION := $(shell grep '__version__' {{python-pkg-name}}/__init__.py |cut -d'"' -f 2)
# docker hub user name or private registry URL with username. do not end with /.
DOCKER_IMAGE_PREFIX ?= de02-reg.emacsos.com/sylecn
KUBECTL_CA_PATH ?= /etc/kubernetes/pki/ca.crt

BUILD_DOCKER_IMAGE := $(DOCKER_IMAGE_PREFIX)/python-build-image:1.2.1-stretch

default: check-coding-style
dist: bootstrap
	rm -rf dist/*
	$(PYTHON) setup.py -q sdist
	$(PYTHON) setup.py -q bdist_wheel --universal
upload: dist
	test -e $(VENV)/bin/twine || $(PIP) install -q twine
	$(VENV)/bin/twine check dist/*.whl
	$(VENV)/bin/twine check dist/*.tar.gz
	@if ! [ -n "$(TWINE_USERNAME)" -o -e ~/.pypirc ]; then \
		echo "You may want to save pypi user/password in env var or ~/.pypirc file."; \
	fi
	$(VENV)/bin/twine upload dist/*
build:

version:
	@echo $(VERSION)
debug:
	env DEBUG=1 $(PYTHON) {{python-pkg-name}}/main.py
run:
	$(PYTHON) {{python-pkg-name}}/main.py
uwsgi:
	$(VENV)/bin/uwsgi --processes=2 --threads=4 --wsgi-file={{python-pkg-name}}/main.py --env=PYTHONPATH=. --http=localhost:8082 --disable-logging
shell:
	$(PYTHON) -i

venv:
	test -d $(VENV) || $(DEFAULT_PYTHON) $(VIRTUALENV) --no-download -q $(VENV)
requirements:
	@if [ -d wheelhouse ]; then \
		$(PIP) install -q --isolated --no-index --find-links=wheelhouse $(REQUIREMENTS); \
	else \
		$(PIP) install -q $(REQUIREMENTS); \
	fi
requirements-dev:
	./utils/ensure_pkg_installed $(DEV_PKGS)
	$(PIP) install -q $(REQUIREMENTS_DEV)
logdir:
	@if [ ! -d /var/log/{{name}} ]; then \
		sudo mkdir /var/log/{{name}}; \
		sudo chown -R ${USER} /var/log/{{name}}; \
	fi
bootstrap: venv requirements
bootstrap-dev: venv requirements requirements-dev
install: bootstrap
	$(PIP) install -q --no-index .
uninstall: bootstrap
	$(PIP) uninstall -q -y {{python-pkg-name}}
docker: deb
	docker build -t $(DOCKER_IMAGE_PREFIX)/{{name}}:$(VERSION) .
	@echo "You may push it with: docker push $(DOCKER_IMAGE_PREFIX)/{{name}}:$(VERSION)"
deb:
	utils/build-deb
pipfreeze:
	$(PIP) freeze
wheel: bootstrap-dev
	@echo "building wheelhouse..."
	$(PIP) install wheel
	$(PIP) wheel -w wheelhouse $(REQUIREMENTS)

check: just-test
sanity-check: bootstrap
	$(PYTHON) {{python-pkg-name}}/sanity_check.py
check-coding-style: bootstrap-dev
	$(PEP8) $(PYTHON_MODULES)
	$(PYLINT) -E $(PYTHON_MODULES)
	$(PYTHON) {{python-pkg-name}}/config.py
pylint-full: check-coding-style
	$(PYLINT) $(PYTHON_MODULES)
test: check-coding-style
	$(PYTEST) $(PYTHON_MODULES)
just-test:
	$(PYTEST) $(PYTHON_MODULES)

# run test, build deb in python build image container, then create docker
# image and push image on host.
ci-build:
	echo '$(value DOCKER_PASSWORD)' | docker login -u $(DOCKER_USER) --password-stdin $(BUILD_DOCKER_IMAGE)
	mkdir -p .cache
	docker run --rm --name {{ name }}-test -v "$(CURDIR)":/app -v "$(CURDIR)/.cache":/.cache -u $(shell id -u):$(shell id -g) $(BUILD_DOCKER_IMAGE) make test deb -C /app
	docker build -t $(DOCKER_IMAGE_PREFIX)/{{ name }}:$(VERSION) .
	docker push $(DOCKER_IMAGE_PREFIX)/{{ name }}:$(VERSION)
deploy:
	sed "s/IMAGE_TAG/$(VERSION)/" app.yaml > $(VERSION).yaml
	kubectl --certificate-authority='$(KUBECTL_CA_PATH)' -s $(KUBECTL_API) --token=$(KUBECTL_TOKEN) apply -f $(VERSION).yaml

test-prod: requirements-dev test

clean:
	find . -name "__pycache__" -type d -exec rm -rf {} \; || true
	find . -name "*.pyc" -type f -exec rm -rf {} \; || true
full-clean:
	rm -rf $(VENV) build/ dist/ wheelhouse/ {{python-pkg-name}}.egg-info/ distribute-*.tar.gz
	find . -name "__pycache__" -type d -exec rm -rf {} \; || true
	find . -name "*.pyc" -type f -exec rm -rf {} \; || true
todo:
	@rgrep -I -n --exclude=Makefile --exclude=TAGS --exclude-dir=$(VENV) -E '(TODO|FIXME|XXX|not_implemented)' $(PYTHON_MODULES)
TAGS:
	etags -R --exclude=static $(PYTHON_MODULES)
update-git-hooks: install-git-hooks-force
install-git-hooks:
	./utils/install-git-hooks
install-git-hooks-force:
	./utils/install-git-hooks -f
loc:
	find . -regex '.*\.pyw?$$' -exec wc -l {} \+ | tail -n 1
	which cloc >/dev/null && cloc {{python-pkg-name}}/
.PHONY: default build debug run uwsgi shell venv bootstrap bootstrap-dev install uninstall deb pipfreeze wheel check check-coding-style pylint-full test just-test test-prod clean full-clean todo TAGS update-git-hooks install-git-hooks install-git-hooks-force loc
