|
1 | 1 | # Global Copilot Instructions |
2 | 2 |
|
3 | | -* Prioritize **minimal scope**: only edit code directly implicated by the failing test. |
| 3 | +* Prioritize **minimal scope**: only edit code directly implicated by the failing test. |
4 | 4 | * Protect existing functionality: do **not** delete or refactor code outside the immediate test context. |
5 | 5 | * Before deleting any code, follow the "Coverage & Code Safety" guidelines below. |
6 | 6 |
|
7 | 7 | Copilot, do not modify any files under .lad/. |
8 | 8 | All edits must occur outside .lad/, or in prompts/ when explicitly updating LAD itself. |
9 | 9 |
|
10 | 10 | Coding & formatting |
11 | | -* Follow PEP 8; run Black. |
| 11 | +* Follow PEP 8; formatting enforced by pre-commit hooks (black, isort). |
12 | 12 | * Use type hints everywhere. |
13 | | -* External dependencies limited to numpy, pandas, requests. |
14 | | -* Target Python 3.11. |
| 13 | +* Respect existing project dependencies declared in pyproject.toml. |
15 | 14 |
|
16 | 15 | Testing & linting |
17 | | -* Write tests using component-appropriate strategy (see Testing Strategy below). |
18 | | -* Run flake8 with `--max-complexity=10`; keep complexity ≤ 10. |
| 16 | +* Write tests using pytest; run via `tox -e py3` or `python -m pytest dandi`. |
| 17 | +* Tests requiring the DANDI archive use Docker Compose fixtures. |
| 18 | +* Mark AI-generated tests with `@pytest.mark.ai_generated`. |
19 | 19 | * Every function/class **must** include a **NumPy-style docstring** (Sections: Parameters, Returns, Raises, Examples). |
20 | 20 |
|
21 | 21 | ## Testing Strategy by Component Type |
22 | 22 |
|
23 | | -**API Endpoints & Web Services:** |
24 | | -* Use **integration testing** - import the real FastAPI/Django/Flask app |
25 | | -* Mock only external dependencies (databases, external APIs, file systems) |
26 | | -* Test actual HTTP routing, validation, serialization, and error handling |
27 | | -* Verify real request/response behavior and framework integration |
| 23 | +**CLI Commands:** |
| 24 | +* Use click's `CliRunner` for testing CLI entry points |
| 25 | +* Test argument parsing, output formatting, and error messages |
| 26 | +* Mock API calls and filesystem where appropriate |
28 | 27 |
|
29 | | -**Business Logic & Algorithms:** |
30 | | -* Use **unit testing** - mock all dependencies completely |
31 | | -* Test logic in complete isolation, focus on edge cases |
32 | | -* Maximize test speed and reliability |
33 | | -* Test pure business logic without framework concerns |
| 28 | +**API Client Operations (upload, download, move, etc.):** |
| 29 | +* Use **integration testing** with Docker Compose fixtures for archive interactions |
| 30 | +* Mock only external services not under test |
| 31 | +* Test actual HTTP interactions, authentication, and error handling |
34 | 32 |
|
35 | | -**Data Processing & Utilities:** |
| 33 | +**File Processing & Utilities:** |
36 | 34 | * Use **unit testing** with minimal dependencies |
37 | | -* Use test data fixtures for predictable inputs |
| 35 | +* Use test data fixtures (tmp_path, simple NWB files) for predictable inputs |
38 | 36 | * Focus on input/output correctness and error handling |
39 | 37 |
|
40 | 38 | ## Regression Prevention |
41 | 39 |
|
42 | 40 | **Before making changes:** |
43 | | -* Run full test suite to establish baseline: `pytest -q --tb=short` |
| 41 | +* Run full test suite to establish baseline: `tox -e py3` or `python -m pytest dandi` |
44 | 42 | * Identify dependencies: `grep -r "function_name" . --include="*.py"` |
45 | 43 | * Understand impact scope before modifications |
46 | 44 |
|
47 | 45 | **During development:** |
48 | | -* Run affected tests after each change: `pytest -q tests/test_modified_module.py` |
| 46 | +* Run affected tests after each change: `python -m pytest dandi/tests/test_modified_module.py` |
49 | 47 | * Preserve public API interfaces or update all callers |
50 | 48 | * Make minimal changes focused on the failing test |
51 | 49 |
|
52 | 50 | **Before commit:** |
53 | | -* Run full test suite: `pytest -q --tb=short` |
| 51 | +* Run full test suite: `tox -e py3` |
54 | 52 | * Verify no regressions introduced |
55 | 53 | * Ensure test coverage maintained or improved |
56 | 54 |
|
57 | | -## Code Quality Setup (One-time per project) |
| 55 | +## Code Quality Setup |
58 | 56 |
|
59 | | -**1. Install quality tools:** |
60 | | -```bash |
61 | | -pip install flake8 pytest coverage radon flake8-radon black |
62 | | -``` |
63 | | - |
64 | | -**2. Configure .flake8 file in project root:** |
65 | | -```ini |
66 | | -[flake8] |
67 | | -max-complexity = 10 |
68 | | -radon-max-cc = 10 |
69 | | -exclude = |
70 | | - __pycache__, |
71 | | - .git, |
72 | | - .lad, |
73 | | - .venv, |
74 | | - venv, |
75 | | - build, |
76 | | - dist |
77 | | -``` |
78 | | - |
79 | | -**3. Configure .coveragerc file (see kickoff prompt for template)** |
80 | | - |
81 | | -**4. Verify setup:** |
82 | | -```bash |
83 | | -flake8 --version # Should show flake8-radon plugin |
84 | | -radon --version # Confirm radon installation |
85 | | -pytest --cov=. --version # Confirm coverage plugin |
86 | | -``` |
87 | | - |
88 | | -## Installing & Configuring Radon |
| 57 | +**This project already has quality tooling configured.** Do not create new config files; use existing ones. |
89 | 58 |
|
90 | | -**Install Radon and its Flake8 plugin:** |
| 59 | +**Verify setup:** |
91 | 60 | ```bash |
92 | | -pip install radon flake8-radon |
| 61 | +pre-commit install # Install pre-commit hooks if not present |
| 62 | +tox -e lint # Run linting |
| 63 | +tox -e typing # Run type checking |
| 64 | +python -m pytest dandi # Run tests |
93 | 65 | ``` |
94 | | -This installs Radon's CLI and enables the `--radon-max-cc` option in Flake8. |
95 | 66 |
|
96 | | -**Enable Radon in Flake8** by adding to `.flake8` or `setup.cfg`: |
97 | | -```ini |
98 | | -[flake8] |
99 | | -max-complexity = 10 |
100 | | -radon-max-cc = 10 |
101 | | -``` |
102 | | -Functions exceeding cyclomatic complexity 10 will be flagged as errors (C901). |
103 | | - |
104 | | -**Verify Radon raw metrics:** |
105 | | -```bash |
106 | | -radon raw path/to/your/module.py |
107 | | -``` |
108 | | -Outputs LOC, LLOC, comments, blank lines—helping you spot oversized modules quickly. |
109 | | - |
110 | | -**(Optional) Measure Maintainability Index:** |
111 | | -```bash |
112 | | -radon mi path/to/your/module.py |
113 | | -``` |
114 | | -Gives a 0–100 score indicating code maintainability. |
| 67 | +**Existing configuration locations:** |
| 68 | +- **Linting/formatting**: `.pre-commit-config.yaml` (black, isort, flake8) |
| 69 | +- **Pytest config**: `tox.ini` under `[pytest]` section |
| 70 | +- **Type checking**: `tox.ini` under `[testenv:typing]` |
| 71 | +- **Dependencies**: `pyproject.toml` |
115 | 72 |
|
116 | 73 | Coverage & Code Safety |
117 | | -* For safety checks, do **not** run coverage inside VS Code. |
118 | | - Instead, ask the user: |
119 | | - > "Please run in your terminal: |
120 | | - > ```bash |
121 | | - > coverage run -m pytest [test_files] -q && coverage html |
122 | | - > ``` |
123 | | - > then reply **coverage complete**." |
124 | | -
|
125 | 74 | * Before deleting code, verify: |
126 | 75 | 1. 0% coverage via `coverage report --show-missing` |
127 | | - 2. Absence from Level-2 API docs |
128 | | - If both hold, prompt: |
129 | | - |
130 | | - Delete <name>? (y/n) |
131 | | - Reason: 0% covered and not documented. |
132 | | - (Tip: use VS Code "Find All References" on <name>.) |
| 76 | + 2. No references found via grep |
| 77 | + If both hold, prompt for confirmation before deletion. |
133 | 78 |
|
134 | 79 | Commits |
135 | | -* Use Conventional Commits. Example: |
136 | | - `feat(pipeline-filter): add ROI masking helper` |
137 | | -* Keep body as bullet list of sub-tasks completed. |
| 80 | +* Follow existing project conventions for commit messages. |
| 81 | +* pre-commit hooks will auto-fix formatting; if commit fails due to auto-fixes, re-run the commit. |
138 | 82 |
|
139 | 83 | Docs |
140 | | -* High-level docs live under the target project's `docs/` and are organised in three nested levels using `<details>` tags. |
| 84 | +* High-level docs live under the target project's `docs/` directory (Sphinx RST format). |
141 | 85 |
|
142 | 86 | * After completing each **main task** (top-level checklist item), run: |
143 | | - • `flake8 {{PROJECT_NAME}} --max-complexity=10` |
144 | | - • `python -m pytest --cov={{PROJECT_NAME}} --cov-context=test -q --maxfail=1` |
| 87 | + • `tox -e lint` |
| 88 | + • `python -m pytest dandi -q --maxfail=1` |
145 | 89 | If either step fails, pause for user guidance. |
146 | | -
|
147 | | -* **Radon checks:** Use `radon raw <file>` to get SLOC; use `radon mi <file>` to check maintainability. If `raw` LOC > 500 or MI < 65, propose splitting the module. |
0 commit comments