forked from val-lop20/Pagina-de-Asistencia-MAC
483 lines
9.3 KiB
Markdown
483 lines
9.3 KiB
Markdown
# Guía de Linting y Calidad de Código
|
||
|
||
Esta guía explica cómo usar las herramientas de linting y formateo configuradas en el proyecto para mantener un código Python de alta calidad siguiendo PEP8 y mejores prácticas.
|
||
|
||
## Tabla de Contenidos
|
||
|
||
- [Herramientas Configuradas](#herramientas-configuradas)
|
||
- [Instalación](#instalación)
|
||
- [Uso Rápido](#uso-rápido)
|
||
- [Herramientas Individuales](#herramientas-individuales)
|
||
- [Pre-commit Hooks](#pre-commit-hooks)
|
||
- [Integración con Docker](#integración-con-docker)
|
||
- [CI/CD](#cicd)
|
||
- [Configuración de IDEs](#configuración-de-ides)
|
||
|
||
## Herramientas Configuradas
|
||
|
||
### Formateo Automático
|
||
- **Black**: Formateador de código opinionado (PEP8)
|
||
- **isort**: Ordenador de imports
|
||
- **autopep8**: Corrector automático de PEP8
|
||
|
||
### Linting (Análisis Estático)
|
||
- **Flake8**: Verificador de estilo PEP8
|
||
- **pycodestyle**: Verificador oficial de PEP8
|
||
- **Pylint**: Analizador estático completo
|
||
- **Bandit**: Verificador de seguridad
|
||
|
||
### Type Checking
|
||
- **MyPy**: Verificador de tipos estáticos
|
||
- **django-stubs**: Type hints para Django
|
||
- **djangorestframework-stubs**: Type hints para DRF
|
||
|
||
### Testing
|
||
- **pytest**: Framework de testing
|
||
- **pytest-django**: Plugin para Django
|
||
- **pytest-cov**: Cobertura de tests
|
||
- **coverage**: Reporte de cobertura
|
||
|
||
## Instalación
|
||
|
||
### Opción 1: Usando Make (Recomendado)
|
||
|
||
```bash
|
||
# Instalar todas las dependencias de desarrollo
|
||
make install-dev
|
||
```
|
||
|
||
### Opción 2: Usando pip directamente
|
||
|
||
```bash
|
||
# Instalar dependencias de producción
|
||
pip install -r requirements.txt
|
||
|
||
# Instalar dependencias de desarrollo
|
||
pip install -r requirements-dev.txt
|
||
|
||
# Instalar pre-commit hooks
|
||
pre-commit install
|
||
```
|
||
|
||
### Opción 3: En Docker
|
||
|
||
```bash
|
||
# Construir imagen con herramientas de desarrollo
|
||
docker-compose exec backend pip install -r requirements-dev.txt
|
||
```
|
||
|
||
## Uso Rápido
|
||
|
||
### Formatear Código Automáticamente
|
||
|
||
```bash
|
||
# Usando Make
|
||
make format
|
||
|
||
# O manualmente
|
||
bash scripts/format.sh
|
||
```
|
||
|
||
Este comando ejecutará automáticamente:
|
||
1. **isort** - Ordena los imports
|
||
2. **black** - Formatea el código
|
||
3. **autopep8** - Aplica correcciones adicionales de PEP8
|
||
|
||
### Verificar Calidad de Código
|
||
|
||
```bash
|
||
# Usando Make
|
||
make lint
|
||
|
||
# O manualmente
|
||
bash scripts/lint.sh
|
||
```
|
||
|
||
Este comando ejecutará:
|
||
1. Black (verificación sin modificar)
|
||
2. isort (verificación)
|
||
3. Flake8 (PEP8)
|
||
4. Pylint (análisis estático)
|
||
5. Bandit (seguridad)
|
||
6. MyPy (type checking)
|
||
|
||
### Ver Todos los Comandos Disponibles
|
||
|
||
```bash
|
||
make help
|
||
```
|
||
|
||
## Herramientas Individuales
|
||
|
||
### Black - Formateador de Código
|
||
|
||
```bash
|
||
# Verificar formato sin modificar
|
||
black --check --diff .
|
||
|
||
# Formatear todo el código
|
||
black .
|
||
|
||
# Formatear archivo específico
|
||
black path/to/file.py
|
||
```
|
||
|
||
**Configuración**: `pyproject.toml` - Longitud de línea: 120
|
||
|
||
### isort - Ordenador de Imports
|
||
|
||
```bash
|
||
# Verificar imports sin modificar
|
||
isort --check-only --diff .
|
||
|
||
# Ordenar imports
|
||
isort .
|
||
|
||
# Ordenar archivo específico
|
||
isort path/to/file.py
|
||
```
|
||
|
||
**Configuración**: `pyproject.toml` - Compatible con Black
|
||
|
||
### Flake8 - Verificador PEP8
|
||
|
||
```bash
|
||
# Verificar todo el proyecto
|
||
flake8 .
|
||
|
||
# Verificar directorio específico
|
||
flake8 authentication/
|
||
|
||
# Verificar archivo específico
|
||
flake8 path/to/file.py
|
||
|
||
# Ignorar reglas específicas
|
||
flake8 --ignore=E501,W503 .
|
||
```
|
||
|
||
**Configuración**: `.flake8`
|
||
|
||
### Pylint - Análisis Estático
|
||
|
||
```bash
|
||
# Analizar todo el código
|
||
pylint authentication attendance events mac_attendance
|
||
|
||
# Analizar archivo específico
|
||
pylint path/to/file.py
|
||
|
||
# Generar reporte de calificación
|
||
pylint --output-format=text authentication/ | tee pylint-report.txt
|
||
```
|
||
|
||
**Configuración**: `pyproject.toml`
|
||
|
||
### Bandit - Verificador de Seguridad
|
||
|
||
```bash
|
||
# Verificar seguridad en todo el proyecto
|
||
bandit -r . -c pyproject.toml
|
||
|
||
# Verificar directorio específico
|
||
bandit -r authentication/
|
||
|
||
# Generar reporte detallado
|
||
bandit -r . -f json -o bandit-report.json
|
||
```
|
||
|
||
**Configuración**: `pyproject.toml`
|
||
|
||
### MyPy - Type Checking
|
||
|
||
```bash
|
||
# Verificar tipos
|
||
mypy --config-file=pyproject.toml .
|
||
|
||
# Verificar archivo específico
|
||
mypy path/to/file.py
|
||
|
||
# Generar reporte HTML
|
||
mypy --html-report mypy-report .
|
||
```
|
||
|
||
**Configuración**: `pyproject.toml`
|
||
|
||
## Pre-commit Hooks
|
||
|
||
Los pre-commit hooks ejecutan automáticamente las herramientas de linting antes de cada commit.
|
||
|
||
### Instalar Hooks
|
||
|
||
```bash
|
||
pre-commit install
|
||
```
|
||
|
||
### Ejecutar Hooks Manualmente
|
||
|
||
```bash
|
||
# Ejecutar en archivos staged
|
||
pre-commit run
|
||
|
||
# Ejecutar en todos los archivos
|
||
pre-commit run --all-files
|
||
|
||
# Usando Make
|
||
make pre-commit-all
|
||
```
|
||
|
||
### Saltar Hooks (No Recomendado)
|
||
|
||
```bash
|
||
git commit --no-verify -m "mensaje"
|
||
```
|
||
|
||
### Actualizar Hooks
|
||
|
||
```bash
|
||
pre-commit autoupdate
|
||
```
|
||
|
||
## Integración con Docker
|
||
|
||
### Ejecutar Linting en Docker
|
||
|
||
```bash
|
||
# Formatear código
|
||
docker-compose exec backend bash scripts/format.sh
|
||
|
||
# Verificar código
|
||
docker-compose exec backend bash scripts/lint.sh
|
||
|
||
# Usando Make
|
||
docker-compose exec backend make format
|
||
docker-compose exec backend make lint
|
||
```
|
||
|
||
### Agregar al Dockerfile
|
||
|
||
```dockerfile
|
||
# En Dockerfile.backend, agregar antes del CMD
|
||
COPY requirements-dev.txt .
|
||
RUN pip install -r requirements-dev.txt
|
||
|
||
# Ejecutar linting en el build
|
||
RUN flake8 . || true
|
||
```
|
||
|
||
## CI/CD
|
||
|
||
### GitHub Actions
|
||
|
||
Crear `.github/workflows/lint.yml`:
|
||
|
||
```yaml
|
||
name: Lint
|
||
|
||
on: [push, pull_request]
|
||
|
||
jobs:
|
||
lint:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v3
|
||
- uses: actions/setup-python@v4
|
||
with:
|
||
python-version: '3.11'
|
||
- name: Install dependencies
|
||
run: |
|
||
pip install -r backend/requirements-dev.txt
|
||
- name: Run linters
|
||
run: |
|
||
cd backend
|
||
make lint
|
||
```
|
||
|
||
### GitLab CI
|
||
|
||
Crear `.gitlab-ci.yml`:
|
||
|
||
```yaml
|
||
lint:
|
||
stage: test
|
||
image: python:3.11
|
||
script:
|
||
- cd backend
|
||
- pip install -r requirements-dev.txt
|
||
- make lint
|
||
```
|
||
|
||
## Configuración de IDEs
|
||
|
||
### Visual Studio Code
|
||
|
||
Crear `.vscode/settings.json`:
|
||
|
||
```json
|
||
{
|
||
"python.linting.enabled": true,
|
||
"python.linting.flake8Enabled": true,
|
||
"python.linting.pylintEnabled": true,
|
||
"python.linting.banditEnabled": true,
|
||
"python.linting.mypyEnabled": true,
|
||
"python.formatting.provider": "black",
|
||
"python.formatting.blackArgs": ["--line-length", "120"],
|
||
"python.sortImports.args": ["--profile", "black"],
|
||
"[python]": {
|
||
"editor.formatOnSave": true,
|
||
"editor.codeActionsOnSave": {
|
||
"source.organizeImports": true
|
||
}
|
||
},
|
||
"python.linting.flake8Args": ["--config=backend/.flake8"],
|
||
"python.linting.pylintArgs": ["--rcfile=backend/pyproject.toml"]
|
||
}
|
||
```
|
||
|
||
### PyCharm
|
||
|
||
1. **Configurar Black**:
|
||
- Settings → Tools → External Tools → Add
|
||
- Name: Black
|
||
- Program: `black`
|
||
- Arguments: `$FilePath$`
|
||
|
||
2. **Configurar Flake8**:
|
||
- Settings → Tools → External Tools → Add
|
||
- Name: Flake8
|
||
- Program: `flake8`
|
||
- Arguments: `$FilePath$`
|
||
|
||
3. **Configurar File Watcher**:
|
||
- Settings → Tools → File Watchers → Add
|
||
- File type: Python
|
||
- Program: `black`
|
||
|
||
## Métricas de Calidad
|
||
|
||
### Cobertura de Tests
|
||
|
||
```bash
|
||
# Ejecutar tests con cobertura
|
||
make coverage
|
||
|
||
# Ver reporte HTML
|
||
open htmlcov/index.html
|
||
```
|
||
|
||
### Complejidad Ciclomática
|
||
|
||
```bash
|
||
# Instalar radon
|
||
pip install radon
|
||
|
||
# Analizar complejidad
|
||
radon cc . -a -nb
|
||
|
||
# Generar reporte JSON
|
||
radon cc . -j > complexity-report.json
|
||
```
|
||
|
||
### Mantenibilidad
|
||
|
||
```bash
|
||
# Índice de mantenibilidad
|
||
radon mi . -s
|
||
|
||
# Mostrar solo archivos con baja mantenibilidad
|
||
radon mi . -s -n C
|
||
```
|
||
|
||
## Consejos y Mejores Prácticas
|
||
|
||
### 1. Formateo Automático
|
||
|
||
Ejecuta `make format` antes de cada commit para mantener el código formateado.
|
||
|
||
### 2. Pre-commit Hooks
|
||
|
||
Deja que los pre-commit hooks trabajen por ti. No los saltes a menos que sea absolutamente necesario.
|
||
|
||
### 3. Gradual
|
||
|
||
Si el proyecto tiene mucho código legacy, puedes aplicar linting gradualmente:
|
||
|
||
```bash
|
||
# Solo en archivos modificados
|
||
git diff --name-only | xargs flake8
|
||
```
|
||
|
||
### 4. Ignorar Reglas Específicas
|
||
|
||
Si necesitas ignorar una regla en una línea específica:
|
||
|
||
```python
|
||
# noqa: E501
|
||
long_line = "Esta línea es muy larga pero es necesaria" # noqa: E501
|
||
|
||
# Para múltiples reglas
|
||
code = "something" # noqa: E501,W503
|
||
```
|
||
|
||
### 5. Documentación
|
||
|
||
Mantén docstrings en funciones importantes:
|
||
|
||
```python
|
||
def calculate_attendance(student_id: int, event_id: int) -> float:
|
||
"""
|
||
Calcula el porcentaje de asistencia de un estudiante.
|
||
|
||
Args:
|
||
student_id: ID del estudiante
|
||
event_id: ID del evento
|
||
|
||
Returns:
|
||
Porcentaje de asistencia (0-100)
|
||
|
||
Raises:
|
||
ValueError: Si el estudiante o evento no existe
|
||
"""
|
||
pass
|
||
```
|
||
|
||
## Solución de Problemas
|
||
|
||
### Error: "command not found"
|
||
|
||
Asegúrate de haber instalado las dependencias:
|
||
```bash
|
||
make install-dev
|
||
```
|
||
|
||
### Error: "pre-commit: command not found"
|
||
|
||
```bash
|
||
pip install pre-commit
|
||
pre-commit install
|
||
```
|
||
|
||
### Conflictos entre Black e isort
|
||
|
||
La configuración está ajustada para que sean compatibles. Si hay conflictos:
|
||
```bash
|
||
# Ejecutar en orden
|
||
isort .
|
||
black .
|
||
```
|
||
|
||
### Demasiados errores de Flake8
|
||
|
||
Puedes ajustar las reglas en `.flake8` o formatear automáticamente:
|
||
```bash
|
||
make format
|
||
```
|
||
|
||
## Referencias
|
||
|
||
- [PEP 8 – Style Guide for Python Code](https://peps.python.org/pep-0008/)
|
||
- [Black Documentation](https://black.readthedocs.io/)
|
||
- [Flake8 Documentation](https://flake8.pycqa.org/)
|
||
- [Pylint Documentation](https://pylint.pycqa.org/)
|
||
- [isort Documentation](https://pycqa.github.io/isort/)
|
||
- [Pre-commit Documentation](https://pre-commit.com/)
|