-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMakefile
More file actions
334 lines (290 loc) · 11.2 KB
/
Copy pathMakefile
File metadata and controls
334 lines (290 loc) · 11.2 KB
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
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#################################################################################
# GLOBALS #
#################################################################################
PROJECT_NAME = devices_rap
PYTHON_VERSION = 3.12
# Detect if uv is available
UV_AVAILABLE := $(shell command -v uv >/dev/null 2>&1 && echo "yes" || echo "no")
# Environment variables that can be overridden
USE_UV ?= auto
VENV_DIR ?= .venv
# Determine which tool to use
ifeq ($(USE_UV),yes)
TOOL = uv
else ifeq ($(USE_UV),no)
TOOL = venv
else ifeq ($(UV_AVAILABLE),yes)
TOOL = uv
else
TOOL = venv
endif
# Set commands based on tool choice
ifeq ($(TOOL),uv)
PYTHON_INTERPRETER = uv run python
VENV_CREATE = uv venv $(VENV_DIR)
INSTALL_CMD = uv sync
INSTALL_DEV = uv sync --extra dev
INSTALL_ALL = uv sync --extra dev --extra docs --extra jupyter
else
PYTHON_INTERPRETER = $(VENV_DIR)/bin/python
VENV_CREATE = python -m venv $(VENV_DIR)
INSTALL_CMD = $(PYTHON_INTERPRETER) -m pip install -e .
INSTALL_DEV = $(PYTHON_INTERPRETER) -m pip install -e ".[dev]"
INSTALL_ALL = $(PYTHON_INTERPRETER) -m pip install -e ".[dev,docs,jupyter]"
endif
#################################################################################
# COMMANDS #
#################################################################################
## Show environment info
.PHONY: info
info:
@echo "=== Environment Information ==="
@echo "Project: $(PROJECT_NAME)"
@echo "Tool: $(TOOL)"
@echo "UV Available: $(UV_AVAILABLE)"
@echo "Python Interpreter: $(PYTHON_INTERPRETER)"
@echo "Virtual Environment: $(VENV_DIR)"
@echo "================================"
## Create virtual environment (use USE_UV=yes/no to force tool choice)
.PHONY: venv
venv:
@echo "Creating virtual environment with $(TOOL)..."
ifeq ($(TOOL),uv)
$(VENV_CREATE)
@echo "✓ Virtual environment created with uv"
@echo "To activate: source $(VENV_DIR)/bin/activate"
@echo "Or use: uv run <command>"
else
$(VENV_CREATE)
$(VENV_DIR)/bin/python -m pip install --upgrade pip
@echo "✓ Virtual environment created with venv"
@echo "To activate: source $(VENV_DIR)/bin/activate"
endif
## Install production dependencies only
.PHONY: install
install: venv
@echo "Installing production dependencies with $(TOOL)..."
$(INSTALL_CMD)
@echo "✓ Production dependencies installed"
## Install development dependencies
.PHONY: install-dev
install-dev: venv
@echo "Installing development dependencies with $(TOOL)..."
$(INSTALL_DEV)
@echo "✓ Development dependencies installed"
## Install all dependencies (dev + test + docs)
.PHONY: install-all
install-all: venv
@echo "Installing all dependencies with $(TOOL)..."
$(INSTALL_ALL)
@echo "✓ All dependencies installed"
## Alias for install-dev (backward compatibility)
.PHONY: requirements
requirements: install-dev
## Check if dev environment is ready (light check without recreating venv)
.PHONY: check-dev-env
check-dev-env:
ifeq ($(TOOL),uv)
@echo "Checking dev environment with uv..."
@uv run python -c "import black, flake8, isort, pytest" 2>/dev/null || (echo "Dev dependencies missing, installing..." && $(MAKE) install-dev)
else
@echo "Checking dev environment with venv..."
@test -f $(VENV_DIR)/bin/python || $(MAKE) install-dev
@$(PYTHON_INTERPRETER) -c "import black, flake8, isort, pytest" 2>/dev/null || $(MAKE) install-dev
endif
## Clean compiled Python files and caches
.PHONY: clean
clean:
@echo "Cleaning Python artifacts..."
find . -type f -name "*.pyc" -delete
find . -type f -name "*.pyo" -delete
find . -type d -name "__pycache__" -delete
find . -type d -name ".pytest_cache" -exec rm -rf {} +
rm -rf htmlcov/
rm -rf .coverage
@echo "✓ Cleaned Python artifacts"
## Alias for clean
.PHONY: clear
clear: clean
## Remove virtual environment and lock files
.PHONY: clean-env
clean-env:
@echo "Removing virtual environment and lock files..."
rm -rf $(VENV_DIR)
rm -f uv.lock
rm -rf .uv
@echo "✓ Environment cleaned"
## Complete cleanup (clean + clean-env)
.PHONY: nuke
nuke: clean clean-env
@echo "🚀 Complete cleanup finished"
## Set up pre-commit hooks
.PHONY: pre-commit
pre-commit: check-dev-env
@echo "Setting up pre-commit hooks..."
$(PYTHON_INTERPRETER) -m pre_commit install
@echo "✓ Pre-commit hooks installed"
## Run pre-commit on all files
.PHONY: pre-commit-all
pre-commit-all: check-dev-env
@echo "Running pre-commit on all files..."
$(PYTHON_INTERPRETER) -m pre_commit run --all-files
## Alias for pre-commit (backward compatibility)
.PHONY: pre-commits
pre-commits: pre-commit-all
## Lint code (without fixing)
.PHONY: lint
lint: check-dev-env
@echo "Linting code..."
$(PYTHON_INTERPRETER) -m flake8 $(PROJECT_NAME) tests/
$(PYTHON_INTERPRETER) -m isort --check-only --diff --profile black $(PROJECT_NAME) tests/
$(PYTHON_INTERPRETER) -m black --check --config pyproject.toml $(PROJECT_NAME) tests/
## Format code
.PHONY: format
format: check-dev-env
@echo "Formatting code..."
$(PYTHON_INTERPRETER) -m isort --profile black $(PROJECT_NAME) tests/
$(PYTHON_INTERPRETER) -m black --config pyproject.toml $(PROJECT_NAME) tests/
@echo "✓ Code formatted"
## Create a new branch
.PHONY: branch
branch:
git checkout -b ${name}
## Create test files for all python files in the project
.PHONY: create_tests
create_tests:
@find $(PROJECT_NAME) -type f -name "*.py" | while read file; do \
if [ $$(basename $$file) != "__init__.py" ]; then \
new_path=tests/unittests/$$(echo $$file | sed 's|^[^/]*/||' | awk -F/ '{for(i=1;i<=NF;i++)$$i="test_"$$i; print}' OFS=/); \
mkdir -p $$(dirname $$new_path); \
if [ ! -f $$new_path ]; then \
touch $$new_path; \
echo "\"\"\"\nTests for $$(echo $$file | sed 's|/|.|g' | sed 's|\.py||')\n\"\"\"\nimport pytest\n" >> $$new_path; \
echo "import $$(echo $$file | sed 's|/|.|g' | sed 's|\.py||')" >> $$new_path; \
echo "\n\nclass TestExample:" >> $$new_path; \
echo " \"\"\"Example test class\"\"\"" >> $$new_path; \
echo " def test_example(self):" >> $$new_path; \
echo " \"\"\"Example test case\"\"\"" >> $$new_path; \
echo " assert True" >> $$new_path; \
fi \
fi \
done
#################################################################################
# DOCUMENTATION #
#################################################################################
## Generate API reference documentation files
.PHONY: docs-generate
docs-generate: check-dev-env
@echo "Generating API documentation..."
$(PYTHON_INTERPRETER) docs/gen_ref_pages.py
## Build documentation
.PHONY: docs-build
docs-build: check-dev-env
@echo "Building documentation..."
$(PYTHON_INTERPRETER) -m mkdocs build --config-file docs/mkdocs.yml
## Serve documentation locally
.PHONY: docs-serve
docs-serve: check-dev-env
@echo "Serving documentation locally..."
$(PYTHON_INTERPRETER) -m mkdocs serve --config-file docs/mkdocs.yml
## Generate API docs and serve locally
.PHONY: docs
docs: docs-serve
#################################################################################
# PROJECT RULES #
#################################################################################
## Run pipeline in local mode
.PHONY: run-pipeline-local
run-pipeline-local: install
ifeq ($(fin_month),)
@echo "Error: fin_month is required. Usage: make run-pipeline-local fin_month=01 fin_year=2526"; exit 1
endif
ifeq ($(fin_year),)
@echo "Error: fin_year is required. Usage: make run-pipeline-local fin_month=01 fin_year=2526"; exit 1
endif
@echo "Running pipeline in local mode..."
$(PYTHON_INTERPRETER) -m $(PROJECT_NAME).pipeline --mode local --fin-month $(fin_month) --fin-year $(fin_year)
## Run pipeline in remote mode
.PHONY: run-pipeline-remote
run-pipeline-remote: install
ifeq ($(fin_month),)
@echo "Error: fin_month is required. Usage: make run-pipeline-remote fin_month=01 fin_year=2526"; exit 1
endif
ifeq ($(fin_year),)
@echo "Error: fin_year is required. Usage: make run-pipeline-remote fin_month=01 fin_year=2526"; exit 1
endif
@echo "Running pipeline in remote mode..."
$(PYTHON_INTERPRETER) -m $(PROJECT_NAME).pipeline --mode remote --fin-month $(fin_month) --fin-year $(fin_year)
.PHONY: run-pipeline
run-pipeline: install
$(PYTHON_INTERPRETER) -m $(PROJECT_NAME).pipeline $(ARGS)
.PHONY: run
run: run-pipeline
.PHONY: e2e
e2e: test-e2e
## Run tests with coverage
.PHONY: test-cov
test-cov: check-dev-env
@echo "Running tests with coverage..."
$(PYTHON_INTERPRETER) -m pytest tests/ --cov=$(PROJECT_NAME) --cov-report=html --cov-report=term-missing -v
@echo "✓ Coverage report generated in htmlcov/"
#################################################################################
# Self Documenting Commands #
#################################################################################
.DEFAULT_GOAL := help
## Show available commands
.PHONY: help
help:
@echo "$(PROJECT_NAME) - Available Commands"
@echo ""
@echo "Environment Setup:"
@echo " info Show environment information"
@echo " venv Create virtual environment"
@echo " install Install production dependencies"
@echo " install-dev Install development dependencies"
@echo " install-all Install all dependencies (dev + docs + jupyter)"
@echo " requirements Install dev dependencies (alias for install-dev)"
@echo ""
@echo "Development:"
@echo " format Format code with black and isort"
@echo " lint Lint code without fixing"
@echo " pre-commit Install pre-commit hooks"
@echo " pre-commit-all Run pre-commit on all files"
@echo " branch Create new branch (usage: make branch name=branch-name)"
@echo " create_tests Create test files for Python modules"
@echo ""
@echo "Documentation:"
@echo " docs Generate API docs and serve locally"
@echo " docs-generate Generate API reference files"
@echo " docs-build Build documentation"
@echo " docs-serve Serve documentation locally"
@echo ""
@echo "Testing:"
@echo " test Run all tests"
@echo " test-unit Run unit tests only"
@echo " test-e2e Run end-to-end tests only"
@echo " test-cov Run tests with coverage report"
@echo " unittest Alias for test-unit"
@echo " e2e Alias for test-e2e"
@echo ""
@echo "Pipeline:"
@echo " run Run pipeline (default: local mode)"
@echo " run-pipeline-local Run pipeline in local mode"
@echo " run-pipeline-remote Run pipeline in remote mode"
@echo ""
@echo "Cleanup:"
@echo " clean Clean Python artifacts"
@echo " clear Alias for clean"
@echo " clean-env Remove virtual environment"
@echo " nuke Complete cleanup (clean + clean-env)"
@echo ""
@echo "Environment Variables:"
@echo " USE_UV=yes/no/auto Force tool choice (default: auto)"
@echo " VENV_DIR=path Virtual environment directory (default: .venv)"
@echo ""
@echo "Examples:"
@echo " make info # Show current environment"
@echo " make venv USE_UV=yes # Force use uv"
@echo " make venv USE_UV=no # Force use venv"
@echo " make install-dev # Auto-detect tool and install dev deps"
@echo " make branch name=jw/DEV-123_new-feature"