-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmakefile
285 lines (229 loc) · 8.61 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
283
284
285
PACKAGE_NAME := maze_dataset
PUBLISH_BRANCH := main
PYPI_TOKEN_FILE := .pypi-token
LAST_VERSION_FILE := .lastversion
PYPROJECT := pyproject.toml
PYTHON := poetry run python
# where to put docs
DOCS_DIR := docs
COVERAGE_REPORTS_DIR := $(DOCS_DIR)/coverage
NOTEBOOKS_DIR := notebooks
CONVERTED_NOTEBOOKS_TEMP_DIR := tests/_temp/notebooks
COMMIT_LOG_FILE := .commit_log
# reading version
# --------------------------------------------------
# assuming your pyproject.toml has a line that looks like `version = "0.0.1"`, will get the version
VERSION := NULL
# read last auto-uploaded version from file
LAST_VERSION := NULL
# get the python version, now that we have picked the python command
PYTHON_VERSION := NULL
.PHONY: gen-version-info
gen-version-info:
$(eval VERSION := $(shell python -c "import re; print('v'+re.search(r'^version\s*=\s*\"(.+?)\"', open('$(PYPROJECT)').read(), re.MULTILINE).group(1))"))
$(eval LAST_VERSION := $(shell [ -f $(LAST_VERSION_FILE) ] && cat $(LAST_VERSION_FILE) || echo NULL) )
$(eval PYTHON_VERSION := $(shell $(PYTHON) -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')") )
# getting commit log
.PHONY: gen-commit-log
gen-commit-log: gen-version-info
if [ "$(LAST_VERSION)" = "NULL" ]; then \
echo "LAST_VERSION is NULL, cant get commit log!"; \
exit 1; \
fi
$(shell python -c "import subprocess; open('$(COMMIT_LOG_FILE)', 'w').write('\n'.join(reversed(subprocess.check_output(['git', 'log', '$(LAST_VERSION)'.strip() + '..HEAD', '--pretty=format:- %s (%h)']).decode('utf-8').strip().split('\n'))))")
# pandoc commands (for docs)
PANDOC ?= pandoc
.PHONY: default
default: help
.PHONY: version
version: gen-commit-log
@echo "current and last-published version, commit log"
@echo "current-version: '$(VERSION)'"
@echo "last-published-version: '$(LAST_VERSION)'"
@echo "Commit log since last version:"
@cat $(COMMIT_LOG_FILE)
@if [ "$(VERSION)" = "$(LAST_VERSION)" ]; then \
echo "Python package $(VERSION) is the same as last published version $(LAST_VERSION), exiting!"; \
exit 1; \
fi
# format and lint
# --------------------------------------------------
.PHONY: lint
lint: clean
@echo "run linting: mypy"
$(PYTHON) -m mypy --config-file $(PYPROJECT) maze_dataset/
$(PYTHON) -m mypy --config-file $(PYPROJECT) tests/
.PHONY: format
format: clean
@echo "run formatting: pycln, isort, and black"
$(PYTHON) -m pycln --config $(PYPROJECT) --all .
$(PYTHON) -m isort format .
$(PYTHON) -m black .
.PHONY: check-format
check-format: clean
@echo "check formatting"
$(PYTHON) -m pycln --config $(PYPROJECT) --check --all .
$(PYTHON) -m isort --check-only .
$(PYTHON) -m black --check .
PYTEST_OPTIONS ?=
PYTEST_PARALLEL ?= 0
ifeq ($(PYTEST_PARALLEL),1)
PYTEST_OPTIONS+=-n auto
endif
# docs, coverage reports, and benchmarks
# --------------------------------------------------
# whether to run pytest with coverage report generation
COV ?= 1
ifeq ($(COV),1)
PYTEST_OPTIONS+=--cov=.
endif
.PHONY: docs-html
docs-html:
@echo "generate html docs"
$(PYTHON) docs/make_docs.py
.PHONY: docs-md
docs-md:
@echo "generate combined docs in markdown"
mkdir $(DOCS_DIR)/combined -p
$(PYTHON) docs/make_docs.py --combined
.PHONY: docs-combined
docs-combined: docs-md
@echo "generate combined docs in markdown and other formats"
@echo "requires pandoc in path"
$(PANDOC) -f markdown -t gfm $(DOCS_DIR)/combined/$(PACKAGE_NAME).md -o $(DOCS_DIR)/combined/$(PACKAGE_NAME)_gfm.md
$(PANDOC) -f markdown -t plain $(DOCS_DIR)/combined/$(PACKAGE_NAME).md -o $(DOCS_DIR)/combined/$(PACKAGE_NAME).txt
$(PANDOC) -f markdown -t html $(DOCS_DIR)/combined/$(PACKAGE_NAME).md -o $(DOCS_DIR)/combined/$(PACKAGE_NAME).html
.PHONY: docs-notebooks
docs-notebooks:
@echo "generate html docs for notebooks"
$(PYTHON) docs/make_docs.py --notebooks
.PHONY: cov
cov:
@echo "generate coverage reports (run tests manually)"
mkdir $(COVERAGE_REPORTS_DIR) -p
$(PYTHON) -m coverage report -m > $(COVERAGE_REPORTS_DIR)/coverage.txt
$(PYTHON) -m coverage_badge -f -o $(COVERAGE_REPORTS_DIR)/coverage.svg
$(PYTHON) -m coverage html --directory=$(COVERAGE_REPORTS_DIR)/html/
rm -rf $(COVERAGE_REPORTS_DIR)/html/.gitignore
.PHONY: benchmark
benchmark:
@echo "run benchmarks"
$(PYTHON) docs/benchmarks/benchmark_generation.py
.PHONY: docs
docs: docs-html docs-combined docs-notebooks cov
@echo "generate all documentation"
.PHONY: clean-docs
clean-docs:
@echo "clean up docs"
rm -rf $(DOCS_DIR)/combined/
rm -rf $(DOCS_DIR)/notebooks/
rm -rf $(DOCS_DIR)/maze_dataset/
rm -rf $(COVERAGE_REPORTS_DIR)/
rm $(DOCS_DIR)/maze_dataset.html
rm $(DOCS_DIR)/index.html
rm $(DOCS_DIR)/search.js
# testing
# --------------------------------------------------
.PHONY: unit
unit:
@echo "run unit tests"
$(PYTHON) -m pytest $(PYTEST_OPTIONS) tests/unit
.PHONY: save_tok_hashes
save_tok_hashes:
@echo "generate and save tokenizer hashes"
$(PYTHON) -m maze_dataset.tokenization.save_hashes -p
.PHONY: test_tok_hashes
test_tok_hashes:
@echo "re-run tokenizer hashes and compare"
$(PYTHON) -m maze_dataset.tokenization.save_hashes -p --check
.PHONY: test_all_tok
test_all_tok:
@echo "run tests on all tokenizers. can pass NUM_TOKENIZERS_TO_TEST arg or SKIP_HASH_TEST"
@echo "NUM_TOKENIZERS_TO_TEST=$(NUM_TOKENIZERS_TO_TEST)"
@if [ "$(SKIP_HASH_TEST)" != "1" ]; then \
echo "Running tokenizer hash tests"; \
$(MAKE) test_tok_hashes; \
else \
echo "Skipping tokenizer hash tests"; \
fi
$(PYTHON) -m pytest $(PYTEST_OPTIONS) --verbosity=-1 --durations=50 tests/all_tokenizers
.PHONY: convert_notebooks
convert_notebooks:
@echo "convert notebooks in $(NOTEBOOKS_DIR) using muutils.nbutils.convert_ipynb_to_script.py"
$(PYTHON) -m muutils.nbutils.convert_ipynb_to_script $(NOTEBOOKS_DIR) --output_dir $(CONVERTED_NOTEBOOKS_TEMP_DIR) --disable_plots
.PHONY: test_notebooks
test_notebooks: convert_notebooks
@echo "run tests on converted notebooks in $(CONVERTED_NOTEBOOKS_TEMP_DIR) using muutils.nbutils.run_notebook_tests.py"
$(PYTHON) -m muutils.nbutils.run_notebook_tests --notebooks-dir=$(NOTEBOOKS_DIR) --converted-notebooks-temp-dir=$(CONVERTED_NOTEBOOKS_TEMP_DIR)
.PHONY: test
test: clean unit test_notebooks
@echo "ran all tests: unit, integration, and notebooks"
.PHONY: check
check: clean check-format clean test
@echo "run format check and test"
# build and publish
# --------------------------------------------------
.PHONY: verify-git
verify-git:
@echo "checking git status"
if [ "$(shell git branch --show-current)" != $(PUBLISH_BRANCH) ]; then \
echo "Git is not on the $(PUBLISH_BRANCH) branch, exiting!"; \
exit 1; \
fi; \
if [ -n "$(shell git status --porcelain)" ]; then \
echo "Git is not clean, exiting!"; \
exit 1; \
fi; \
.PHONY: build
build:
@echo "build via poetry, assumes checks have been run"
poetry build
.PHONY: publish
publish: gen-commit-log check build verify-git version gen-version-info
@echo "run all checks, build, and then publish"
@echo "Enter the new version number if you want to upload to pypi and create a new tag"
@read -p "Confirm: " NEW_VERSION; \
if [ "$$NEW_VERSION" != "$(VERSION)" ]; then \
echo "'$$NEW_VERSION' is not the same as '$(VERSION)', exiting!"; \
echo "Confirmation failed, exiting!"; \
exit 1; \
fi; \
@echo "pypi username: __token__"
@echo "pypi token from '$(PYPI_TOKEN_FILE)' :"
echo $$(cat $(PYPI_TOKEN_FILE))
echo "Uploading!"; \
echo $(VERSION) > $(LAST_VERSION_FILE); \
git add $(LAST_VERSION_FILE); \
git commit -m "Auto update to $(VERSION)"; \
git tag -a $(VERSION) -F $(COMMIT_LOG_FILE); \
git push origin $(VERSION); \
twine upload dist/* --verbose
# general util
# --------------------------------------------------
.PHONY: clean
clean:
@echo "cleaning up caches and temp files"
rm -rf .mypy_cache
rm -rf .pytest_cache
rm -rf .coverage
rm -rf dist
rm -rf build
rm -rf tests/_temp
python -Bc "import pathlib; [p.unlink() for p in pathlib.Path('.').rglob('*.py[co]')]"
python -Bc "import pathlib; [p.rmdir() for p in pathlib.Path('.').rglob('__pycache__')]"
help-prereq:
@echo -n "# list make targets"
@echo ":"
@cat Makefile | sed -n '/^\.PHONY: / h; /\(^\t@*echo\|^\t:\)/ {H; x; /PHONY/ s/.PHONY: \(.*\)\n.*"\(.*\)"/ make \1\t\2/p; d; x}'| sort -k2,2 |expand -t 30
# listing targets, from stackoverflow
# https://stackoverflow.com/questions/4219255/how-do-you-get-the-list-of-targets-in-a-makefile
.PHONY: help
help: help-prereq gen-version-info
@echo -n ""
@echo "# makefile variables"
@echo " PYTHON = $(PYTHON)"
@echo " PYTHON_VERSION = $(PYTHON_VERSION)"
@echo " PACKAGE_NAME = $(PACKAGE_NAME)"
@echo " VERSION = $(VERSION)"
@echo " LAST_VERSION = $(LAST_VERSION)"
@echo " PYTEST_OPTIONS = $(PYTEST_OPTIONS)"