forked from langchain-ai/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
223 lines (196 loc) Β· 10.7 KB
/
Copy pathMakefile
File metadata and controls
223 lines (196 loc) Β· 10.7 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
.PHONY: all dev build export htmltest export-htmltest format lint test install install_vale 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}/...
# Default mint output when run from build/ is build/export.zip. Override with MINT_EXPORT_ARGS='--output other.zip' (path relative to build/) and matching EXPORT_ZIP=build/other.zip for htmltest.
# Requires: recent mint CLI (mint export), Node LTS 20/22 (Node 25+ unsupported), Enterprise Mintlify plan.
export: build
@command -v mint >/dev/null 2>&1 || { echo "Error: mint not installed. Run: npm install -g mint@latest"; exit 1; }
@mint help 2>&1 | grep -q 'mint export' || { \
echo "Error: 'mint export' is missing from mint $$(mint --version 2>/dev/null || echo unknown)."; \
echo "Upgrade: npm install -g mint@latest"; \
echo "Also needs Node LTS (20 or 22; Node 25 is unsupported) and an Enterprise Mintlify plan."; \
exit 1; \
}
@NODE_MAJOR=$$(node -p "process.versions.node.split('.')[0]"); \
if [ "$$NODE_MAJOR" -ge 25 ]; then \
echo "Error: mint does not support Node $$NODE_MAJOR. Switch to Node 20 or 22 (e.g. nvm use 22), install mint for that Node (npm install -g mint@latest), then retry."; \
exit 1; \
fi
@cd build && mint export $(MINT_EXPORT_ARGS)
# Zip produced by make export (default Mintlify name: export.zip in build/). Override if you used --output.
EXPORT_ZIP ?= build/export.zip
# Unpacked copy for htmltest (gitignored under build/).
HTMLTEST_UNPACK_DIR ?= build/mint-export-htmltest-unpacked
# Extra htmltest CLI flags (config already checks external URLs only). Example: HTMLTEST_ARGS='-l 1'
HTMLTEST_ARGS ?=
# Unzip EXPORT_ZIP and run htmltest (https://github.com/wjdp/htmltest). Run after make export.
# Uses htmltest-mint-export.yml: external URLs only (mint export omits many pages, so internals are noisy).
htmltest:
@command -v htmltest >/dev/null 2>&1 || { echo "Error: htmltest not found. Install: brew install htmltest OR curl https://htmltest.wjdp.uk | sudo bash -s -- -b /usr/local/bin"; exit 1; }
@command -v unzip >/dev/null 2>&1 || { echo "Error: unzip not found."; exit 1; }
@test -f $(EXPORT_ZIP) || { echo "Error: $(EXPORT_ZIP) not found. Run make export first, or set EXPORT_ZIP to your mint export zip path."; exit 1; }
mkdir -p $(HTMLTEST_UNPACK_DIR)
unzip -q -o $(EXPORT_ZIP) -d $(HTMLTEST_UNPACK_DIR)
@bash -ec 'ROOT="$(HTMLTEST_UNPACK_DIR)"; \
COUNT=$$(find "$$ROOT" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l | tr -d " "); \
if [ "$$COUNT" -eq 1 ]; then \
ONLY=$$(find "$$ROOT" -mindepth 1 -maxdepth 1 2>/dev/null | head -n 1); \
if [ -d "$$ONLY" ]; then ROOT="$$ONLY"; fi; \
fi; \
echo "htmltest root: $$ROOT"; \
htmltest $(HTMLTEST_ARGS) -c "$(CURDIR)/htmltest-mint-export.yml" "$$ROOT"'
# make export then make htmltest (sequential; use this for a one-shot check).
export-htmltest:
@$(MAKE) export
@$(MAKE) htmltest
# 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
VALE_BIN ?= .bin/vale
# Single source of truth for the Vale pin is .mise.toml. Override on the
# command line only for a one-off test: make lint_prose VALE_VERSION=3.16.0
VALE_VERSION ?= $(shell sed -n 's/^[[:space:]]*vale[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' .mise.toml | head -n 1)
install_vale:
@bash scripts/install-vale.sh "$(VALE_BIN)" "$(VALE_VERSION)"
lint_prose:
@echo "Linting prose with Vale..."
@bash scripts/install-vale.sh "$(VALE_BIN)" "$(VALE_VERSION)"
@if [ -n "$(FILES)" ]; then \
"$(VALE_BIN)" --glob='!{**/node_modules/**,src/code-samples/**}' $(FILES); \
else \
"$(VALE_BIN)" --glob='!{**/node_modules/**,src/code-samples/**}' 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
# Excluded: /langsmith/agent-server-api/, /api-reference/ (Mintlify-generated at deploy, not in local build)
# Excluded: entire snippets/ report sections (scripts/filter_mint_broken_links.py)
# Snippet /oss/ links are absolute language-prefixed paths under
# build/snippets/{python|javascript}/...; mint checks snippets as standalone files
# so those look broken until inlined into a page.
# 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=$$(python3 ../scripts/filter_mint_broken_links.py --input /tmp/broken-links.txt); \
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=$$(python3 ../scripts/filter_mint_broken_links.py --check-anchors --input /tmp/broken-links.txt); \
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 htmltest - Unzip EXPORT_ZIP, run htmltest on external URLs only (HTMLTEST_ARGS)"
@echo " make export-htmltest - make export then make htmltest"
@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"