-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
186 lines (126 loc) · 3.5 KB
/
Makefile
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
# {{{ globals
SHELL = bash -eu -o pipefail
override MAKEFLAGS += --no-builtin-rules --warn-undefined-variables
.DELETE_ON_ERROR:
export CLICOLOR_FORCE = 1
export FORCE_COLOR = 1
PYPROJECT = pyproject.toml
ARGV ?=
# }}}
# {{{ help
.PHONY: help
help:
$(info $(_HELP))
@true
define _HELP
PyProject Dev
variables:
ARGV: Append to target command line
targets:
lint: `pre-commit run`
endef
# }}}
# {{{ lint
.PHONY: lint
lint:
pre-commit run --all-files $(ARGV)
# }}}
# {{{ test
ifneq ($(wildcard tests),)
# {{{ whitelist
WHITELIST = tests/whitelist.py
.PHONY: $(WHITELIST)
$(WHITELIST):
echo > $@ "# whitelist for vulture"
echo >> $@ "# ruff: noqa"
echo >> $@ "# type: ignore"
-vulture --make-whitelist . >> $@
.PHONY: whitelist
whitelist: $(WHITELIST)
# }}}
# {{{ basic
EXPR ?=
TEST_PATH ?=
_EMPTY :=
_SPACE := $(_EMPTY) $(_EMPTY)
.PHONY: test
test: override ARGV += $(if $(EXPR),-k "$(subst $(_SPACE), and ,$(strip $(EXPR)))")
test:
pytest $(strip $(ARGV) $(TEST_PATH))
# }}}
# {{{ coverage
COV_REPORT ?= term-missing:skip-covered html
COV_CFG =
# conf `coverage.run.dynamic_context` breaks with pytest-cov so we set --cov-context=test
# https://github.com/pytest-dev/pytest-cov/issues/604
COV_ARGV = \
--cov \
--cov-context=test \
$(addprefix --cov-report=,$(COV_REPORT)) \
--no-cov-on-fail
# needed for subprocess coverage
SITE_CUSTOMIZE = .site/sitecustomize.py
$(SITE_CUSTOMIZE):
mkdir -p $(@D)
echo > $@ "import coverage; coverage.process_startup()"
# define if not set to silence warning
NIX_PYTHONPATH ?=
.PHONY: test-cov
test-cov: export COVERAGE_PROCESS_START = $(CURDIR)/$(if $(COV_CFG),$(COV_CFG),$(PYPROJECT))
# use NIX_PYTHONPATH as this sets the contents as site dirs, which is needed to pick
# up sitecustomize
test-cov: export NIX_PYTHONPATH := $(CURDIR)/$(patsubst %/,%,$(dir $(SITE_CUSTOMIZE))):$(NIX_PYTHONPATH)
test-cov: override ARGV += $(COV_ARGV)
test-cov: $(SITE_CUSTOMIZE) test
define _HELP :=
$(_HELP)
whitelist: write vulture whitelist
test: run tests
EXPR: Filter tests by substring expression
TEST_PATH: Path to test file or directory
test-cov: run tests with coverage
EXPR/TEST_PATH: As above
COV_REPORT: Coverage report types (current: $(COV_REPORT))
see `pytest --help /--cov-report`
endef
# }}}
# {{{ subtest
SUBTEST_TEST = test-$1
SUBTEST_COV = test-$1-cov
SUBTEST_TARGETS = $(SUBTEST_TEST) $(SUBTEST_COV)
NUM_PROCESSES ?= logical
HERE = $(patsubst %/,%,$(dir $(lastword \
$(shell realpath --relative-to $(CURDIR) $(MAKEFILE_LIST)))))
tests/.covcfg-%.toml: $(HERE)/covcfg.py $(PYPROJECT)
./$^ $* > $@
define SUBTEST
.PHONY: test-$1
define _HELP :=
$(_HELP)
$(SUBTEST_TARGETS): Sub test and coverage
endef
ifneq ($(shell find tests -path \*$1\*.py),)
$(SUBTEST_TARGETS): TEST_PATH = tests/$1
endif
ifneq ($(wildcard tests/$1/pytest),)
$(SUBTEST_TARGETS): override ARGV += $$(file < tests/$1/pytest)
endif
ifneq ($(wildcard tests/$1/xdist),)
$(SUBTEST_TARGETS): override ARGV += --numprocesses=$(NUM_PROCESSES)
endif
ifneq ($(wildcard tests/$1/covcfg.toml),)
tests/.covcfg-$1.toml: tests/$1/covcfg.toml
$(SUBTEST_COV): COV_CFG = tests/.covcfg-$1.toml
$(SUBTEST_COV): tests/.covcfg-$1.toml
$(SUBTEST_COV): override COV_ARGV += --cov-config=$$(COV_CFG)
endif
$(SUBTEST_TEST): test
$(SUBTEST_COV): test-cov
endef
$(foreach test, \
$(shell find tests -mindepth 1 -maxdepth 1 -type d \
-not -name .\* -and -not -name __pycache__ -and -not -name coverage\* | sort), \
$(eval $(call SUBTEST,$(notdir $(test)))))
# }}}
endif
# }}}