Skip to content

Commit 052d644

Browse files
committed
chore(githooks): auto-configure hooks from installers; ensure scripts/*.sh executable; add CI check for executable shebangs
1 parent 421fc64 commit 052d644

9 files changed

Lines changed: 124 additions & 17 deletions

File tree

.githooks/pre-commit

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
11
#!/usr/bin/env bash
2-
# Pre-commit hook: Ensure scripts under scripts/ with shebang become executable in the index
2+
# Cross-platform pre-commit hook: ensure scripts/*.sh are executable in the index
33
set -euo pipefail
44

5-
# Get list of staged files (added/modified)
5+
# If PowerShell is available, run the PowerShell hook on Windows
6+
if command -v pwsh >/dev/null 2>&1; then
7+
pwsh -ExecutionPolicy Bypass -File "$(git rev-parse --show-toplevel)/.githooks/pre-commit.ps1"
8+
exit 0
9+
fi
10+
if command -v powershell >/dev/null 2>&1; then
11+
powershell -ExecutionPolicy Bypass -File "$(git rev-parse --show-toplevel)/.githooks/pre-commit.ps1"
12+
exit 0
13+
fi
14+
15+
# Fallback: POSIX logic (for Bash)
616
STAGED=$(git diff --cached --name-only --diff-filter=ACM)
7-
if [ -z "$STAGED" ]; then exit 0
17+
if [ -z "$STAGED" ]; then
18+
exit 0
819
fi
920

1021
CHANGED=0
1122
for f in $STAGED; do
12-
# Only consider files under scripts/
1323
case "$f" in
14-
scripts/*)
24+
scripts/*.sh)
1525
if [ -f "$f" ]; then
16-
# If file has shebang, make it executable in the index
17-
if head -n 1 "$f" | grep -q '^#!'; then
18-
git update-index --chmod=+x "$f"
19-
CHANGED=1
20-
fi
26+
git update-index --chmod=+x "$f" && CHANGED=1 || true
2127
fi
2228
;;
2329
esac
2430
done
2531

2632
if [ "$CHANGED" -eq 1 ]; then
27-
echo "Fixed executable bit for staged scripts; the index has been updated."
28-
# Keep commit proceeding. We changed the index, but the commit will include that change.
33+
echo "Marked staged scripts/*.sh as executable in index"
2934
fi
3035

3136
exit 0

.githooks/pre-commit.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# PowerShell pre-commit hook: ensure scripts/*.sh are executable in the index
2+
param()
3+
4+
# Get staged files
5+
$staged = git diff --cached --name-only --diff-filter=ACM
6+
if (-not $staged) { exit 0 }
7+
8+
$changed = $false
9+
foreach ($f in $staged) {
10+
if ($f -like 'scripts/*.sh') {
11+
if (Test-Path $f) {
12+
# Set the executable bit in git index
13+
git update-index --chmod=+x $f
14+
$changed = $true
15+
}
16+
}
17+
}
18+
if ($changed) {
19+
Write-Host "Marked staged scripts/*.sh as executable in index"
20+
}
21+
exit 0

.github/workflows/ci.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,23 @@ jobs:
2222
- name: Bash syntax check
2323
run: |
2424
for f in ./scripts/*.sh; do bash -n "$f"; done
25+
- name: Check executable bit on shebang scripts
26+
run: |
27+
set -e
28+
fail=0
29+
files=$(git ls-files -- "scripts/*.sh" || true)
30+
if [ -n "$files" ]; then
31+
for f in $files; do
32+
if head -n1 "$f" | grep -q '^#!'; then
33+
mode=$(git ls-files --stage "$f" | awk '{print $1}')
34+
if [ "$mode" != "100755" ]; then
35+
echo "$f has shebang but is not executable in index (mode: $mode). Run: git update-index --chmod=+x $f"
36+
fail=1
37+
fi
38+
fi
39+
done
40+
fi
41+
if [ "$fail" -eq 1 ]; then exit 1; fi
2542
- name: Run shellcheck
2643
run: |
2744
for f in ./scripts/*.sh; do shellcheck "$f" || true; done

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ Para más detalles y alternativas (subtree, CI, etc), revisa `docs/INSTALL.md` y
8989
```
9090
Nota: El instalador `./scripts/install.sh` aplica solo dotfiles de usuario en `$HOME` (stow), y no modifica archivos de sistema como `/etc/*`. Para cambios a nivel sistema aplica los archivos manualmente con permisos root según las instrucciones en `docs/INSTALL.md`.
9191

92-
Desarrolladores: Si quieres que los hooks locales se activen automáticamente en tu clone, ejecuta:
92+
Desarrolladores: Los instaladores `scripts/install.sh` y `scripts/install.ps1` configuran automáticamente `core.hooksPath` a `.githooks`
93+
en tu copia local del repositorio cuando se ejecutan (esto es seguro y idempotente). Si prefieres configurarlo manualmente en vez de
94+
ejecutar el instalador, puedes correr:
9395

9496
```bash
9597
./scripts/setup-githooks.sh

docs/INSTALL.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,19 @@ Precauciones:
3434
1. Copiar `modules/system/etc/X11/*.conf` a `/etc/X11/xorg.conf.d/`.
3535
2. Reinicia la sesión gráfica tras copiar el archivo a /etc/X11/xorg.conf.d/.
3636

37-
## Hooks Git (Opcional)
38-
Este repositorio incluye un hook pre-commit en `.githooks/pre-commit` que asegura que los archivos dentro
37+
## Hooks Git (automático)
38+
Este repositorio incluye un pre-commit hook en `.githooks/pre-commit` que asegura que los archivos dentro
3939
de `scripts/` con un shebang (`#!`) reciban el bit de ejecución (`+x`) en el índice al hacer commit, para evitar
40-
problemas en plataformas Unix. Para activar los hooks en tu copia local ejecuta:
40+
problemas en plataformas Unix.
41+
42+
Los instaladores `scripts/install.sh` y `scripts/install.ps1` ejecutarán automáticamente `scripts/setup-githooks.*`
43+
si se ejecutan en una copia del repositorio (es idempotente y seguro). Si prefieres configurarlo manualmente, ejecuta:
4144

4245
```bash
4346
./scripts/setup-githooks.sh
4447
```
4548

46-
Después de ejecutar el script, el hook correrá localmente antes de cada commit. Si deseas revertir este cambio:
49+
Para revertir la configuración en tu copia local:
4750
```bash
4851
git config --unset core.hooksPath
4952
```

scripts/install.ps1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,15 @@ foreach ($module in $Modules) {
3535
}
3636

3737
Write-Host "Instalación (PowerShell) finalizada. Revisa los enlaces simbólicos." -ForegroundColor Cyan
38+
39+
# Auto-configure Git hooks in this repository (safe and idempotent)
40+
try {
41+
$null = git rev-parse --is-inside-work-tree 2>$null
42+
$setupPath = Join-Path $PSScriptRoot 'setup-githooks.ps1'
43+
if (Test-Path $setupPath) {
44+
Write-Host "Configurando hooks de git localmente (core.hooksPath -> .githooks)" -ForegroundColor Cyan
45+
try { & $setupPath } catch { Write-Warning "No se pudo configurar hooks de git: $_" }
46+
}
47+
} catch {
48+
# Not a git repository or git not available; ignore
49+
}

scripts/install.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,14 @@ done
7474
echo "Instalación finalizada. Este instalador solo aplica dotfiles de usuario en \\${HOME}."
7575
echo "Si necesitas aplicar cambios a nivel sistema (Xorg, etc.), hazlo manualmente con permisos de root."
7676
echo "Recuerda revisar los archivos instalados para asegurarte de que todo esté como deseas."
77+
78+
# Auto-configure git hooks (if available) — this is safe and idempotent and only affects local git config
79+
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
80+
REPO_ROOT=$(git rev-parse --show-toplevel)
81+
SETUP_SCRIPT="$REPO_ROOT/scripts/setup-githooks.sh"
82+
if [ -f "$SETUP_SCRIPT" ]; then
83+
echo "Configurando hooks de git localmente (core.hooksPath -> .githooks)"
84+
# run setup script, ignore errors (non-fatal)
85+
"$SETUP_SCRIPT" || true
86+
fi
87+
fi

scripts/setup-githooks.ps1

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# PowerShell setup to configure Git hooks path
2+
param()
3+
4+
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
5+
Write-Error "git not found"
6+
exit 1
7+
}
8+
9+
git config core.hooksPath .githooks
10+
Write-Host "core.hooksPath set to .githooks"
11+
12+
# Make sure the Windows scripts are executable in index (call the PS pre-commit logic)
13+
# Only set execute bit for scripts with a shebang
14+
$files = git ls-files "scripts/*.sh" 2>$null
15+
foreach ($f in $files) {
16+
if (Test-Path $f) {
17+
$firstLine = Get-Content -Path $f -TotalCount 1 -ErrorAction SilentlyContinue
18+
if ($firstLine -and $firstLine -match '^#!') {
19+
git update-index --chmod=+x $f
20+
}
21+
}
22+
}
23+
24+
Write-Host "Updated git index for scripts/*.sh to be executable (if present)."

scripts/setup-githooks.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,15 @@ fi
1010
git config core.hooksPath .githooks
1111

1212
echo "Configured Git hooks path to '.githooks' in this repository. If you want to revert, do: git config --unset core.hooksPath"
13+
14+
# Ensure scripts/*.sh with a shebang are executable in the index (idempotent)
15+
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
16+
for f in $(git ls-files "scripts/*.sh" 2>/dev/null || true); do
17+
if [ -f "$f" ]; then
18+
if head -n 1 "$f" | grep -q '^#!'; then
19+
git update-index --chmod=+x "$f" || true
20+
fi
21+
fi
22+
done
23+
echo "Ensured executable bit is set for scripts/*.sh with a shebang in the git index."
24+
fi

0 commit comments

Comments
 (0)