-
Notifications
You must be signed in to change notification settings - Fork 1
/
Makefile
282 lines (223 loc) · 9.11 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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
SHELL = /bin/bash
PROJECT_ROOT = $(shell pwd)
VENV_NAME = venv
VENV_DIR = $(PROJECT_ROOT)/$(VENV_NAME)
VENV_BIN = $(VENV_DIR)/bin
VENV_LIBRARY_BIN = $(VENV_DIR)/Library/bin
# Windows support
ifeq ($(OS),Windows_NT)
VENV_BIN = $(PROJECT_ROOT)/venv/Scripts
endif
# Version of the used tools
PYTHON_VERSION = 3.9
# Project Directories
REPORT_TARGET_DIR = $(PROJECT_ROOT)/target/report
PYTEST_REPORT_DIR = $(REPORT_TARGET_DIR)/pytest
COVERAGE_REPORT_DIR = $(REPORT_TARGET_DIR)/coverage
FLAKE8_REPORT_DIR = $(REPORT_TARGET_DIR)/flake8
SECURITY_REPORT_DIR = $(REPORT_TARGET_DIR)/security
TEST_TARGET_DIR = $(PROJECT_ROOT)/target/test
DOCS_SITE_DIR = $(PROJECT_ROOT)/site
SRC_DIST_DIR = $(PROJECT_ROOT)/dist
# Export some environment variables
export PYTHONPATH := $(PROJECT_ROOT)/src/:$(PROJECT_ROOT)
export PACKAGE_NAME = $(shell python setup.py --name 2> /dev/null)
export FULL_PACKAGE_VERSION = $(shell python setup.py --version 2> /dev/null)
export PACKAGE_VERSION = $(shell python setup.py --version 2> /dev/null | \
grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | \
cut -d '.' -f 1-3)
export SHORT_PACKAGE_VERSION = $(shell python setup.py --version 2> /dev/null | \
grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | \
cut -d '.' -f 1-2)
# Activate virtual environment
VENV_ACTIVATE = source activate $(PROJECT_ROOT)/$(VENV_NAME)
# ============================
# INFO
# ============================
all: info
.PHONY: info
info: ## Show this information
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
# ============================
# ENV
# ============================
$(VENV_DIR):
conda create --verbose --no-default-packages --yes --prefix $(VENV_DIR)
cp -f .condarc venv/.condarc || true
cp -f pip.conf venv/pip.conf || true
cp -f pip.conf venv/pip.ini || true
$(VENV_ACTIVATE); python -m pip install -U -e . -r requirements.dev.txt -c constraints.txt
venv: $(VENV_DIR) ## Create virtualenv
.PHONY: update
update: venv ## Update dependencies
$(VENV_ACTIVATE); python -m pip install -U -e . -r requirements.dev.txt -c constraints.txt
.PHONY: freeze
freeze: ## List dependencies
$(VENV_ACTIVATE); pip freeze > requirements.freeze.txt
# ============================
# CLEAN
# ============================
.PHONY: clean
clean: clean-pyc clean-dist clean-test clean-reports clean-docs ## Clean artifacts
@find . -name '*~' -exec rm -f {} +
.PHONY: clean-pyc
clean-pyc: ## Clean python artifacts
@find . -name '*.eggs' -exec rm -rf {} +
@find . -name '*.pyc' -exec rm -rf {} +
@find . -name '*.pyo' -exec rm -rf {} +
@find . -name '*.egg-info' -exec rm -rf {} +
@find . -name '__pycache__' -exec rm -rf {} +
@find . -name '.pytest_cache' -exec rm -rf {} +
@find . -name '.coverage*' -exec rm -rf {} +
@find . -name 'spark-warehouse*' -exec rm -rf {} +
@find . -name 'checkpoints*' -exec rm -rf {} +
@find ./src -type d -empty -delete
@find ./tests -type d -empty -delete
.PHONY: clean-dist
clean-dist: ## Clean dist directories
rm -rf $(SRC_DIST_DIR) || true
rm -rf build || true
.PHONY: clean-reports
clean-reports: ## Clean reports
rm -rf $(REPORT_TARGET_DIR) || true
.PHONY: clean-docs
clean-docs: ## Clean documentation site directory.
rm -rf $(DOCS_SITE_DIR) || true
.PHONY: clean-test
clean-test: ## Clean test target directory
@find . -name '.coverage*' -exec rm -rf {} +
rm -rf $(TEST_TARGET_DIR) || true
.PHONY: clean-security
clean-security: ## Clean security reports
rm -rf $(SECURITY_REPORT_DIR) || true
.PHONY: clean-flake8
clean-flake8: ## Clean flake8 reports
rm -rf $(FLAKE8_REPORT_DIR) || true
.PHONY: clean-changelog
clean-changelog: ## Clean changelog fragments (records).
rm -rf resources/changelog/*.md || true
.PHONY: clean-local-ghp
clean-local-ghp: ## Clean local documentation branches.
git branch --delete gh-pages || true
git branch --delete github-pages || true
.PHONY: clean-remote-ghp
clean-remote-ghp: ## Clean remote documentation branches.
git push origin --delete gh-pages || true
git push origin --delete github-pages || true
# ============================
# SAFETY
# ============================
.PHONY: safety-check
safety-check: clean-security ## Check dependencies vulnerabilities using pyup.io safety package.
@echo "----------------------------------------------------------------------------------------"
@echo "------------------------ VULNERABILITY CHECK --------------------------"
@echo "----------------------------------------------------------------------------------------"
mkdir -p $(SECURITY_REPORT_DIR) || true
$(VENV_ACTIVATE); safety check --output=json -i 51457 --save-json=$(SECURITY_REPORT_DIR)
#$(VENV_ACTIVATE); safety scan --detailed-output --save-as json $(SECURITY_REPORT_DIR)/safety-report.json
.PHONY: safety-review
safety-review: safety-check ## Review a pyup.io safety report.
$(VENV_ACTIVATE); safety review --full-report --file=$(SECURITY_REPORT_DIR)/safety-report.json
# ============================
# TEST
# ============================
.PHONY: check-code
check-code: clean-flake8 ## Check code with some static analysis.
mkdir -p $(FLAKE8_REPORT_DIR)
$(VENV_ACTIVATE); flake8 --output-file=$(FLAKE8_REPORT_DIR)/codeclimate.json ./src/ || true
$(VENV_ACTIVATE); flake8 --output-file=$(FLAKE8_REPORT_DIR)/quality.txt ./src/ || true
$(VENV_ACTIVATE); flake8 --format=html --htmldir=$(FLAKE8_REPORT_DIR)/html ./src/ || true
.PHONY: test
test: clean-test check-code ## Launch tests with coverage.
$(VENV_ACTIVATE); pytest -vvv -rA \
--continue-on-collection-errors \
--numprocesses logical \
--maxprocesses 1 \
--dist loadfile \
--asyncio-mode strict \
--cov
.PHONY: test-with-report
test-with-report: clean-test clean-pyc clean-dist check-code ## Launch tests with coverage reports.
mkdir -p $(TEST_TARGET_DIR)
mkdir -p $(COVERAGE_REPORT_DIR)/html
$(VENV_ACTIVATE); pytest -vv -rA \
--basetemp $(TEST_TARGET_DIR) \
--continue-on-collection-errors \
--numprocesses logical \
--maxprocesses 1 \
--dist loadfile \
--asyncio-mode strict \
--html=$(PYTEST_REPORT_DIR)/pytests.html --self-contained-html \
--junitxml=$(PYTEST_REPORT_DIR)/junit.xml \
--cov \
&& coverage json --pretty-print --ignore-errors -o $(COVERAGE_REPORT_DIR)/coverage.json \
&& coverage xml --ignore-errors -o $(COVERAGE_REPORT_DIR)/coverage.xml \
&& coverage html -d $(COVERAGE_REPORT_DIR)/html
# ============================
# Package
# ============================
.PHONY: build-package
build-package: clean-pyc clean-dist ## Build the python package.
$(VENV_ACTIVATE); python -m pip install --upgrade build -c constraints.txt
$(VENV_ACTIVATE); python -m build --no-isolation
.PHONY: deploy-package
deploy-package: ## Deploy the python package
$(VENV_ACTIVATE); python -m pip install --upgrade twine -c constraints.txt
echo "Deployment: Twine uploads to PyPI"
$(VENV_ACTIVATE); python -m twine upload --verbose dist/*
# ============================
# CHANGELOG
# ============================
.PHONY: record-add
record-add: ## Record a new change by creating news fragments (Read changelog.md).
echo "Message: $(msg)"
echo "Issue: db2ixf-$(nbr)"
$(VENV_ACTIVATE); towncrier create -c "$(msg)" $(nbr).added.md
.PHONY: record-change
record-change: ## Record a new change by creating new fragments (Read changelog.md).
echo "Message: $(msg)"
echo "Issue: db2ixf-$(nbr)"
$(VENV_ACTIVATE); towncrier create -c "$(msg)" $(nbr).changed.md
.PHONY: record-deprecate
record-deprecate: ## Record a new change by creating new fragments (Read changelog.md).
echo "Message: $(msg)"
echo "Issue: db2ixf-$(nbr)"
$(VENV_ACTIVATE); towncrier create -c "$(msg)" $(nbr).deprecated.md
.PHONY: record-remove
record-remove: ## Record a new change by creating new fragments (Read changelog.md).
echo "Message: $(msg)"
echo "Issue: db2ixf-$(nbr)"
$(VENV_ACTIVATE); towncrier create -c "$(msg)" $(nbr).removed.md
.PHONY: record-fix
record-fix: ## Record a new change by creating new fragments (Read changelog.md).
echo "Message: $(msg)"
echo "Issue: db2ixf-$(nbr)"
$(VENV_ACTIVATE); towncrier create -c "$(msg)" $(nbr).fixed.md
.PHONY: record-secure
record-secure: ## Record a new change by creating new fragments (Read changelog.md).
echo "Message: $(msg)"
echo "Issue: db2ixf-$(nbr)"
$(VENV_ACTIVATE); towncrier create -c "$(msg)" $(nbr).security.md
.PHONY: changelog
changelog: ## Update CHANGELOG.md with the last news fragments.
$(VENV_ACTIVATE); towncrier build --yes --version $(PACKAGE_VERSION) 2> /dev/null || true
# ============================
# DOCS
# ============================
.PHONY: serve-docs
serve-docs: ## Serve documentation in a live loading mode.
echo "Serve the documentation using Mkdocs"
$(VENV_ACTIVATE); mkdocs serve
.PHONY: build-docs
build-docs: ## Build documentation.
echo "Build the documentation using Mkdocs"
$(VENV_ACTIVATE); mkdocs build
.PHONY: mkdocs-deploy-docs
mkdocs-deploy-docs: clean-docs build-docs ## Deploy documentation to github pages (gh-pages) using Mkdocs.
echo "Deploying the documentation to github pages (gh-pages) using Mkdocs"
$(VENV_ACTIVATE); mkdocs gh-deploy --clean \
--message "Deploy documentation ({sha})." \
--config-file mkdocs.yml \
--verbose \
--force