claude-git-hooks 1.2.1 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/LICENSE +0 -0
- package/README.md +45 -6
- package/bin/claude-hooks +118 -6
- package/package.json +1 -1
- package/templates/CLAUDE_PRE_COMMIT.md +2 -1
- package/templates/CLAUDE_PRE_COMMIT_SONAR.md +12 -2
- package/templates/pre-commit +33 -25
- package/templates/prepare-commit-msg +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ Todos los cambios notables en este proyecto se documentarán en este archivo.
|
|
|
5
5
|
El formato está basado en [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.2.4] - 2025-08-22
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- 🐛 Corregido el análisis de SonarQube para mostrar correctamente el formato detallado
|
|
12
|
+
- 📊 Arreglado el parsing de JSON para buscar `QUALITY_GATE` en mayúsculas según las pautas
|
|
13
|
+
- 🔧 Actualizado el mapeo de campos JSON para coincidir con la estructura esperada
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- 📈 Añadidas métricas de coverage, duplications y complexity al formato SonarQube
|
|
17
|
+
- 📝 Actualizado el archivo de pautas SonarQube para incluir todas las métricas
|
|
18
|
+
|
|
19
|
+
## [1.2.3] - 2025-08-22
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- 🚀 Actualización automática de `.gitignore` durante la instalación
|
|
23
|
+
- 📝 Claude Hooks ahora agrega automáticamente las entradas necesarias a `.gitignore`
|
|
24
|
+
- 🔍 El comando `status` ahora muestra el estado de las entradas en `.gitignore`
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- 🎯 Mejorado el proceso de instalación para ser más completo y automatizado
|
|
28
|
+
- 📊 El comando `status` ahora proporciona información más detallada sobre la configuración
|
|
29
|
+
|
|
30
|
+
## [1.2.2] - 2025-08-22
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- 🐛 Corregido problema donde los archivos markdown de pautas no se instalaban correctamente desde npm
|
|
34
|
+
- 📁 Los archivos de pautas ahora se instalan en el directorio `.claude/` en lugar de la raíz del proyecto
|
|
35
|
+
- 🔧 Actualizado el hook pre-commit para buscar los archivos de pautas en la nueva ubicación `.claude/`
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
- 📂 Los archivos `CLAUDE_PRE_COMMIT.md` y `CLAUDE_PRE_COMMIT_SONAR.md` ahora se almacenan en `.claude/`
|
|
39
|
+
- 🎯 Mejorada la organización del proyecto manteniendo los archivos de configuración separados del código fuente
|
|
40
|
+
- 📝 Actualizada la documentación para reflejar la nueva estructura de directorios
|
|
41
|
+
|
|
8
42
|
## [1.2.1] - 2024-07-24
|
|
9
43
|
|
|
10
44
|
### Fixed
|
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -8,8 +8,8 @@ Este directorio contiene un pre-commit hook que utiliza Claude CLI para revisar
|
|
|
8
8
|
- **`pre-commit`** - Hook principal para análisis de código (con auto-actualización)
|
|
9
9
|
- **`prepare-commit-msg`** - Hook para generar mensajes de commit automáticos
|
|
10
10
|
- **`.gitattributes`** - Configuración para mantener line endings correctos
|
|
11
|
-
-
|
|
12
|
-
-
|
|
11
|
+
- **`.claude/CLAUDE_PRE_COMMIT.md`** - Pautas de evaluación formato estándar
|
|
12
|
+
- **`.claude/CLAUDE_PRE_COMMIT_SONAR.md`** - Pautas de evaluación formato SonarQube
|
|
13
13
|
|
|
14
14
|
## 🔧 Configuración Previa Importante
|
|
15
15
|
|
|
@@ -69,6 +69,7 @@ El comando `claude-hooks install` ahora incluye:
|
|
|
69
69
|
- ✅ Configuración de Git (line endings WSL/Windows)
|
|
70
70
|
- ✅ Verificación de autenticación Claude con entretenimiento
|
|
71
71
|
- ✅ Instalación de hooks y archivos de pautas
|
|
72
|
+
- ✅ Actualización automática de .gitignore con archivos de Claude
|
|
72
73
|
|
|
73
74
|
#### Añadir como Dependencia de Desarrollo
|
|
74
75
|
|
|
@@ -99,6 +100,37 @@ Luego añade esto a tu `package.json`:
|
|
|
99
100
|
- `pre-commit`: Análisis de código con Claude (solo archivos Java/config)
|
|
100
101
|
- `prepare-commit-msg`: Generación automática de mensajes de commit
|
|
101
102
|
|
|
103
|
+
## 📁 Gestión de Archivos
|
|
104
|
+
|
|
105
|
+
### Archivos creados durante la instalación
|
|
106
|
+
|
|
107
|
+
El comando `claude-hooks install` crea los siguientes archivos y directorios:
|
|
108
|
+
|
|
109
|
+
1. **`.git/hooks/pre-commit`** - Hook de análisis de código
|
|
110
|
+
2. **`.git/hooks/prepare-commit-msg`** - Hook de generación de mensajes
|
|
111
|
+
3. **`.claude/`** - Directorio para archivos de configuración
|
|
112
|
+
- `CLAUDE_PRE_COMMIT.md` - Pautas de evaluación estándar
|
|
113
|
+
- `CLAUDE_PRE_COMMIT_SONAR.md` - Pautas de evaluación SonarQube
|
|
114
|
+
4. **`.claude-analysis-mode`** - Archivo de preferencia de modo (creado al primer uso)
|
|
115
|
+
|
|
116
|
+
### Actualización automática de .gitignore
|
|
117
|
+
|
|
118
|
+
Durante la instalación, Claude Hooks actualiza automáticamente tu `.gitignore` para incluir:
|
|
119
|
+
|
|
120
|
+
```gitignore
|
|
121
|
+
# Claude Git Hooks
|
|
122
|
+
.claude/
|
|
123
|
+
.claude-analysis-mode
|
|
124
|
+
debug-claude-response.json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Esto asegura que:
|
|
128
|
+
- Los archivos de configuración de Claude específicos del proyecto no se suban al repositorio
|
|
129
|
+
- Los archivos de debug temporales se ignoren
|
|
130
|
+
- Cada desarrollador pueda tener sus propias preferencias de análisis
|
|
131
|
+
|
|
132
|
+
Si no existe un `.gitignore`, se creará uno nuevo. Si ya existe, las entradas se agregarán al final solo si no están presentes.
|
|
133
|
+
|
|
102
134
|
## 🎯 Funcionamiento
|
|
103
135
|
|
|
104
136
|
### Hook pre-commit (Análisis de código)
|
|
@@ -112,7 +144,7 @@ Luego añade esto a tu `package.json`:
|
|
|
112
144
|
- **Estándar**: Formato clásico con score y recomendaciones detalladas
|
|
113
145
|
- **SonarQube**: Simula salida de SonarQube con Quality Gate, métricas y clasificación de issues
|
|
114
146
|
4. **Construye prompt inteligente**:
|
|
115
|
-
- Lee las pautas desde
|
|
147
|
+
- Lee las pautas desde `.claude/CLAUDE_PRE_COMMIT.md` o `.claude/CLAUDE_PRE_COMMIT_SONAR.md`
|
|
116
148
|
- Incluye el diff completo para archivos nuevos
|
|
117
149
|
- Muestra solo cambios para archivos existentes
|
|
118
150
|
5. **Envía a Claude CLI para revisión**
|
|
@@ -284,8 +316,8 @@ En el archivo `pre-commit`:
|
|
|
284
316
|
- **`MAX_FILE_SIZE`**: Tamaño máximo de archivo a analizar (default: 100KB)
|
|
285
317
|
- **`MAX_FILES`**: Número máximo de archivos por commit (default: 10)
|
|
286
318
|
- **`CLAUDE_CLI`**: Comando de Claude CLI (default: "claude")
|
|
287
|
-
- **`GUIDELINES_FILE`**: Archivo de pautas para modo estándar (default: "CLAUDE_PRE_COMMIT.md")
|
|
288
|
-
- **`GUIDELINES_FILE_SONAR`**: Archivo de pautas para modo SonarQube (default: "CLAUDE_PRE_COMMIT_SONAR.md")
|
|
319
|
+
- **`GUIDELINES_FILE`**: Archivo de pautas para modo estándar (default: ".claude/CLAUDE_PRE_COMMIT.md")
|
|
320
|
+
- **`GUIDELINES_FILE_SONAR`**: Archivo de pautas para modo SonarQube (default: ".claude/CLAUDE_PRE_COMMIT_SONAR.md")
|
|
289
321
|
|
|
290
322
|
En el archivo `prepare-commit-msg`:
|
|
291
323
|
|
|
@@ -351,7 +383,11 @@ Este problema suele ocurrir por conflictos de configuración de line endings:
|
|
|
351
383
|
|
|
352
384
|
## 📝 Personalización
|
|
353
385
|
|
|
354
|
-
Puedes modificar las pautas de evaluación editando
|
|
386
|
+
Puedes modificar las pautas de evaluación editando los archivos en el directorio `.claude/`:
|
|
387
|
+
- `.claude/CLAUDE_PRE_COMMIT.md` - Para el modo estándar
|
|
388
|
+
- `.claude/CLAUDE_PRE_COMMIT_SONAR.md` - Para el modo SonarQube
|
|
389
|
+
|
|
390
|
+
Estos archivos son específicos de tu proyecto y puedes adaptarlos a los estándares de tu equipo.
|
|
355
391
|
|
|
356
392
|
## 🔄 Arquitectura del Sistema
|
|
357
393
|
|
|
@@ -394,6 +430,9 @@ claude-git-hooks/
|
|
|
394
430
|
│ ├── prepare-commit-msg # Hook de generación de mensajes
|
|
395
431
|
│ ├── CLAUDE_PRE_COMMIT.md # Pautas estándar
|
|
396
432
|
│ └── CLAUDE_PRE_COMMIT_SONAR.md # Pautas SonarQube
|
|
433
|
+
├── .claude/ # Directorio creado en el repo del usuario
|
|
434
|
+
│ ├── CLAUDE_PRE_COMMIT.md # Pautas copiadas aquí durante la instalación
|
|
435
|
+
│ └── CLAUDE_PRE_COMMIT_SONAR.md
|
|
397
436
|
├── package.json # Configuración NPM
|
|
398
437
|
├── README.md # Este archivo
|
|
399
438
|
├── CHANGELOG.md # Historial de versiones
|
package/bin/claude-hooks
CHANGED
|
@@ -308,14 +308,22 @@ async function install(args) {
|
|
|
308
308
|
success(`${hook} instalado`);
|
|
309
309
|
});
|
|
310
310
|
|
|
311
|
-
//
|
|
311
|
+
// Crear directorio .claude si no existe
|
|
312
|
+
const claudeDir = '.claude';
|
|
313
|
+
if (!fs.existsSync(claudeDir)) {
|
|
314
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
315
|
+
success('.claude directory created');
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Copiar archivos de pautas a .claude si no existen
|
|
312
319
|
const guidelines = ['CLAUDE_PRE_COMMIT.md', 'CLAUDE_PRE_COMMIT_SONAR.md'];
|
|
313
320
|
guidelines.forEach(guideline => {
|
|
314
|
-
|
|
321
|
+
const destPath = path.join(claudeDir, guideline);
|
|
322
|
+
if (!fs.existsSync(destPath)) {
|
|
315
323
|
const sourcePath = path.join(templatesPath, guideline);
|
|
316
324
|
if (fs.existsSync(sourcePath)) {
|
|
317
|
-
fs.copyFileSync(sourcePath,
|
|
318
|
-
success(`${guideline} creado
|
|
325
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
326
|
+
success(`${guideline} creado en .claude/`);
|
|
319
327
|
}
|
|
320
328
|
}
|
|
321
329
|
});
|
|
@@ -323,6 +331,9 @@ async function install(args) {
|
|
|
323
331
|
// Configurar Git
|
|
324
332
|
configureGit();
|
|
325
333
|
|
|
334
|
+
// Actualizar .gitignore
|
|
335
|
+
updateGitignore();
|
|
336
|
+
|
|
326
337
|
success('¡Claude Git Hooks instalado exitosamente! 🎉');
|
|
327
338
|
console.log('\nUso:');
|
|
328
339
|
console.log(' git commit -m "auto" # Genera mensaje automáticamente');
|
|
@@ -503,6 +514,79 @@ async function checkClaudeAuth() {
|
|
|
503
514
|
}
|
|
504
515
|
}
|
|
505
516
|
|
|
517
|
+
// Actualizar .gitignore con las entradas de Claude
|
|
518
|
+
function updateGitignore() {
|
|
519
|
+
info('Actualizando .gitignore...');
|
|
520
|
+
|
|
521
|
+
const gitignorePath = '.gitignore';
|
|
522
|
+
const claudeEntries = [
|
|
523
|
+
'# Claude Git Hooks',
|
|
524
|
+
'.claude/',
|
|
525
|
+
'.claude-analysis-mode',
|
|
526
|
+
'debug-claude-response.json'
|
|
527
|
+
];
|
|
528
|
+
|
|
529
|
+
let gitignoreContent = '';
|
|
530
|
+
let fileExists = false;
|
|
531
|
+
|
|
532
|
+
// Leer .gitignore existente si existe
|
|
533
|
+
if (fs.existsSync(gitignorePath)) {
|
|
534
|
+
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
535
|
+
fileExists = true;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Verificar qué entradas faltan
|
|
539
|
+
const missingEntries = [];
|
|
540
|
+
claudeEntries.forEach(entry => {
|
|
541
|
+
if (entry.startsWith('#')) {
|
|
542
|
+
// Para comentarios, verificar si ya existe algún comentario de Claude
|
|
543
|
+
if (!gitignoreContent.includes('# Claude')) {
|
|
544
|
+
missingEntries.push(entry);
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
// Para entradas normales, verificar si ya están presentes
|
|
548
|
+
const regex = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'm');
|
|
549
|
+
if (!regex.test(gitignoreContent)) {
|
|
550
|
+
missingEntries.push(entry);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
// Si hay entradas faltantes, agregarlas
|
|
556
|
+
if (missingEntries.length > 0) {
|
|
557
|
+
// Asegurar que hay una nueva línea al final si el archivo existe y no está vacío
|
|
558
|
+
if (fileExists && gitignoreContent.length > 0 && !gitignoreContent.endsWith('\n')) {
|
|
559
|
+
gitignoreContent += '\n';
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Si el archivo no está vacío, agregar una línea en blanco antes
|
|
563
|
+
if (gitignoreContent.length > 0) {
|
|
564
|
+
gitignoreContent += '\n';
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Agregar las entradas faltantes
|
|
568
|
+
gitignoreContent += missingEntries.join('\n') + '\n';
|
|
569
|
+
|
|
570
|
+
// Escribir el archivo actualizado
|
|
571
|
+
fs.writeFileSync(gitignorePath, gitignoreContent);
|
|
572
|
+
|
|
573
|
+
if (fileExists) {
|
|
574
|
+
success('.gitignore actualizado con entradas de Claude');
|
|
575
|
+
} else {
|
|
576
|
+
success('.gitignore creado con entradas de Claude');
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Mostrar qué se agregó
|
|
580
|
+
missingEntries.forEach(entry => {
|
|
581
|
+
if (!entry.startsWith('#')) {
|
|
582
|
+
info(` + ${entry}`);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
} else {
|
|
586
|
+
info('.gitignore ya contiene todas las entradas necesarias');
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
506
590
|
// Configurar Git (line endings, etc.)
|
|
507
591
|
function configureGit() {
|
|
508
592
|
info('Configurando Git...');
|
|
@@ -631,12 +715,40 @@ function status() {
|
|
|
631
715
|
console.log('\nArchivos de pautas:');
|
|
632
716
|
const guidelines = ['CLAUDE_PRE_COMMIT.md', 'CLAUDE_PRE_COMMIT_SONAR.md'];
|
|
633
717
|
guidelines.forEach(guideline => {
|
|
634
|
-
|
|
635
|
-
|
|
718
|
+
const claudePath = path.join('.claude', guideline);
|
|
719
|
+
if (fs.existsSync(claudePath)) {
|
|
720
|
+
success(`${guideline}: presente en .claude/`);
|
|
721
|
+
} else if (fs.existsSync(guideline)) {
|
|
722
|
+
warning(`${guideline}: presente en raíz (debería estar en .claude/)`);
|
|
636
723
|
} else {
|
|
637
724
|
warning(`${guideline}: faltante`);
|
|
638
725
|
}
|
|
639
726
|
});
|
|
727
|
+
|
|
728
|
+
// Verificar entradas en .gitignore
|
|
729
|
+
console.log('\n.gitignore:');
|
|
730
|
+
const gitignorePath = '.gitignore';
|
|
731
|
+
if (fs.existsSync(gitignorePath)) {
|
|
732
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
733
|
+
const claudeIgnores = ['.claude/', '.claude-analysis-mode', 'debug-claude-response.json'];
|
|
734
|
+
let allPresent = true;
|
|
735
|
+
|
|
736
|
+
claudeIgnores.forEach(entry => {
|
|
737
|
+
const regex = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'm');
|
|
738
|
+
if (regex.test(gitignoreContent)) {
|
|
739
|
+
success(`${entry}: incluido`);
|
|
740
|
+
} else {
|
|
741
|
+
warning(`${entry}: faltante`);
|
|
742
|
+
allPresent = false;
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
if (!allPresent) {
|
|
747
|
+
info('\nEjecuta "claude-hooks install" para actualizar .gitignore');
|
|
748
|
+
}
|
|
749
|
+
} else {
|
|
750
|
+
warning('.gitignore no existe');
|
|
751
|
+
}
|
|
640
752
|
}
|
|
641
753
|
|
|
642
754
|
// Comando set-mode
|
package/package.json
CHANGED
|
@@ -23,6 +23,11 @@ Evaluar el código modificado siguiendo métricas similares a SonarQube para ase
|
|
|
23
23
|
- Duplicación de código
|
|
24
24
|
- Deuda técnica
|
|
25
25
|
|
|
26
|
+
### Métricas Adicionales
|
|
27
|
+
- **Coverage**: Porcentaje estimado de cobertura de pruebas (0-100)
|
|
28
|
+
- **Duplications**: Porcentaje estimado de código duplicado (0-100)
|
|
29
|
+
- **Complexity**: Complejidad ciclomática promedio del código
|
|
30
|
+
|
|
26
31
|
## Clasificación de Issues
|
|
27
32
|
|
|
28
33
|
### Severidad
|
|
@@ -42,7 +47,10 @@ Responde ÚNICAMENTE con un JSON válido siguiendo esta estructura:
|
|
|
42
47
|
"metrics": {
|
|
43
48
|
"reliability": "A/B/C/D/E",
|
|
44
49
|
"security": "A/B/C/D/E",
|
|
45
|
-
"maintainability": "A/B/C/D/E"
|
|
50
|
+
"maintainability": "A/B/C/D/E",
|
|
51
|
+
"coverage": 75,
|
|
52
|
+
"duplications": 5,
|
|
53
|
+
"complexity": 15
|
|
46
54
|
},
|
|
47
55
|
"issues": {
|
|
48
56
|
"blocker": 0,
|
|
@@ -60,7 +68,9 @@ Responde ÚNICAMENTE con un JSON válido siguiendo esta estructura:
|
|
|
60
68
|
"line": 42
|
|
61
69
|
}
|
|
62
70
|
],
|
|
63
|
-
"securityHotspots": 0
|
|
71
|
+
"securityHotspots": 0,
|
|
72
|
+
"approved": true/false,
|
|
73
|
+
"blockingIssues": ["Lista de problemas bloqueantes si existen"]
|
|
64
74
|
}
|
|
65
75
|
```
|
|
66
76
|
|
package/templates/pre-commit
CHANGED
|
@@ -64,10 +64,10 @@ if [ "$ANALYSIS_MODE" != "standard" ] && [ "$ANALYSIS_MODE" != "sonar" ]; then
|
|
|
64
64
|
|
|
65
65
|
if [ "$REPLY" = "2" ]; then
|
|
66
66
|
ANALYSIS_MODE="sonar"
|
|
67
|
-
GUIDELINES_FILE="CLAUDE_PRE_COMMIT_SONAR.md"
|
|
67
|
+
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
|
|
68
68
|
else
|
|
69
69
|
ANALYSIS_MODE="standard"
|
|
70
|
-
GUIDELINES_FILE="CLAUDE_PRE_COMMIT.md"
|
|
70
|
+
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
|
|
71
71
|
fi
|
|
72
72
|
|
|
73
73
|
# Guardar preferencia para futuros commits
|
|
@@ -78,10 +78,10 @@ if [ "$ANALYSIS_MODE" != "standard" ] && [ "$ANALYSIS_MODE" != "sonar" ]; then
|
|
|
78
78
|
else
|
|
79
79
|
# Usar modo guardado
|
|
80
80
|
if [ "$ANALYSIS_MODE" = "sonar" ]; then
|
|
81
|
-
GUIDELINES_FILE="CLAUDE_PRE_COMMIT_SONAR.md"
|
|
81
|
+
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT_SONAR.md"
|
|
82
82
|
log "Usando modo de análisis: SonarQube"
|
|
83
83
|
else
|
|
84
|
-
GUIDELINES_FILE="CLAUDE_PRE_COMMIT.md"
|
|
84
|
+
GUIDELINES_FILE=".claude/CLAUDE_PRE_COMMIT.md"
|
|
85
85
|
log "Usando modo de análisis: Estándar"
|
|
86
86
|
fi
|
|
87
87
|
fi
|
|
@@ -233,7 +233,7 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
|
|
|
233
233
|
BLOCKING_ISSUES=$(echo "$JSON_RESPONSE" | jq -r '.blockingIssues[]?' 2>/dev/null | sed '/^$/d')
|
|
234
234
|
|
|
235
235
|
# Verificar si estamos en modo SonarQube
|
|
236
|
-
QUALITY_GATE=$(echo "$JSON_RESPONSE" | jq -r '.
|
|
236
|
+
QUALITY_GATE=$(echo "$JSON_RESPONSE" | jq -r '.QUALITY_GATE // ""' 2>/dev/null)
|
|
237
237
|
|
|
238
238
|
if [ "$ANALYSIS_MODE" = "sonar" ] && [ -n "$QUALITY_GATE" ] && [ "$QUALITY_GATE" != "null" ]; then
|
|
239
239
|
# Mostrar resultados estilo SonarQube
|
|
@@ -265,15 +265,15 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
|
|
|
265
265
|
fi
|
|
266
266
|
|
|
267
267
|
# Issues Summary
|
|
268
|
-
|
|
269
|
-
if [ "$
|
|
268
|
+
ISSUES=$(echo "$JSON_RESPONSE" | jq -r '.issues // {}' 2>/dev/null)
|
|
269
|
+
if [ "$ISSUES" != "{}" ] && [ "$ISSUES" != "null" ]; then
|
|
270
270
|
echo "📋 ISSUES SUMMARY"
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
271
|
+
BLOCKER=$(echo "$ISSUES" | jq -r '.blocker // 0' 2>/dev/null)
|
|
272
|
+
CRITICAL=$(echo "$ISSUES" | jq -r '.critical // 0' 2>/dev/null)
|
|
273
|
+
MAJOR=$(echo "$ISSUES" | jq -r '.major // 0' 2>/dev/null)
|
|
274
|
+
MINOR=$(echo "$ISSUES" | jq -r '.minor // 0' 2>/dev/null)
|
|
275
|
+
INFO=$(echo "$ISSUES" | jq -r '.info // 0' 2>/dev/null)
|
|
276
|
+
TOTAL=$((BLOCKER + CRITICAL + MAJOR + MINOR + INFO))
|
|
277
277
|
|
|
278
278
|
echo "Total: $TOTAL issues found"
|
|
279
279
|
[ "$BLOCKER" -gt 0 ] && echo -e " ${RED}🔴 Blocker: $BLOCKER${NC}"
|
|
@@ -285,18 +285,19 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
|
|
|
285
285
|
fi
|
|
286
286
|
|
|
287
287
|
# Detailed Issues
|
|
288
|
-
|
|
289
|
-
if [ "$
|
|
288
|
+
DETAILS_COUNT=$(echo "$JSON_RESPONSE" | jq -r '.details | length' 2>/dev/null)
|
|
289
|
+
if [ "$DETAILS_COUNT" -gt 0 ] 2>/dev/null; then
|
|
290
290
|
echo "🔍 DETAILED ISSUES"
|
|
291
|
-
echo "$JSON_RESPONSE" | jq -r '.
|
|
292
|
-
"[\(.severity)] \(.type) in \(.file):\(.line // "?")\n \(.message)\n
|
|
291
|
+
echo "$JSON_RESPONSE" | jq -r '.details[]? |
|
|
292
|
+
"[\(.severity)] \(.type) in \(.file):\(.line // "?")\n \(.message)\n"' 2>/dev/null
|
|
293
293
|
fi
|
|
294
294
|
|
|
295
295
|
# Security Hotspots
|
|
296
|
-
|
|
297
|
-
if [ "$
|
|
298
|
-
echo "🔥 SECURITY HOTSPOTS"
|
|
299
|
-
echo "
|
|
296
|
+
HOTSPOTS=$(echo "$JSON_RESPONSE" | jq -r '.securityHotspots // 0' 2>/dev/null)
|
|
297
|
+
if [ "$HOTSPOTS" -gt 0 ] 2>/dev/null; then
|
|
298
|
+
echo "🔥 SECURITY HOTSPOTS: $HOTSPOTS found"
|
|
299
|
+
echo " Review security-sensitive code carefully"
|
|
300
|
+
|
|
300
301
|
echo
|
|
301
302
|
fi
|
|
302
303
|
|
|
@@ -332,11 +333,18 @@ if $CLAUDE_CLI < "$PROMPT_FILE" > "$RESPONSE_FILE" 2>&1; then
|
|
|
332
333
|
exit 1
|
|
333
334
|
fi
|
|
334
335
|
|
|
335
|
-
|
|
336
|
-
|
|
336
|
+
# Mostrar detalles adicionales si existen
|
|
337
|
+
DETAILS=$(echo "$JSON_RESPONSE" | jq -r '.details // null')
|
|
338
|
+
if [ -n "$DETAILS" ] && [ "$DETAILS" != "null" ]; then
|
|
337
339
|
echo
|
|
338
|
-
echo "=== DETALLES
|
|
339
|
-
|
|
340
|
+
echo "=== DETALLES ADICIONALES ==="
|
|
341
|
+
# Si details es un string, imprimirlo directamente
|
|
342
|
+
if echo "$DETAILS" | jq -e 'type == "string"' >/dev/null 2>&1; then
|
|
343
|
+
echo "$DETAILS" | jq -r '.'
|
|
344
|
+
# Si es un objeto o array, formatearlo
|
|
345
|
+
else
|
|
346
|
+
echo "$DETAILS" | jq '.'
|
|
347
|
+
fi
|
|
340
348
|
fi
|
|
341
349
|
|
|
342
350
|
log "✅ Revisión completada. Commit aprobado (Score: $SCORE/10)"
|
|
File without changes
|