-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.pre-commit-config.yaml
More file actions
401 lines (382 loc) · 14.9 KB
/
Copy path.pre-commit-config.yaml
File metadata and controls
401 lines (382 loc) · 14.9 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
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# Pre-commit hooks configuration for SAGE project
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
#
# Usage:
# - Install pre-commit: pip install pre-commit
# - Install hooks: pre-commit install --config .pre-commit-config.yaml
# - Run manually: pre-commit run --all-files --config .pre-commit-config.yaml
#
default_language_version:
python: python3.11
repos:
# General file checks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
exclude: '(\.svg$|ThirdParty/|thirdparty/)'
- id: end-of-file-fixer
exclude: '(\.svg$|ThirdParty/|thirdparty/)'
- id: check-yaml
args: [--unsafe] # Allow custom YAML tags
exclude: ^(.*/benchmark_anns/|ThirdParty/|thirdparty/|.*/implementations/(SPTAG|faiss|DiskANN)/)
- id: check-json
exclude: "(ThirdParty/|thirdparty/)"
- id: check-toml
exclude: "(ThirdParty/|thirdparty/)"
- id: check-added-large-files
args: ["--maxkb=1000"]
exclude: "(ThirdParty/|thirdparty/)"
- id: check-merge-conflict
exclude: "(ThirdParty/|thirdparty/)"
- id: check-case-conflict
exclude: ^(.*/benchmark_(libamm|db)/|.*/vendors/|.*/build/|ThirdParty/|thirdparty/)
- id: mixed-line-ending
args: [--fix=lf]
exclude: "(ThirdParty/|thirdparty/)"
- id: detect-private-key
exclude: "(ThirdParty/|thirdparty/)"
# Python: Black formatter (DISABLED - using ruff format instead)
# Black and ruff format can conflict in edge cases, causing infinite reformatting
# Ruff format is now mature enough to replace Black completely
# - repo: https://github.com/psf/black
# rev: 25.9.0
# hooks:
# - id: black
# language_version: python3.11
# args: [--line-length=100]
# exclude: ^(docs/|examples/data/|.*/vendors/|.*/build/)
# Python: isort import sorting
# - repo: https://github.com/pycqa/isort
# rev: 7.0.0
# hooks:
# - id: isort
# args: [--profile=black, --line-length=100]
# exclude: ^(docs/|examples/data/|.*/vendors/|.*/build/)
#
# Python: Ruff linter and formatter (replaces flake8, isort, pyupgrade)
# NOTE: Using local/system ruff to avoid network download failures
# Requires: ruff is available in PATH (installed via pip in the active env)
- repo: local
hooks:
- id: ruff
name: ruff check
language: system
entry: ruff
args: [check, --fix, --exit-non-zero-on-fix, --config, tools/ruff.toml]
types: [python]
exclude: ^(docs/|examples/data/|tests/fixtures/|.*/benchmark_(libamm|db)/|.*/vendors/|.*/build/|ThirdParty/|thirdparty/|.*/implementations/(SPTAG|faiss|DiskANN|diskann-ms|candy|puck|pybind11)/)
- id: ruff-format
name: ruff format
language: system
entry: ruff
args: [format, --config, tools/ruff.toml]
types: [python]
exclude: ^(docs/|examples/data/|tests/fixtures/|.*/benchmark_(libamm|db)/|.*/vendors/|.*/build/|ThirdParty/|thirdparty/|.*/implementations/(SPTAG|faiss|DiskANN|diskann-ms|candy|puck|pybind11)/)
- repo: local
hooks:
- id: meta-dependency-audit-gate
name: check isage meta dependency audit evidence
entry: python3 tools/scripts/check_meta_dependency_audit.py --enforce-change-evidence --staged
language: system
pass_filenames: false
always_run: false
stages: [pre-commit, manual]
files: ^pyproject.toml$|^docs/dependency-audit-gate\.md$
- id: architecture-violation-check
name: check architecture violations (directory placement)
entry: tools/maintenance/checks/pre-commit-architecture.sh
language: system
pass_filenames: false
always_run: false
stages: [pre-commit]
- id: release-tools-boundary-check
name: check release package vs tools boundary
entry: python3 tools/maintenance/checks/check_release_tools_boundary.py
language: system
pass_filenames: false
always_run: false
stages: [pre-commit, manual]
files: ^(src/sage/(foundation|runtime|stream|serving|edge)/|tools/|quickstart\.sh|manage\.sh|\.pre-commit-config\.yaml)$
# Check for files in wrong locations under the current meta-repo layout
# - id: dependency-version-conflicts
# name: check dependency version conflicts
# entry: python3 tools/install/helpers/unify_dependencies.py --check
# language: system
# pass_filenames: false
# always_run: false
# files: ^pyproject\.toml$
# # DEPRECATED: Script removed, dependency management moved to sage-tools
- id: pep420-namespace-compliance
name: PEP 420 namespace package compliance check
entry: bash -c 'tools/scripts/validate_pep420_compliance.sh'
language: system
pass_filenames: false
always_run: false
files: ^src/sage/__init__\.py$
# Block commit if src/sage/__init__.py is added/modified (violates PEP 420)
- id: cross-repo-dedup-check
name: cross-repo duplicate declaration check (SAGE vs sageFlownet)
entry: python3 tools/scripts/check_cross_repo_dedup.py
language: system
pass_filenames: false
always_run: false
stages: [pre-commit, manual]
files: \.py$
# Enforces move-then-delete rule: migrated symbols must not be redefined in Flownet.
# See Issue #1439 and flownet-migration-boundary.md
- id: markdown-files-location-check
name: check markdown files are in proper locations
entry: tools/maintenance/checks/check_docs_location.sh
language: system
pass_filenames: false
always_run: false
files: \.md$
# - id: control-plane-only-guard
# name: prevent embedded/local inference paths
# entry: tools/maintenance/checks/check_control_plane_only.py
# language: system
# pass_filenames: false
# always_run: false
# files: \.py$
# # DEPRECATED: Script removed, control plane checks moved to sage-tools
- id: python-test-files-location-check
name: check Python test files are in proper locations
entry: bash -c
args:
- |
# Get all Python test files (staged if in commit, or all files if --all-files)
if [ -n "$PRE_COMMIT_FROM_REF" ] && [ -n "$PRE_COMMIT_TO_REF" ]; then
# Running with --all-files or during push
all_test_files=$(git ls-files "*.py" | grep -E "(^|/)test_.*\.py$|_test\.py$|tests\.py$" || true)
else
# Running in normal commit mode
all_test_files=$(git diff --cached --name-only --diff-filter=ACM | grep "\.py$" | grep -E "(^|/)test_.*\.py$|_test\.py$|tests\.py$" || true)
fi
if [ -z "$all_test_files" ]; then
exit 0
fi
# Define disallowed patterns (blacklist for test files)
violations=""
for file in $all_test_files; do
# Test files should be in tests/, src/tests/, or test scripts in examples/
if echo "$file" | grep -qE "^(tests/|src/tests/|examples/.*/tests?\.py$|examples/.*test.*\.py$)"; then
# Allowed location
continue
else
# Disallowed location
violations="$violations$file\n"
fi
done
# Report violations
if [ -n "$violations" ]; then
echo "❌ 错误: 以下测试文件不在正确的位置:"
echo -e "$violations" | sed "s/^/ - /"
echo ""
echo "📁 测试文件应该放在:"
echo " - tests/ - 单元测试和集成测试"
echo " - src/tests/ - 主仓当前测试路径(由 pytest.ini 配置)"
echo " - tests/unit/ - 单元测试"
echo " - tests/integration/ - 集成测试"
echo " - tests/manual/ - 手动测试脚本"
echo " - examples/ - 示例和演示脚本(可以包含 test 名称)"
echo ""
echo "💡 建议: 请将测试文件移动到仓库的 tests/ 目录"
exit 1
else
exit 0
fi
language: system
pass_filenames: false
always_run: false
files: \.py$
- id: installation-consistency-check
name: installation consistency check (local vs CI/CD)
entry: bash tools/install/checks/installation_consistency_check.sh
language: system
pass_filenames: false
# 仅在修改安装相关文件时运行
files: ^(quickstart\.sh|tools/install/.*\.sh|pyproject\.toml|setup\.py|\.github/workflows/.*\.yml)$
# 也在手动运行 pre-commit run --all-files 时执行
stages: [pre-commit, manual]
- id: root-directory-cleanup-check
name: check for unwanted files/directories in project root
entry: bash -c
args:
- |
# Whitelist mode: Only allow known files/directories in project root
# Any unexpected item will trigger a warning
# Allowed files in project root (whitelist)
allowed_files=(
".env"
".env.template"
".github_token"
".gitignore"
".pre-commit-config.yaml"
".pypirc"
".pyrightconfig.json"
".secrets.baseline"
"codecov.yml"
"CONTRIBUTING.md"
"coverage.xml"
"DEVELOPER.md"
"LICENSE"
"Makefile"
"manage.sh"
"pytest.ini"
"quickstart.sh"
"README.md"
"CHANGELOG.md"
"dependencies-spec.yaml"
"tasks.md"
"SAGE.code-workspace"
"SAGE_ZOO.md"
"pyproject.toml" # isage meta-package
)
# Allowed directories in project root (whitelist)
allowed_dirs=(
".benchmarks" # Deprecated; keep for legacy benchmark artifacts
".git"
".github"
".mypy_cache" # mypy cache (temporary; should use .sage/cache/mypy)
".pytest_cache"
".ruff_cache"
".sage"
".vscode"
"benchmark" # Dedicated benchmark workspace in repo root
"build"
"config"
"dist"
"docker"
# "docs" # Root docs/ for meta-package (layer-manifest.json, dependency-audit-gate.md)
"docs"
"examples"
"htmlcov"
"src" # isage meta-package source (src/sage/_version.py)
"data"
"tools"
"hooks"
)
violations=""
# Check all items in project root
for item in * .*; do
# Skip . and ..
[ "$item" = "." ] || [ "$item" = ".." ] && continue
# Skip if item doesn't exist (glob didn't match)
[ -e "$item" ] || continue
allowed=false
if [ -d "$item" ]; then
# Check directories
for allowed_dir in "${allowed_dirs[@]}"; do
if [ "$item" = "$allowed_dir" ]; then
allowed=true
break
fi
done
else
# Check files
for allowed_file in "${allowed_files[@]}"; do
if [ "$item" = "$allowed_file" ]; then
allowed=true
break
fi
done
fi
if [ "$allowed" = false ]; then
violations="$violations$item\n"
fi
done
if [ -n "$violations" ]; then
echo "⚠️ 警告: 项目根目录下存在未授权的文件/目录:"
echo -e "$violations" | grep -v "^$" | sed "s/^/ - /"
echo ""
echo "📁 可能的原因:"
echo " - 运行脚本/测试时错误创建的临时目录"
echo " - 临时文件未清理"
echo ""
echo "💡 建议:"
echo " - 临时文件应放在 .sage/ 目录下"
echo " - 如果是新增的合法文件/目录,请更新 .pre-commit-config.yaml 中的白名单"
echo ""
echo "📖 参考: DEVELOPER.md"
exit 1
fi
exit 0
language: system
pass_filenames: false
always_run: true
stages: [pre-commit, manual]
# Shell: shellcheck
# NOTE: Using local/system shellcheck to avoid network download failures
# (shellcheck-py downloads the binary at install time, which fails behind proxies/firewalls)
# Requires: shellcheck is available in PATH (e.g. installed via conda or apt)
- repo: local
hooks:
- id: shellcheck
name: shellcheck
language: system
entry: shellcheck
args: [-x, -e, SC1091, -S, error] # -x: follow sources, -e SC1091: ignore source errors, -S error: only fail on errors
files: \.(sh|bash)$
exclude: ^(tools/install/conda/|.*/benchmark_anns/|ThirdParty/|thirdparty/|.*/implementations/(SPTAG|faiss|DiskANN|diskann-ms|candy|puck|pybind11)/)
# YAML formatting
# NOTE: Using local/system pretty-format-yaml to avoid network download failures
# Requires: language-formatters-pre-commit-hooks is installed via pip
- repo: local
hooks:
- id: pretty-format-yaml
name: pretty-format-yaml
language: system
entry: pretty-format-yaml
args: [--autofix, --indent=2, --preserve-quotes]
types: [yaml]
exclude: ^(\.github/|examples/config/|.*/benchmark_anns/|ThirdParty/|thirdparty/|.*/implementations/(SPTAG|faiss|DiskANN|diskann-ms|candy|puck|pybind11)/)
# Markdown formatting
# NOTE: Using local/system mdformat to avoid network download failures
# Requires: mdformat + mdformat-gfm installed via pip
- repo: local
hooks:
- id: mdformat
name: mdformat
language: system
entry: mdformat
args: [--wrap=100]
types: [markdown]
exclude: ^(CHANGELOG.md|\.github/)
# Security: Check for secrets
# NOTE: Using local/system detect-secrets to avoid network download failures
# Requires: detect-secrets installed via pip
- repo: local
hooks:
- id: detect-secrets
name: detect-secrets
language: system
entry: detect-secrets-hook
args: [--baseline, .secrets.baseline]
exclude: ^(\.secrets\.baseline|\.env\.template|\.github/workflows/|examples/config/.*\.yaml|tests/fixtures/|.*package-lock\.json$|.*\.ipynb$|docs/.*\.md$|examples/.*\.py$|.*\.html$|.*/benchmark_anns/|ThirdParty/|thirdparty/|.*/implementations/(SPTAG|faiss|DiskANN|diskann-ms|candy|puck|pybind11)/)
# SAGE Data Architecture Validation - REMOVED (sage-benchmark is now independent)
# See: https://github.com/intellistream/sage-benchmark
- repo: local
hooks:
- id: copilot-instructions-sync-check
name: check copilot-instructions and my-agent sync
entry: bash tools/maintenance/checks/check_copilot_instructions_sync.sh
language: system
pass_filenames: false
# Trigger on: doc files, installation scripts, CI/CD, config, ports, CLI, LLM/Gateway
files: ^(\.github/(copilot-instructions\.md|agents/my-agent\.agent\.md|workflows/.*\.yml)|quickstart\.sh|manage\.sh|Makefile|pyproject\.toml|(\.pre-commit-config\.yaml|tools/ruff\.toml|tools/install/.*\.sh)|config/(config|cluster)\.yaml)
stages: [pre-commit, manual]
description: Warn if critical project files change without updating copilot instructions
# To install pre-commit hooks:
# pre-commit install
#
# To run manually:
# pre-commit run --all-files
#
# To update hook versions:
# pre-commit autoupdate
#
# To skip hooks temporarily:
# git commit --no-verify