1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
SHELL := bash
.SHELLFLAGS := -eux -o pipefail -c
.DEFAULT_GOAL := build
.DELETE_ON_ERROR: # If a recipe to build a file exits with an error, delete the file.
.SUFFIXES: # Remove the default suffixes which are for compiling C projects.
.NOTPARALLEL: # Disable use of parallel subprocesses.
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
export COLUMNS ?= 70
seperator ?= $(shell printf %${COLUMNS}s | tr " " "═")
platform := $(shell python -c 'import sys; print(sys.platform)')
PYTHON_VERSION ?= 3
export PIP_DISABLE_PIP_VERSION_CHECK=1
pip-install := ve/bin/pip --no-input install --constraint constraints.txt
pip-check := ve/bin/pip show -q
source_code := src
isort := ve/bin/isort --multi-line=VERTICAL_HANGING_INDENT --trailing-comma --no-sections
########################################################################################
# Build targets
#
# It is acceptable for other targets to implicitly depend on these targets having been
# run. I.e., it is ok if "make lint" generates an error before "make" has been run.
.PHONY: build
build: ve development-utilities
ve:
python$(PYTHON_VERSION) -m venv ve
ve/bin/genbadge:
$(pip-install) genbadge[coverage]
ve/bin/%:
# Install development utility "$*"
$(pip-install) $*
# Utilities we use during development.
.PHONY: development-utilities
development-utilities: ve/bin/black
development-utilities: ve/bin/coverage
development-utilities: ve/bin/flake8
development-utilities: ve/bin/genbadge
development-utilities: ve/bin/isort
development-utilities: ve/bin/mypy
development-utilities: ve/bin/pydocstyle
development-utilities: ve/bin/pyinstaller
development-utilities: ve/bin/pylint
development-utilities: ve/bin/twine
development-utilities: ve/bin/wheel
########################################################################################
# Distribution targets
.PHONY: assert-one-dist
assert-one-dist:
@if [ $$(find dist -name 'manuel-*.tar.gz' | wc -l) != 1 ]; then \
echo There must be one and only one distribution file present.; \
exit 1; \
fi
.PHONY: assert-no-unreleased-changes
assert-no-unreleased-changes:
@if grep unreleased CHANGES.rst > /dev/null; then \
echo There must not be any unreleased changes in CHANGES.rst.; \
exit 1; \
fi
.PHONY: assert-version-in-changelog
assert-version-in-changelog:
@if ! grep $$(ve/bin/python setup.py --version) CHANGES.rst; then \
echo The current version number must be mentioned in CHANGES.rst.; \
exit 1; \
fi
.PHONY: assert-matching-versions
assert-matching-versions:
# verify that the top-most version in the change log matches what is in setup.py
@env \
CHANGE_LOG_VERSION=$$(grep '^[^ ]\+ (20\d\d-\d\d-\d\d)' CHANGES.rst | head -n 1 | cut -d' ' -f1) \
SETUP_VERSION=$$(ve/bin/python setup.py --version) \
bash -c 'test $$CHANGE_LOG_VERSION = $$SETUP_VERSION'
.PHONY: assert-no-changes
assert-no-changes:
@if ! output=$$(git status --porcelain) || [ -n "$$output" ]; then \
echo There must not be any ucomitted changes.; \
exit 1; \
fi
.PHONY: dist
dist:
ve/bin/python setup.py sdist
.PHONY: test-dist
test-dist:
# check to see if the distribution passes the tests
rm -rf tmp
mkdir tmp
tar xzvf $$(find dist -name 'manuel-*.tar.gz') -C tmp
cd tmp/manuel-* && make && make check
rm -rf tmp
.PHONY: upload
upload: assert-one-dist
ve/bin/twine upload --repository manuel $$(find dist -name 'manuel-*.tar.gz')
.PHONY: badges
badges:
ve/bin/python bin/genbadge coverage -i coverage.xml -o badges/coverage-badge.svg
.PHONY: release
ifeq '$(shell git rev-parse --abbrev-ref HEAD)' 'master'
release: clean-dist assert-no-unreleased-changes assert-matching-versions \
assert-version-in-changelog badges dist assert-one-dist test-dist \
assert-no-changes upload
# now that a release has happened, tag the current HEAD as that release
git tag $$(ve/bin/python setup.py --version)
git push origin
git push origin --tags
else
release:
@echo Error: must be on master branch to do a release.; exit 1
endif
########################################################################################
# Test and lint targets
.PHONY: pylint
pylint:
ve/bin/pylint $(source_code) --output-format=colorized
.PHONY: flake8
flake8:
ve/bin/flake8 $(source_code)
.PHONY: pydocstyle
pydocstyle:
ve/bin/pydocstyle $(source_code)
.PHONY: mypy
mypy:
ve/bin/mypy $(source_code) --strict
.PHONY: black-check
black-check:
ve/bin/black -S $(source_code) --check
.PHONY: isort-check
isort-check:
$(isort) $(source_code) --diff --check
.PHONY: lint
lint: black-check isort-check
.PHONY: test
test:
ve/bin/python setup.py test
.PHONY: coverage
coverage:
ve/bin/coverage run --branch setup.py test
ve/bin/coverage xml # the XML output file is used by the "badges" target
PYTHONWARNINGS=ignore ve/bin/coverage report --ignore-errors --fail-under=97 --show-missing --skip-empty
.PHONY: check
check: test lint coverage
########################################################################################
# Sorce code formatting targets
.PHONY: black
black:
ve/bin/black -S $(source_code)
.PHONY: isort
isort:
$(isort) $(source_code)
########################################################################################
# Cleanup targets
.PHONY: clean-%
clean-%:
rm -rf $*
.PHONY: clean-pycache
clean-pycache:
find . -name __pycache__ -delete
.PHONY: clean
clean: clean-ve clean-pycache clean-dist
|