123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- # The following python-related tools and processes are supported:
- # * black
- # * coverage (requires ".coveragerc")
- # * flake8
- # * pypi upload (requires "~/.pypirc")
- # * tox / unittests (requires "tox.ini")
- #
- PYTHON_BIN ?= python3
- DIR_PYTHON_BUILD ?= $(DIR_BUILD)/python-lib
- PYTHON_BDIST_ARGS = --dist-dir $(DIR_BUILD)/python-packages
- PYTHON_BUILD_ARGS = --build-base "$(DIR_PYTHON_BUILD)"
- PYTHON_INSTALL_ARGS = --root "$(abspath $(DESTDIR))"
- DISABLE_PYTHON_TESTS ?= 0
- DISABLE_PYTHON_LINT_FLAKE8 ?= 0
- ENABLE_PYTHON_LINT_BLACK ?= 0
- PYPI_UPLOAD_TARGET = https://pypi.python.org/pypi
- DIR_PYTHON_COVERAGE_HTML = $(DIR_BUILD)/coverage-html
- # detect if flake8 is available as an executable (e.g. Arch) or as a python module (e.g. Debian)
- FLAKE8_BIN ?= $(shell hash flake8 2>/dev/null && echo "flake8" || echo "$(PYTHON_BIN) -m flake8")
- FLAKE8_FILES ?= $(DIR_PYTHON_SETUP)
- RUN_PYTHON = $(PYTHON_BIN)
- BLACK_BIN ?= black
- # projects may want to override this with something like "--target-version=py39"
- BLACK_ARGS ?=
- BLACK_FILES ?= $(DIR_PYTHON_SETUP)
- PYTHON_TOX_FILE ?= $(DIR_PYTHON_SETUP)/tox.ini
- PYTHON_TEST_POETRY_COMMAND ?= pytest
- PYTHON_BUILD_SYSTEM ?= $(shell \
- if grep -q "^build-backend.*hatch" "$(PYTHON_PYPROJECT_FILE)"; then echo "hatchling"; \
- elif grep -q "^build-backend.*poetry" "$(PYTHON_PYPROJECT_FILE)"; then echo "poetry"; \
- elif [ -e "$(PYTHON_SETUP_FILE)" ]; then echo "setuptools"; \
- fi)
- PYTHON_TEST_RUNNER ?= $(shell \
- if [ -e "$(PYTHON_TOX_FILE)" ]; then echo "tox"; \
- elif [ -e manage.py ]; then echo "django"; \
- elif [ "$(PYTHON_BUILD_SYSTEM)" = "hatchling" ]; then echo "hatch"; \
- elif [ "$(PYTHON_BUILD_SYSTEM)" = "poetry" ]; then echo "poetry"; \
- else echo "generic"; \
- fi)
- PYTHON_LINT_RUNNER ?= $(shell \
- if [ "$(PYTHON_BUILD_SYSTEM)" = "hatchling" ]; then echo "hatch"; \
- else echo "generic"; \
- fi)
- PYTHON_STYLE_RUNNER ?= $(shell \
- if [ "$(PYTHON_BUILD_SYSTEM)" = "hatchling" ]; then echo "hatch"; \
- else echo "generic"; \
- fi)
- .PHONY: help
- help: help-python
- .PHONY: help-python
- help-python:
- @echo "Python-specific packaging targets:"
- @echo " clean-python"
- @echo " dist-python"
- @echo " lint-python"
- @echo " report-python"
- @echo " style-python"
- @echo " test-python"
- @echo " upload-python"
- @echo
- .PHONY: dist
- dist: dist-python
- .PHONY: install
- install: install-python
- .PHONY: lint
- lint: lint-python
- .PHONY: style
- style: style-python
- ifneq ($(DISABLE_PYTHON_TESTS),1)
- .PHONY: test
- test: test-python
- endif
- .PHONY: install-python
- install-python:
- cd "$(DIR_PYTHON_SETUP)" && $(RUN_PYTHON) setup.py install $(PYTHON_INSTALL_ARGS)
- .PHONY: dist-python
- dist-python: clean-python
- cd "$(DIR_PYTHON_SETUP)" \
- && $(RUN_PYTHON) setup.py build $(PYTHON_BUILD_ARGS) bdist $(PYTHON_BDIST_ARGS)
- .PHONY: check-pypi-config
- check-pypi-config:
- @# verify that the section for our internal target is not missing
- @if grep -q "^\[$(PYPI_UPLOAD_TARGET)\]$$" ~/.pypirc; then true; else \
- echo "ERROR: missing '$(PYPI_UPLOAD_TARGET)' section in ~/.pypirc: "\
- "take a look at pypirc.sample" >&2; \
- exit 1; \
- fi
- .PHONY: upload
- upload: upload-python
- .PHONY: upload-python
- upload-python: check-pypi-config
- cd "$(DIR_PYTHON_SETUP)" && $(RUN_PYTHON) setup.py sdist upload -r "$(PYPI_UPLOAD_TARGET)"
- .PHONY: lint-python
- ifeq ($(PYTHON_LINT_RUNNER),hatch)
- lint-python: lint-python-hatch
- else ifeq ($(PYTHON_LINT_RUNNER),generic)
- ifeq ($(ENABLE_PYTHON_LINT_BLACK),1)
- lint-python: lint-python-black
- endif
- ifneq ($(DISABLE_PYTHON_LINT_FLAKE8),1)
- lint-python: lint-python-flake8
- endif
- endif
- .PHONY: lint-python-black
- lint-python-black:
- $(BLACK_BIN) --check $(BLACK_ARGS) $(BLACK_FILES)
- .PHONY: lint-python-flake8
- lint-python-flake8:
- $(FLAKE8_BIN) $(FLAKE8_FILES)
- .PHONY: lint-python-hatch
- lint-python-hatch:
- hatch run lint:all
- .PHONY: style-python
- ifeq ($(PYTHON_STYLE_RUNNER),hatch)
- style-python: style-python-hatch
- else ifeq ($(PYTHON_STYLE_RUNNER),generic)
- style-python: style-python-black
- endif
- .PHONY: style-python-black
- style-python-black:
- $(BLACK_BIN) $(BLACK_ARGS) $(BLACK_FILES)
- .PHONY: style-python-hatch
- style-python-hatch:
- hatch run lint:fmt
- .PHONY: test-python
- ifeq ($(PYTHON_TEST_RUNNER),tox)
- test-python: test-python-tox
- else ifeq ($(PYTHON_TEST_RUNNER),django)
- test-python: test-python-django
- else ifeq ($(PYTHON_TEST_RUNNER),hatch)
- test-python: test-python-hatch
- else ifeq ($(PYTHON_TEST_RUNNER),poetry)
- test-python: test-python-poetry
- else ifeq ($(PYTHON_TEST_RUNNER),generic)
- test-python: test-python-generic
- endif
- .PHONY: test-python-tox
- test-python-tox:
- tox
- .PHONY: test-python-django
- test-python-django:
- $(RUN_PYTHON) manage.py test
- .PHONY: test-python-hatch
- test-python-hatch:
- hatch run test
- .PHONY: test-python-poetry
- test-python-poetry:
- poetry run $(PYTHON_TEST_POETRY_COMMAND)
- .PHONY: test-python-generic
- test-python-generic:
- $(RUN_PYTHON) $(PYTHON_TEST_ARGS)
- .PHONY: report
- report: report-python
- .PHONY: report-python
- report-python:
- if [ -e .coveragerc ]; then $(MAKE) report-python-coverage; fi
- .PHONY: report-python-coverage
- report-python-coverage:
- @# run tests for coverage analysis
- $(RUN_PYTHON) -m coverage run $(PYTHON_TEST_ARGS)
- @# provide textual report
- $(RUN_PYTHON) -m coverage report
- $(RUN_PYTHON) -m coverage html --directory "$(DIR_PYTHON_COVERAGE_HTML)"
- @printf "Browse the coverage report:\n\tfile://%s/index.html\n" \
- "$(abspath $(DIR_PYTHON_COVERAGE_HTML))"
- @# run a visual browser if the DISPLAY variable is set
- @if [ -n "$$DISPLAY" ] && [ -n "$(COVERAGE_BROWSER_BIN)" ]; then \
- "$(COVERAGE_BROWSER_BIN)" "$(DIR_PYTHON_COVERAGE_HTML)/index.html"; fi
- .PHONY: clean-python
- clean-python:
- cd "$(DIR_PYTHON_SETUP)" && python3 setup.py clean || true
- @# datafile for python3-coverage
- $(RM) .coverage
- @# workaround for https://github.com/pypa/setuptools/issues/436
- $(RM) "$(DIR_PYTHON_SETUP)"/*.egg-info/SOURCES.txt
- clean: clean-python
|