From d20c36371a428a17f8d64178a80f373db24accfd Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Mon, 16 Feb 2026 20:00:43 +0200 Subject: [PATCH] docs: add AI Coding Guide for cpp-linter-hooks --- .github/copilot-instructions.md | 113 ++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..1810369 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,113 @@ +# cpp-linter-hooks AI Coding Guide + +## Project Overview +Pre-commit hooks wrapper that auto-installs and runs clang-format and clang-tidy from Python wheels. Supports Python 3.9-3.14 across Windows, Linux, and macOS. + +## Architecture + +### Entry Points & Flow +- **Entry scripts**: `clang-format-hook` and `clang-tidy-hook` (defined in `pyproject.toml`) +- **Hook definitions**: `.pre-commit-hooks.yaml` configures both hooks with `types_or: [c++, c]` +- **Execution pattern**: Parse args → resolve/install tool version → subprocess.run → return (exit_code, output) + +### Core Modules +- **`clang_format.py`**: Wraps clang-format with `-i` (in-place), supports `--verbose` and `--dry-run` modes + - Returns `-1` for dry-run to distinguish from actual failures +- **`clang_tidy.py`**: Wraps clang-tidy, forces exit code 1 if "warning:" or "error:" in output +- **`util.py`**: Version resolution and pip-based tool installation + - `_resolve_version()`: Supports partial matches (e.g., "20" → "20.1.7") + - `DEFAULT_CLANG_FORMAT_VERSION` and `DEFAULT_CLANG_TIDY_VERSION` read from `pyproject.toml` +- **`versions.py`**: Auto-generated by `scripts/update_versions.py` (runs weekly via GitHub Actions) + +### Version Management Pattern +```python +# Users can specify partial versions +--version=21 # Resolves to latest 21.x.x +--version=21.1 # Resolves to latest 21.1.x +--version=21.1.8 # Exact version +``` + +## Development Workflows + +### Local Testing +```bash +# Test hooks locally without installing +pre-commit try-repo ./.. clang-format --verbose --all-files +pre-commit try-repo ./.. clang-tidy --verbose --all-files + +# Run test suite +uv run pytest -vv # All tests +uv run coverage run -m pytest # With coverage +uv run pytest -m benchmark # Performance tests only +``` + +### Adding/Modifying Features +1. **Update hook logic** in `cpp_linter_hooks/{clang_format,clang_tidy}.py` +2. **Add tests** in `tests/test_*.py` with `@pytest.mark.benchmark` for performance tracking +3. **Test with sample files** in `testing/` directory (use `good.c` as expected output) +4. **Update README.md** if user-facing behavior changes + +### Dependency Management +- **Uses `uv`** for all dev operations (not pip directly) +- **Pin versions**: Default tool versions in `pyproject.toml` dependencies section +- **Update versions**: Run `python scripts/update_versions.py` (auto-runs weekly on Monday 2 AM UTC) + +## Project-Specific Conventions + +### Return Value Pattern +All hook functions return `Tuple[int, str]`: +- `(0, "")` → Success +- `(1, output)` → Failure (print output) +- `(-1, output)` → Dry-run mode (clang-format only, convert to success in main) + +### Testing Conventions +- Use `tmp_path` fixture to avoid modifying repo files +- Parametrize version tests: `@pytest.mark.parametrize` with versions 16-21 +- Mark performance-sensitive tests with `@pytest.mark.benchmark` +- Compare formatted output against `testing/good.c` for correctness + +### Argument Handling +```python +# Standard pattern in both hooks +parser = ArgumentParser() +parser.add_argument("--version", default=DEFAULT_VERSION) +hook_args, other_args = parser.parse_known_args(args) +# ... install tool if needed ... +command = ["tool-name"] + other_args # Pass through unknown args +``` + +## Critical Files + +- **`pyproject.toml`**: Defines entry points, dependencies, default versions +- **`versions.py`**: Auto-updated; DO NOT edit manually (see comment) +- **`.pre-commit-hooks.yaml`**: Hook metadata for pre-commit framework +- **`testing/run.sh`**: Integration test script used in CI + +## Integration Points + +### PyPI Dependencies +- Fetches available versions from `https://pypi.org/pypi/{package}/json` +- Filters out pre-release versions using regex pattern `(alpha|beta|rc|dev|a\d+|b\d+)` +- Installs via `subprocess.run([sys.executable, "-m", "pip", "install", f"{tool}=={version}"])` + +### Pre-commit Framework +- Hooks run in parallel (`require_serial: false`) for performance +- File type filtering via `types_or: [c++, c]` +- Users configure via `.pre-commit-config.yaml` with `args:` list + +## Common Tasks + +**Add support for a new argument:** +1. Add to ArgumentParser in hook module +2. Pass to subprocess command or handle in Python +3. Add test case in `tests/test_*.py` + +**Update default tool versions:** +1. Edit `dependencies` in `pyproject.toml` +2. Run tests to ensure compatibility +3. Update version in README examples + +**Debug hook failures:** +- Add `--verbose` to clang-format args for detailed output +- Check `testing/run.sh` for integration test patterns +- Use `pre-commit run --verbose` for detailed pre-commit logs