Files
docs/Makefile
T

172 lines
8.3 KiB
Makefile

.PHONY: all dev build export format lint test install clean lint_md lint_md_fix lint_prose broken-links broken-links-with-anchors format-check code-snippets test-code-samples check-cross-refs
# Default target
all: help
dev:
@echo "Starting development mode..."
npm install
PYTHONPATH=$(CURDIR) uv run pipeline dev
build:
@echo "Building documentation..."
npm install
PYTHONPATH=$(CURDIR) uv run pipeline build
# Offline zip via Mintlify (https://www.mintlify.com/docs/deploy/export).
# Must run from build/: docs.json paths are oss/python/... and oss/javascript/... but sources live under src/oss/... until the pipeline emits build/oss/{python,javascript}/...
# Example: make export MINT_EXPORT_ARGS='--output ../langchain-docs-export.zip'
export: build
@command -v mint >/dev/null 2>&1 || { echo "Error: mint not installed. Run: npm install -g mint@latest"; exit 1; }
@cd build && mint export $(MINT_EXPORT_ARGS)
# Define a variable for the test file path.
TEST_FILE ?= tests/unit_tests
# Define a variable for Python and notebook files.
PYTHON_FILES=.
lint:
uv run ruff format $(PYTHON_FILES) --diff
uv run ruff check $(PYTHON_FILES) --diff
uv run ty check
uv run codespell src
format:
uv run ruff format $(PYTHON_FILES)
uv run ruff check --fix $(PYTHON_FILES)
# Check formatting without applying changes (for CI)
format-check:
uv run ruff format $(PYTHON_FILES) --check --diff
uv run ruff check $(PYTHON_FILES)
lint_md:
@echo "Linting markdown files..."
@if command -v markdownlint >/dev/null 2>&1; then \
find src -name "*.md" -o -name "*.mdx" | xargs markdownlint; \
else \
echo "markdownlint not found. Install with: npm install -g markdownlint-cli or VSCode extension"; \
exit 1; \
fi
lint_md_fix:
@echo "Linting and fixing markdown files..."
@if command -v markdownlint >/dev/null 2>&1; then \
find src -name "*.md" -o -name "*.mdx" | xargs markdownlint --fix; \
else \
echo "markdownlint not found. Install with: npm install -g markdownlint-cli or VSCode extension"; \
exit 1; \
fi
lint_prose:
@echo "Linting prose with Vale..."
@command -v vale >/dev/null 2>&1 || { echo "Installing Vale for prose linting..."; brew install vale; }
@if [ -n "$(FILES)" ]; then \
vale --glob='!**/node_modules/**' $(FILES); \
else \
vale --glob='!**/node_modules/**' src/; \
fi
test:
uv run pytest --disable-socket --allow-unix-socket $(TEST_FILE) -vv
install:
@echo "Installing all dependencies"
uv sync --all-groups
npm install
npm install -g mint@latest
@echo "If the docs command is not available, relaunch your shell so it picks up the docs binary."
clean:
@echo "Cleaning build artifacts..."
@rm -rf build/
@rm -rf __pycache__/
@find . -name "*.pyc" -delete
@find . -name "*.pyo" -delete
@find . -name "*.pyd" -delete
@find . -name "__pycache__" -type d -exec rm -rf {} +
# Mintlify commands (run from build directory where final docs are generated)
# broken-links: Checks for broken links, excluding OpenAPI-generated pages and snippet files
# (snippets use relative paths that resolve when inlined; /oss/langchain/agents uses redirect)
# Excluded: /langsmith/agent-server-api/, /api-reference/ (Mintlify-generated at deploy, not in local build)
# Excluded: ../langchain/agents, ../langgraph/local-server (snippet preprocessing: /oss/... → relative path, resolves when inlined)
# python3 normalizes U+00A0 (NBSP) to space so grep works on both macOS and Linux ([[:space:]] treats NBSP differently by locale)
# Failure: only when filtered output still has indented link lines (real broken links we care about)
# Run mint, capture output, filter exclusions. Only show output when failing.
broken-links: build
@command -v mint >/dev/null 2>&1 || { echo "Error: mint not installed. Run 'npm install -g mint@latest'"; exit 1; }
@KATEX_MJS="$$(npm root -g 2>/dev/null)/mint/node_modules/katex/dist/katex.mjs"; \
if [ -f "$$KATEX_MJS" ] && grep -q '__VERSION__' "$$KATEX_MJS" 2>/dev/null; then \
KATEX_DIR="$$(cd "$$(dirname "$$KATEX_MJS")/.." && pwd)"; \
VERSION=$$(node -e "console.log(require('$$KATEX_DIR/package.json').version)" 2>/dev/null); \
if [ -n "$$VERSION" ]; then sed -i.bak "s/__VERSION__/\"$$VERSION\"/g" "$$KATEX_MJS" 2>/dev/null || true; fi; \
fi
@cd build && mint broken-links 2>&1 | tee /tmp/broken-links.txt > /dev/null; \
filtered=$$(grep -v '/langsmith/agent-server-api/' /tmp/broken-links.txt | grep -v '/langsmith/smith-api' | grep -v '/api-reference/' | grep -v '\.\./langchain/agents' | grep -v '\.\./langgraph/local-server' | python3 -c "import sys; sys.stdout.write(sys.stdin.read().replace('\u00a0', ' '))"); \
if echo "$$filtered" | grep -qE '^[[:space:]]+[^[:space:]]'; then \
echo "$$filtered"; echo ""; echo "❌ Broken links found"; exit 1; \
else \
echo "✅ No broken links"; \
fi
broken-links-with-anchors: build
@command -v mint >/dev/null 2>&1 || { echo "Error: mint not installed. Run 'npm install -g mint@latest'"; exit 1; }
@KATEX_MJS="$$(npm root -g 2>/dev/null)/mint/node_modules/katex/dist/katex.mjs"; \
if [ -f "$$KATEX_MJS" ] && grep -q '__VERSION__' "$$KATEX_MJS" 2>/dev/null; then \
KATEX_DIR="$$(cd "$$(dirname "$$KATEX_MJS")/.." && pwd)"; \
VERSION=$$(node -e "console.log(require('$$KATEX_DIR/package.json').version)" 2>/dev/null); \
if [ -n "$$VERSION" ]; then sed -i.bak "s/__VERSION__/\"$$VERSION\"/g" "$$KATEX_MJS" 2>/dev/null || true; fi; \
fi
@cd build && mint broken-links --check-anchors 2>&1 | tee /tmp/broken-links.txt > /dev/null; \
filtered=$$(grep -v '/langsmith/agent-server-api/' /tmp/broken-links.txt | grep -v '/langsmith/smith-api' | grep -v '/api-reference/' | grep -v '\.\./langchain/agents' | grep -v '\.\./langgraph/local-server' | grep -vE '/langsmith/smithdb-sdk-migration#(traces-query|runs-query|exceptions)$$' | python3 -c "import sys; sys.stdout.write(sys.stdin.read().replace('\u00a0', ' '))"); \
if echo "$$filtered" | grep -qE '^[[:space:]]+[^[:space:]]'; then \
echo "$$filtered"; echo ""; echo "❌ Broken links found"; exit 1; \
else \
echo "✅ No broken links"; \
fi
check-openapi: build
@echo "Checking openapi spec validity"
@command -v mint >/dev/null 2>&1 || { echo "Error: mint is not installed. Run 'npm install -g mint@latest'"; exit 1; }
@cd build && output=$$(mint openapi-check langsmith/agent-server-openapi.json) && echo "$$output"
# Extract code snippets from src/code-samples (line-based, Bluehawk-compatible tags)
code-snippets:
@echo "Extracting code snippets..."
@mkdir -p src/code-samples-generated
@PYTHONPATH=$(CURDIR) python scripts/extract_code_snippets.py
@PYTHONPATH=$(CURDIR) python scripts/generate_code_snippet_mdx.py
# Run code samples. By default runs all; pass FILES to test specific paths.
# make test-code-samples
# make test-code-samples FILES="src/code-samples/langchain/return-a-string.py"
test-code-samples:
@if [ -f src/code-samples/package.json ]; then (cd src/code-samples && npm install --silent); fi
@FILES="$(FILES)" PYTHONPATH=$(CURDIR) python scripts/test_code_samples.py
# Check that all @[ref] cross-references in source files resolve against link_map.py
check-cross-refs:
@PYTHONPATH=$(CURDIR) uv run python scripts/check_cross_refs.py
help:
@echo "Available commands:"
@echo " make dev - Start development mode with file watching and mint dev"
@echo " make build - Build documentation to ./build directory"
@echo " make export - Run mint export from ./build (optional: MINT_EXPORT_ARGS)"
@echo " make broken-links - Check for broken links in built documentation"
@echo " make check-cross-refs - Check for unresolved @[ref] cross-references"
@echo " make broken-links-with-anchors - Same as above, also validates anchor links"
@echo " make format - Format code"
@echo " make lint - Lint code"
@echo " make lint_md - Lint markdown files"
@echo " make lint_md_fix - Lint and fix markdown files"
@echo " make lint_prose - Lint prose with Vale (terminology, style)"
@echo " make test - Run tests"
@echo " make install - Install dependencies"
@echo " make code-snippets - Extract code snippets (line-based, Bluehawk-compatible)"
@echo " make test-code-samples - Run code samples (FILES=\"path ...\" for specific)"
@echo " make clean - Clean build artifacts"
@echo " make help - Show this help message"