Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Check no file is longer than 1000 lines
run: bin/check-file-length

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
Expand Down
14 changes: 13 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,20 @@ Lanza lo mismo que lanza la CI:
composer cs-fix # formatea el código PHP (reglas @Symfony)
composer phpstan # análisis estático
composer test # PHPUnit
bin/check-file-length # ningún archivo de más de 1000 líneas
```

### Tamaño de los archivos

Ningún archivo puede pasar de **1000 líneas**: la CI falla si alguno lo hace. Los archivos
largos cuestan de revisar y hacen que los PR choquen entre sí; si uno crece demasiado,
divídelo por responsabilidades (como `public/styles/pages/game/`, que antes era un solo
`game.css`). Quedan fuera los archivos generados (`composer.lock`, `config/reference.php`…).

Algunos archivos ya eran más largos cuando se puso la regla. Tienen una excepción temporal,
con un tope para que no sigan creciendo, en `bin/check-file-length`; cada uno tiene su issue
para dividirlo, y al cerrarlo se quita su línea de la lista.

Si tocas el minijuego **Al Filo**: la simulación vive en `public/js/game/sim.js` y el
servidor la repite línea a línea en `src/Service/Game/ClimbSimulation.php` para validar
las partidas. Cualquier cambio en una debe ir en las dos, subiendo `SIM_VERSION`, y
Expand All @@ -92,7 +104,7 @@ y de la plantilla `templates/game/index.html.twig`.
- Una cosa por PR, con una descripción de qué cambia y por qué (la plantilla te guía).
- Añade o actualiza tests cuando cambie el comportamiento.
- Los mensajes de commit pueden ir en español o en inglés; que expliquen el porqué.
- La CI (estilo, PHPStan y tests) tiene que pasar, y un mantenedor revisará el PR antes de
- La CI (estilo, PHPStan, tests y tamaño de archivos) tiene que pasar, y un mantenedor revisará el PR antes de
fusionarlo. Lo que se fusiona en `main` se despliega solo a producción, así que la
revisión es obligatoria.

Expand Down
59 changes: 59 additions & 0 deletions bin/check-file-length
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Repository rule: no source file may be longer than MAX_LINES lines.
# Run by CI (.github/workflows/ci.yml) on every push and pull request; run it locally with
# bin/check-file-length
# Long files are hard to review and make PRs collide: split them by responsibility instead.

set -euo pipefail

MAX_LINES=1000

# Generated or third-party files: never edited by hand, so the rule doesn't apply.
is_excluded() {
case "$1" in
composer.lock|package-lock.json|symfony.lock) return 0 ;;
config/reference.php) return 0 ;; # generated by Symfony
LICENSE) return 0 ;;
assets/vendor/*) return 0 ;; # vendored by importmap
tests/fixtures/*|data/*) return 0 ;; # test fixtures and sample data
*.png|*.jpg|*.jpeg|*.gif|*.webp|*.ico|*.svg|*.woff|*.woff2) return 0 ;;
esac
return 1
}

# Temporary exceptions: files that were already too long when the rule was added. Each one
# has an issue to split it and a cap so it can't keep growing. Remove the line once split.
exception_cap() {
case "$1" in
public/js/game/render.js) echo 1700 ;; # issue #15
public/js/game/main.js) echo 1350 ;; # issue #16
public/styles/main.css) echo 1100 ;; # issue #18
public/styles/pages/saved_routes/saved_routes.css) echo 1150 ;; # issue #18
*) echo "" ;;
esac
}

failed=0
while IFS= read -r file; do
[ -f "$file" ] || continue
is_excluded "$file" && continue
lines=$(wc -l < "$file" | tr -d ' ')
cap=$(exception_cap "$file")
limit=${cap:-$MAX_LINES}
if [ "$lines" -gt "$limit" ]; then
if [ -n "$cap" ]; then
echo "✗ $file: $lines lines (temporary cap $cap until it is split - see bin/check-file-length)"
else
echo "✗ $file: $lines lines (max $MAX_LINES) - split it into smaller files"
fi
failed=1
fi
done < <(git ls-files)

if [ "$failed" -ne 0 ]; then
echo
echo "Some files are too long. See the \"Tamaño de los archivos\" section in CONTRIBUTING.md."
exit 1
fi

echo "✓ No file is longer than $MAX_LINES lines (apart from the listed temporary exceptions)."
Loading
Loading