chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# Python Linter
|
||||
|
||||
Run Python code linting and formatting tools.
|
||||
|
||||
## Purpose
|
||||
|
||||
This command helps you maintain code quality using Python's best linting and formatting tools.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/lint
|
||||
```
|
||||
|
||||
## What this command does
|
||||
|
||||
1. **Runs multiple linters** (flake8, pylint, black, isort)
|
||||
2. **Provides detailed feedback** on code quality issues
|
||||
3. **Auto-fixes formatting** where possible
|
||||
4. **Checks type hints** if mypy is configured
|
||||
|
||||
## Example Commands
|
||||
|
||||
### Black (code formatting)
|
||||
```bash
|
||||
# Format all Python files
|
||||
black .
|
||||
|
||||
# Check formatting without changing files
|
||||
black --check .
|
||||
|
||||
# Format specific file
|
||||
black src/main.py
|
||||
```
|
||||
|
||||
### flake8 (style guide enforcement)
|
||||
```bash
|
||||
# Check all Python files
|
||||
flake8 .
|
||||
|
||||
# Check specific directory
|
||||
flake8 src/
|
||||
|
||||
# Check with specific rules
|
||||
flake8 --max-line-length=88 .
|
||||
```
|
||||
|
||||
### isort (import sorting)
|
||||
```bash
|
||||
# Sort imports in all files
|
||||
isort .
|
||||
|
||||
# Check import sorting
|
||||
isort --check-only .
|
||||
|
||||
# Sort imports in specific file
|
||||
isort src/main.py
|
||||
```
|
||||
|
||||
### pylint (comprehensive linting)
|
||||
```bash
|
||||
# Run pylint on all files
|
||||
pylint src/
|
||||
|
||||
# Run with specific score threshold
|
||||
pylint --fail-under=8.0 src/
|
||||
|
||||
# Generate detailed report
|
||||
pylint --output-format=html src/ > pylint_report.html
|
||||
```
|
||||
|
||||
### mypy (type checking)
|
||||
```bash
|
||||
# Check types in all files
|
||||
mypy .
|
||||
|
||||
# Check specific module
|
||||
mypy src/models.py
|
||||
|
||||
# Check with strict mode
|
||||
mypy --strict src/
|
||||
```
|
||||
|
||||
## Configuration Files
|
||||
|
||||
Most projects benefit from configuration files:
|
||||
|
||||
### .flake8
|
||||
```ini
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
exclude = .git,__pycache__,venv
|
||||
ignore = E203,W503
|
||||
```
|
||||
|
||||
### pyproject.toml
|
||||
```toml
|
||||
[tool.black]
|
||||
line-length = 88
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Run linters before committing code
|
||||
- Use consistent formatting across the project
|
||||
- Fix linting issues promptly
|
||||
- Configure linters to match your team's style
|
||||
- Use type hints for better code documentation
|
||||
@@ -0,0 +1,73 @@
|
||||
# Test Runner
|
||||
|
||||
Run Python tests with pytest, unittest, or other testing frameworks.
|
||||
|
||||
## Purpose
|
||||
|
||||
This command helps you run Python tests effectively with proper configuration and reporting.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/test
|
||||
```
|
||||
|
||||
## What this command does
|
||||
|
||||
1. **Detects test framework** (pytest, unittest, nose2)
|
||||
2. **Runs appropriate tests** with proper configuration
|
||||
3. **Provides coverage reporting** if available
|
||||
4. **Shows clear test results** with failure details
|
||||
|
||||
## Example Commands
|
||||
|
||||
### pytest (recommended)
|
||||
```bash
|
||||
# Run all tests
|
||||
pytest
|
||||
|
||||
# Run with coverage
|
||||
pytest --cov=src --cov-report=html
|
||||
|
||||
# Run specific test file
|
||||
pytest tests/test_models.py
|
||||
|
||||
# Run with verbose output
|
||||
pytest -v
|
||||
|
||||
# Run tests matching pattern
|
||||
pytest -k "test_user"
|
||||
```
|
||||
|
||||
### unittest
|
||||
```bash
|
||||
# Run all tests
|
||||
python -m unittest discover
|
||||
|
||||
# Run specific test file
|
||||
python -m unittest tests.test_models
|
||||
|
||||
# Run with verbose output
|
||||
python -m unittest -v
|
||||
```
|
||||
|
||||
### Django tests
|
||||
```bash
|
||||
# Run all Django tests
|
||||
python manage.py test
|
||||
|
||||
# Run specific app tests
|
||||
python manage.py test myapp
|
||||
|
||||
# Run with coverage
|
||||
coverage run --source='.' manage.py test
|
||||
coverage report
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Write tests for all critical functionality
|
||||
- Use descriptive test names
|
||||
- Keep tests isolated and independent
|
||||
- Mock external dependencies
|
||||
- Aim for high test coverage (80%+)
|
||||
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash",
|
||||
"Edit",
|
||||
"MultiEdit",
|
||||
"Write",
|
||||
"Bash(python:*)",
|
||||
"Bash(pip:*)",
|
||||
"Bash(pytest:*)",
|
||||
"Bash(black:*)",
|
||||
"Bash(isort:*)",
|
||||
"Bash(flake8:*)",
|
||||
"Bash(mypy:*)",
|
||||
"Bash(django-admin:*)",
|
||||
"Bash(flask:*)",
|
||||
"Bash(uvicorn:*)",
|
||||
"Bash(gunicorn:*)",
|
||||
"Bash(git:*)"
|
||||
],
|
||||
"deny": [
|
||||
"Bash(curl:*)",
|
||||
"Bash(wget:*)",
|
||||
"Bash(rm -rf:*)"
|
||||
],
|
||||
"defaultMode": "allowEdits"
|
||||
},
|
||||
"env": {
|
||||
"BASH_DEFAULT_TIMEOUT_MS": "60000",
|
||||
"BASH_MAX_OUTPUT_LENGTH": "20000",
|
||||
"CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": "1",
|
||||
"PYTHONPATH": "."
|
||||
},
|
||||
"includeCoAuthoredBy": true,
|
||||
"cleanupPeriodDays": 30,
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "FILE=$(echo $STDIN_JSON | jq -r '.tool_input.file_path // \"\"); CONTENT=$(echo $STDIN_JSON | jq -r '.tool_input.content // \"\"); if [[ \"$FILE\" =~ \\.py$ ]] && echo \"$CONTENT\" | grep -q 'print('; then echo 'Warning: print() statements should be replaced with logging' >&2; exit 2; fi"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "FILE=$(echo $STDIN_JSON | jq -r '.tool_input.file_path // \"\"'); if [[ \"$FILE\" == \"requirements.txt\" ]] || [[ \"$FILE\" == \"pyproject.toml\" ]] || [[ \"$FILE\" == \"setup.py\" ]]; then echo 'Checking for vulnerable dependencies...'; if command -v safety >/dev/null 2>&1; then safety check; elif command -v pip-audit >/dev/null 2>&1; then pip-audit; else echo 'No security audit tool found. Install safety or pip-audit'; fi; fi",
|
||||
"timeout": 60
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Write|Edit|MultiEdit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "FILE=$(echo $STDIN_JSON | jq -r '.tool_input.file_path // \"\"'); if [[ \"$FILE\" =~ \\.py$ ]]; then black \"$FILE\" 2>/dev/null || echo 'Black formatting skipped (not installed)'; fi",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write|Edit|MultiEdit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "FILE=$(echo $STDIN_JSON | jq -r '.tool_input.file_path // \"\"'); if [[ \"$FILE\" =~ \\.py$ ]]; then isort \"$FILE\" 2>/dev/null || echo 'isort skipped (not installed)'; fi",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write|Edit|MultiEdit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "FILE=$(echo $STDIN_JSON | jq -r '.tool_input.file_path // \"\"'); if [[ \"$FILE\" =~ \\.py$ ]]; then RESULT=$(flake8 \"$FILE\" 2>&1); if [ $? -ne 0 ] && command -v flake8 >/dev/null 2>&1; then echo \"Flake8 linting issues found: $RESULT\" >&2; exit 2; fi; fi",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write|Edit|MultiEdit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "FILE=$(echo $STDIN_JSON | jq -r '.tool_input.file_path // \"\"'); if [[ \"$FILE\" =~ \\.py$ ]]; then RESULT=$(mypy \"$FILE\" 2>&1); if [ $? -ne 0 ] && command -v mypy >/dev/null 2>&1; then echo \"MyPy type checking issues found: $RESULT\" >&2; exit 2; fi; fi",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write|Edit|MultiEdit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "FILE=$(echo $STDIN_JSON | jq -r '.tool_input.file_path // \"\"'); if [[ \"$FILE\" =~ \\.py$ && \"$FILE\" != *\"test_\"* && \"$FILE\" != *\"_test.py\" ]]; then DIR=$(dirname \"$FILE\"); BASENAME=$(basename \"$FILE\" .py); for TEST_FILE in \"$DIR/test_$BASENAME.py\" \"$DIR/${BASENAME}_test.py\" \"tests/test_$BASENAME.py\"; do if [ -f \"$TEST_FILE\" ]; then echo \"Running tests for $TEST_FILE...\"; if command -v pytest >/dev/null 2>&1; then pytest \"$TEST_FILE\" -v; elif python -m pytest \"$TEST_FILE\" 2>/dev/null; then python -m pytest \"$TEST_FILE\" -v; else python -m unittest \"$TEST_FILE\" 2>/dev/null || echo 'No test runner found'; fi; break; fi; done; fi",
|
||||
"timeout": 60
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Notification": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "echo \"Claude Code notification: $(date)\" >> ~/.claude/notifications.log"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Stop": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "if [[ -f requirements.txt || -f pyproject.toml || -f setup.py ]] && [[ $(git status --porcelain | grep '\\.py$') ]]; then echo 'Running linter on changed Python files...'; if command -v flake8 >/dev/null 2>&1; then flake8 $(git diff --name-only --diff-filter=ACMR | grep '\\.py$'); elif command -v pylint >/dev/null 2>&1; then pylint $(git diff --name-only --diff-filter=ACMR | grep '\\.py$'); else echo 'No Python linter found (flake8/pylint)'; fi; fi",
|
||||
"timeout": 60
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "if [[ -f requirements.txt || -f pyproject.toml || -f setup.py ]] && [[ $(git status --porcelain | grep '\\.py$') ]]; then echo 'Running type checking on changed files...'; if command -v mypy >/dev/null 2>&1; then mypy $(git diff --name-only --diff-filter=ACMR | grep '\\.py$') || echo 'Type checking completed with issues'; else echo 'MyPy not found for type checking'; fi; fi",
|
||||
"timeout": 60
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user