Created
August 16, 2017 13:22
-
-
Save brutus/2dfd02917a939577a8dd561fb091e872 to your computer and use it in GitHub Desktop.
Makefile for Python projects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Python Project | |
# | |
# Some targets to lint your code, run tests, builds and do some cleanup. | |
# Works fine with tox and Travis, etc. | |
# | |
# This setup assumes that you take care of the virtual environment setup | |
# yourself and that the needed requirements are installed. And also that | |
# you configure your tools. So edit your own `setup.cfg` or `.tox.ini` | |
# with the settings needed for the tools. | |
# | |
# # TOOLS | |
# | |
# - isort | |
# - pylama | |
# - pyflakes | |
# - pycodestyle | |
# - pydocstyle | |
# - mccabe | |
# - pylint | |
# - pylint (optional) | |
# - coverage | |
# | |
# # SETUP | |
# | |
# You should set _SOURCE_ to the path that contains your source (a relative | |
# path from this file is fine). All checks and stuff will be run from the | |
# directory containing this file, but the path given is used as base for the | |
# commands. | |
# | |
# If you have multiple directories, that should be checked, thats fine. You | |
# can set _SOURCE_ to a list of space separated paths instead. | |
# | |
# NOTE: Take care though if you set `.` as a directory: Your virtual | |
# environment, the tox directory, you tests, etc. might also be affected, if | |
# they are in this directory, which is probably not what you want. | |
# | |
# Also, if you set _DJANGO_ to `1`, the tests will be run by the | |
# `django-admin test` command instead of the default unittest discovery. | |
# | |
# And lastly, the commands are printed by choice, so you can see whats | |
# happening. To disable this, perpend `@` to the commands in the | |
# targets. | |
# | |
# TARGETS | |
# | |
# ## CHECKS and TESTS: | |
# - __style__ (default): checks syntax and code conventions. | |
# - __tests__: runs doctest from Python files and all unittests discovered. | |
# - __check__: runs both (_style_ & _tests_). | |
# - __lint__: checks for opinionated code smells (_mccabe_ & _pylama_). | |
# - __full__: runs all three (_style_, _lint_ and _tests_). | |
# | |
# ## TOOLS: | |
# - __cover__: runs the unittests and prints a coverage report. | |
# - __pylint__: prints a _very_ opinionated code smell report. | |
# - __isort__: sorts all imports (this might change your Python files). | |
# | |
# ## BUILD: | |
# - __build__: builds a source distribution and a wheel (needs `setup.py`). | |
# - __upload__: uploads builds to PyPi (needs `.pypirc`). | |
# _ __clean__: removes temporary files and caches. | |
# | |
# ## PIP | |
# _ __outdated__: lists outdated packages. | |
# _ __update__: updates outdated packages. | |
# --- SETTINGS ------------------------------------------------------------- | |
# Set this to the directory, where your code is. If you have multiple | |
# directories, you want to check, use a space separated list instead. | |
SOURCE = . | |
# Set this to the string used for the `--source` argument to coverage. | |
COVARAGE_SOURCES = . | |
# Should the Django test runner be used instead of unittest discovery? If | |
# so, set this to `1` instead of `0`. This is needed to run the tests for | |
# Django projects. | |
DJANGO = 0 | |
# --- COMMANDS ------------------------------------------------------------- | |
# The commands that are run by the targets… feel free to change (them). | |
PWD = $(shell pwd) | |
CFG = $(PWD)/setup.cfg | |
EXCLUDES = \( \ | |
-path './.git/*' -o \ | |
-path './.venv/*' -o \ | |
-path './venv/*' -o \ | |
-path './env/*' -o \ | |
-path './.tox/*' -o \ | |
-path '.*/node_modules/*' -o \ | |
-path '.*/bower_components/*' \ | |
\) -prune -o | |
# Isort | |
CMD_ISORT = isort --settings-path $(CFG) --apply | |
CMD_ISORT_CHECK = isort --settings-path $(CFG) --check-only --quiet | |
# Linters | |
CMD_PYLAMA_ISORT_CHECK = pylama --options $(CFG) -l isort | |
CMD_PYLAMA_SYNTAX_CHECK = pylama --options $(CFG) -l pyflakes | |
CMD_PYLAMA_STYLE_CHECK_CODE = pylama --options $(CFG) -l pycodestyle | |
CMD_PYLAMA_STYLE_CHECK_DOCS = pylama --options $(CFG) -l pydocstyle | |
CMD_PYLAMA_COMPLEXITY_CHECK = pylama --options $(CFG) -l mccabe | |
CMD_PYLAMA_PYLINT_CHECK = pylama --options $(CFG) -l pylint | |
CMD_PYLINT_CHECK = find . $(EXCLUDES) -name '*.py' -print0 | xargs -0 \ | |
pylint --rcfile $(PWD)/.pylintrc | |
CMD_PYLINT_REPORT = $(CMD_PYLINT_CHECK) -ry | |
# Test Runners | |
CMD_DOCTEST = find $(dir) $(EXCLUDES) -name '*.py' -print0 | xargs -0 \ | |
python -m doctest | |
ifeq ($(DJANGO), 1) | |
CMD_COVERAGE_TEST = -m django test | |
CMD_TEST = python $(CMD_COVERAGE_TEST) | |
else | |
CMD_COVERAGE_TEST = -m unittest discover | |
CMD_TEST = python $(CMD_COVERAGE_TEST) | |
endif | |
CMD_COVERAGE_RUN = coverage run --append --source $(COVARAGE_SOURCES) $(CMD_COVERAGE_TEST) | |
# Build Package | |
CMD_BUILD = python setup.py sdist bdist_wheel | |
CMD_UPLOAD = twine upload --skip-existing dist/* | |
# Pip | |
CMD_PIP_OUTDATED = pip list --outdated --format=columns | |
CMD_PIP_UPDATE = $(CMD_PIP_OUTDATED) | tail -n +3 | cut -d' ' -f1 | \ | |
xargs -r pip install --upgrade | |
# --- TARGETS -------------------------------------------------------------- | |
.PHONY: default style_check style tests check lint full isort isort_check syntax_check style_check_code style_check_docs code_check pylama pylint doctests unittests cover build upload clean outdated update | |
default: style | |
style_check: style_check_code style_check_docs | |
style: syntax_check isort_check style_check | |
tests: doctests unittests | |
check: style tests | |
lint: complexity_check pylama | |
full: check lint | |
build: mk_build clean | |
isort: | |
# Sort imports in all `*.py` files. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_ISORT)) | |
isort_check: | |
# Checks for correctly sorted imports in all `*.py` files. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_PYLAMA_ISORT_CHECK)) | |
syntax_check: | |
# Checks source files for syntax errors. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_PYLAMA_SYNTAX_CHECK)) | |
style_check_code: | |
# Checks source files for common code style conventions. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_PYLAMA_STYLE_CHECK_CODE)) | |
style_check_docs: | |
# Checks source files for common documentation style conventions. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_PYLAMA_STYLE_CHECK_DOCS)) | |
complexity_check: | |
# Checks source files for too much complexity. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_PYLAMA_COMPLEXITY_CHECK)) | |
pylama: | |
# Checks the source files for opinionated code smells. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_PYLAMA_PYLINT_CHECK)) | |
pylint: | |
# Prints a report of _very_ opinionated code smells in the source files. | |
$(foreach dir,$(SOURCE),cd $(dir); $(CMD_PYLINT_REPORT)) | |
doctests: | |
# Runs doctest found in the source files. | |
$(foreach dir,$(SOURCE),$(CMD_DOCTEST)) | |
unittests: | |
# Runs all unittests that follow common naming schemes. | |
$(CMD_TEST) | |
cover: | |
# Runs all those unittests with coverage and prints a report. | |
$(CMD_COVERAGE_RUN) | |
coverage report -m | |
mk_build: | |
# Builds a Python distribution (source distribution and wheel). | |
$(CMD_BUILD) | |
upload: | |
# Uploads builds to PyPi. | |
$(CMD_UPLOAD) | |
clean: | |
# Removes caches and bytecode files. | |
find . $(EXCLUDES) -print0 | xargs -0 -r rm -r | |
outdated: | |
# Lists outdated packages. | |
$(CMD_PIP_OUTDATED) | |
update: | |
# Updates outdated packages. | |
$(CMD_PIP_UPDATE) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment