3
3
# (An enterprise-ready Model Context Protocol Gateway)
4
4
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5
5
#
6
- # Author : Mihai Criveti
6
+ # Authors : Mihai Criveti, Manav Gupta
7
7
# Description: Build & automation helpers for the MCP Gateway project
8
8
# Usage: run `make` or `make help` to view available targets
9
9
#
@@ -182,8 +182,12 @@ clean:
182
182
# help: htmlcov - (re)build just the HTML coverage report into docs
183
183
# help: test-curl - Smoke-test API endpoints with curl script
184
184
# help: pytest-examples - Run README / examples through pytest-examples
185
+ # help: doctest - Run doctest on all modules with summary report
186
+ # help: doctest-verbose - Run doctest with detailed output (-v flag)
187
+ # help: doctest-coverage - Generate coverage report for doctest examples
188
+ # help: doctest-check - Check doctest coverage percentage (fail if < 100%)
185
189
186
- .PHONY : smoketest test coverage pytest-examples test-curl htmlcov
190
+ .PHONY : smoketest test coverage pytest-examples test-curl htmlcov doctest doctest-verbose doctest-coverage doctest-check
187
191
188
192
# # --- Automated checks --------------------------------------------------------
189
193
smoketest :
@@ -239,6 +243,43 @@ pytest-examples:
239
243
test-curl :
240
244
./test_endpoints.sh
241
245
246
+ # # --- Doctest targets ---------------------------------------------------------
247
+ doctest :
248
+ @echo " 🧪 Running doctest on all modules..."
249
+ @test -d " $( VENV_DIR) " || $(MAKE ) venv
250
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
251
+ python3 -m pytest --doctest-modules mcpgateway/ --tb=short"
252
+
253
+ doctest-verbose :
254
+ @echo " 🧪 Running doctest with verbose output..."
255
+ @test -d " $( VENV_DIR) " || $(MAKE ) venv
256
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
257
+ python3 -m pytest --doctest-modules mcpgateway/ -v --tb=short"
258
+
259
+ doctest-coverage :
260
+ @echo " 📊 Generating doctest coverage report..."
261
+ @test -d " $( VENV_DIR) " || $(MAKE ) venv
262
+ @mkdir -p $(TEST_DOCS_DIR )
263
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
264
+ python3 -m pytest --doctest-modules mcpgateway/ \
265
+ --cov=mcpgateway --cov-report=term --cov-report=html:htmlcov-doctest \
266
+ --cov-report=xml:coverage-doctest.xml"
267
+ @echo " ✅ Doctest coverage report generated in htmlcov-doctest/"
268
+
269
+ doctest-check :
270
+ @echo " 🔍 Checking doctest coverage..."
271
+ @test -d " $( VENV_DIR) " || $(MAKE ) venv
272
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && \
273
+ python3 -c \" import subprocess, sys; \
274
+ result = subprocess.run([' python' , ' -m' , ' pytest' , ' --doctest-modules' , ' mcpgateway/' , ' --tb=no' , ' -q' ], capture_output=True); \
275
+ if result.returncode == 0: \
276
+ print(' ✅ All doctests passing' ); \
277
+ else: \
278
+ print(' ❌ Doctest failures detected' ); \
279
+ print(result.stdout.decode ()); \
280
+ print(result.stderr.decode ()); \
281
+ sys.exit(1)\" "
282
+
242
283
# =============================================================================
243
284
# 📊 METRICS
244
285
# =============================================================================
@@ -304,8 +345,8 @@ images:
304
345
@mkdir -p $(DOCS_DIR ) /docs/design/images
305
346
@code2flow mcpgateway/ --output $(DOCS_DIR ) /docs/design/images/code2flow.dot || true
306
347
@dot -Tsvg -Gbgcolor=transparent -Gfontname=" Arial" -Nfontname=" Arial" -Nfontsize=14 -Nfontcolor=black -Nfillcolor=white -Nshape=box -Nstyle=" filled,rounded" -Ecolor=gray -Efontname=" Arial" -Efontsize=14 -Efontcolor=black $(DOCS_DIR ) /docs/design/images/code2flow.dot -o $(DOCS_DIR ) /docs/design/images/code2flow.svg || true
307
- @/bin/bash -c " source $( VENV_DIR) /bin/activate && python -m pip install snakefood3"
308
- @/bin/bash -c " source $( VENV_DIR) /bin/activate && python -m snakefood3 . mcpgateway > snakefood.dot"
348
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && python3 -m pip install snakefood3"
349
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && python3 -m snakefood3 . mcpgateway > snakefood.dot"
309
350
@dot -Tpng -Gbgcolor=transparent -Gfontname=" Arial" -Nfontname=" Arial" -Nfontsize=12 -Nfontcolor=black -Nfillcolor=white -Nshape=box -Nstyle=" filled,rounded" -Ecolor=gray -Efontname=" Arial" -Efontsize=10 -Efontcolor=black snakefood.dot -o $(DOCS_DIR ) /docs/design/images/snakefood.png || true
310
351
@pyreverse --colorized mcpgateway || true
311
352
@dot -Tsvg -Gbgcolor=transparent -Gfontname=" Arial" -Nfontname=" Arial" -Nfontsize=14 -Nfontcolor=black -Nfillcolor=white -Nshape=box -Nstyle=" filled,rounded" -Ecolor=gray -Efontname=" Arial" -Efontsize=14 -Efontcolor=black packages.dot -o $(DOCS_DIR ) /docs/design/images/packages.svg || true
@@ -403,7 +444,13 @@ pycodestyle: ## 📝 Simple PEP-8 checker
403
444
@$(VENV_DIR ) /bin/pycodestyle mcpgateway --max-line-length=200
404
445
405
446
pre-commit : # # 🪄 Run pre-commit hooks
406
- @$(VENV_DIR ) /bin/pre-commit run --all-files --show-diff-on-failure
447
+ @echo " 🪄 Running pre-commit hooks..."
448
+ @test -d " $( VENV_DIR) " || $(MAKE ) venv install install-dev
449
+ @if [ ! -f " $( VENV_DIR) /bin/pre-commit" ]; then \
450
+ echo " 📦 Installing pre-commit..." ; \
451
+ /bin/bash -c " source $( VENV_DIR) /bin/activate && python3 -m pip install --quiet pre-commit" ; \
452
+ fi
453
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && pre-commit run --all-files --show-diff-on-failure"
407
454
408
455
ruff : # # ⚡ Ruff lint + format
409
456
@$(VENV_DIR ) /bin/ruff check mcpgateway && $(VENV_DIR ) /bin/ruff format mcpgateway tests
@@ -460,7 +507,7 @@ spellcheck-sort: .spellcheck-en.txt ## 🔤 Sort spell-list
460
507
461
508
tox : # # 🧪 Multi-Python tox matrix (uv)
462
509
@echo " 🧪 Running tox with uv ..."
463
- python -m tox -p auto $(TOXARGS )
510
+ python3 -m tox -p auto $(TOXARGS )
464
511
465
512
sbom : # # 🛡️ Generate SBOM & security report
466
513
@echo " 🛡️ Generating SBOM & security report..."
@@ -470,7 +517,7 @@ sbom: ## 🛡️ Generate SBOM & security report
470
517
@/bin/bash -c " source $( VENV_DIR) /bin/activate && python3 -m uv pip install cyclonedx-bom sbom2doc"
471
518
@echo " 🔍 Generating SBOM from environment..."
472
519
@/bin/bash -c " source $( VENV_DIR) /bin/activate && \
473
- python -m cyclonedx_py environment \
520
+ python3 -m cyclonedx_py environment \
474
521
--output-format XML \
475
522
--output-file $(PROJECT_NAME ) .sbom.xml \
476
523
--no-validate \
@@ -843,7 +890,7 @@ pip-audit:
843
890
deps-update :
844
891
@echo " ⬆️ Updating project dependencies via update-deps.py..."
845
892
@test -f update-deps.py || { echo " ❌ update-deps.py not found in root directory." ; exit 1; }
846
- @/bin/bash -c " source $( VENV_DIR) /bin/activate && python update-deps.py"
893
+ @/bin/bash -c " source $( VENV_DIR) /bin/activate && python3 update-deps.py"
847
894
@echo " ✅ Dependencies updated in pyproject.toml and docs/requirements.txt"
848
895
849
896
containerfile-update :
@@ -2090,7 +2137,7 @@ devpi-unconfigure-pip:
2090
2137
# 📦 Version helper (defaults to the version in pyproject.toml)
2091
2138
# override on the CLI: make VER=0.2.1 devpi-delete
2092
2139
# ─────────────────────────────────────────────────────────────────────────────
2093
- VER ?= $(shell python -c "import tomllib, pathlib; \
2140
+ VER ?= $(shell python3 -c "import tomllib, pathlib; \
2094
2141
print(tomllib.loads(pathlib.Path('pyproject.toml') .read_text())['project']['version'])" \
2095
2142
2>/dev/null || echo 0.0.0)
2096
2143
0 commit comments