|
| 1 | +# Refactor plan checklist (plugin / repo) |
| 2 | + |
| 3 | +Estado al **2026-03-19**. Marca lo implementado en el código actual; úsalo para seguimiento del roadmap. |
| 4 | + |
| 5 | +Leyenda: **`[x]`** hecho · **`[ ]`** pendiente / parcial · **`[~]`** hecho con matices (ver nota) |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Fase 0 — Setup y calidad base |
| 10 | + |
| 11 | +- [x] Rama / flujo de trabajo acordado para cambios grandes del plugin |
| 12 | +- [x] Detekt en `plugin/build.gradle.kts` + `config/detekt/detekt.yml` + **baseline** (`baseline.xml`) |
| 13 | +- [x] Ktlint en el plugin (`ignoreFailures`, exclusión legacy `Vars.kt`) |
| 14 | +- [x] Develocity / build scan en `settings.gradle.kts` (publicación condicional a fallos) |
| 15 | +- [x] Tests JUnit 5 por defecto; tarea `:plugin:integrationTest` + `@Tag("integration")` para clones/nested Gradle |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## Fase 1 — Seguridad y ejecución |
| 20 | + |
| 21 | +- [x] Estado mutable del plugin migrado a **`StringCareBuildService`** + `StringCareSession` solo para tests |
| 22 | +- [x] Tareas críticas con **`usesService`** al build service |
| 23 | +- [x] Comandos shell vía **`ProcessBuilder`** (no shell inseguro directo en el path feliz) |
| 24 | +- [x] Timeout (~60s) y **`ExecutionResult.Timeout`** |
| 25 | +- [x] JNI del host: verificación **SHA-256** antes de cargar, reintentos, **`LoadResult`**, limpieza de temporales JNI (sin `deleteOnExit` como única estrategia) |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +## Fase 2 — Rendimiento y XML |
| 30 | + |
| 31 | +- [x] Parser **SAX-first** para `strings.xml` + **fallback DOM** si hay anidamiento / detector falla |
| 32 | +- [x] Fachada `XmlParser` / `StringsXmlParser`; `XParser` delega |
| 33 | +- [x] Walk de recursos con **prune** de `build/`, `.gradle/`, `.git/`, `node_modules/` |
| 34 | +- [x] `StringCareConfiguration.normalize()` idempotente |
| 35 | +- [x] Copia de backup **temp + move atómico** (`BackupCopy` + `ResourceFile` / `AssetsFile`) |
| 36 | +- [ ] Módulo **JMH** u otro benchmark reproducible para el parser |
| 37 | +- [ ] Regresión de rendimiento automatizada en CI |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +## Fase 3 — APIs Gradle |
| 42 | + |
| 43 | +- [x] Entradas de tareas como **`Property<>`** donde aplica |
| 44 | +- [x] **`@DisableCachingByDefault`** en tareas que mutan el árbol de fuentes (no `@CacheableTask`) |
| 45 | +- [x] Wiring con AGP: dependencias de merge/process/assets dentro de `onVariants {}` usando `tasks.matching { it.name == ... }.configureEach { ... }` (sin `afterEvaluate` ni `findByName`) |
| 46 | +- [x] Sustituido `afterEvaluate` por wiring lazy y seguro por nombre de tarea |
| 47 | +- [ ] Declarar **`@InputFiles` / outputs** fiables para tareas mutadoras (difícil mientras se editan fuentes in-place) |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## Fase 4 — Arquitectura (capas) |
| 52 | + |
| 53 | +- [x] Modelos en `domain.models` (`StringEntity`, `ResourceFile`, `AssetsFile`, `ExecutionResult`, `Backupable`, etc.) |
| 54 | +- [x] `infrastructure`: parsers, filesystem (`BackupService`), crypto (`ObfuscationService`), Gradle (`FileSystemResourceRepository`) |
| 55 | +- [x] Casos de uso / repositorios (`ObfuscateStringsUseCase`, `ResourceRepository`) |
| 56 | +- [x] AGP como **`compileOnly`** en el plugin |
| 57 | +- [x] JSON de listas con **kotlinx-serialization** (sin Gson) |
| 58 | +- [x] **`ExtractFingerprintUseCase`** en `domain.usecases` (tests pueden llamar `extract` con `log` por defecto; `extractFingerprint` delega desde `internal`) |
| 59 | +- [ ] Partir **`Extensions.kt`** en módulos más pequeños (Gradle vs FS vs XML) |
| 60 | + |
| 61 | +--- |
| 62 | + |
| 63 | +## Fase 5 — Kotlin y robustez |
| 64 | + |
| 65 | +- [x] Reducción de **`!!`** en fuentes principales del plugin (revisar periódicamente) |
| 66 | +- [x] Utilidades tipo `toReadableString` donde aplica |
| 67 | +- [~] API de ejecución: ahora **`execute(command: String)` → `Result<ExecutionResult>`** y existe overload con **`List<String>`**; queda como deuda dejar `List<String>` como API única |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +## Fase 6 — Tests y cobertura |
| 72 | + |
| 73 | +- [x] Tests unitarios por defecto **sin** integración pesada (`:plugin:test` excluye tag `integration`) |
| 74 | +- [x] JaCoCo: `jacocoTestReport` + **`jacocoTestCoverageVerification`** (umbral **bajo interino** ~12% líneas; objetivo roadmap **>80%**) |
| 75 | +- [x] Tests de infraestructura XML (`XmlParserInfrastructureTest`: SAX, DOM implícito, **UTF-16**, XML mal formado) |
| 76 | +- [x] `ObfuscationServiceTest` (roundtrip JNI con **`assumeTrue(Stark.isNativeLibLoaded() is LoadResult.Loaded)`)** |
| 77 | +- [x] `BackupServiceTest` vía `BackupService` + `defaultConfig()` |
| 78 | +- [x] Otros tests de configuración / JSON / fingerprint según el árbol actual (`ConfigurationNormalizationTest`, `FingerprintExtractionTest`, `JsonListsTest`, etc.) |
| 79 | +- [ ] Fixtures **`test-projects/`** minimalistas adicionales (además de samples existentes) |
| 80 | +- [ ] Cobertura **>80%** como gate duro en CI |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +## Fase 7 — Mantenibilidad |
| 85 | + |
| 86 | +- [x] Detekt con baseline (no “cero issues” sin baseline) |
| 87 | +- [ ] Subir poco a poco reglas / reducir baseline hasta acercarse a **Detekt sin baseline** |
| 88 | +- [x] Ktlint operativo; fallos no bloquean build (`ignoreFailures`) |
| 89 | +- [~] KDoc: presente en puntos clave; ampliar en APIs públicas internas del plugin |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## Fase 8 — Documentación y CI/CD |
| 94 | + |
| 95 | +- [x] `CHANGELOG.md` actualizado con hitos del refactor |
| 96 | +- [x] `MIGRATION.md` / docs de migración |
| 97 | +- [x] `SECURITY.md` y documentación de contribución / build |
| 98 | +- [x] `plugin/README.md` (requisitos, DSL avanzado, troubleshooting, rendimiento) |
| 99 | +- [x] **`.github/workflows/ci.yml`**: test, JaCoCo report + **verification**, detekt, integration opcional, `assembleDebug` |
| 100 | +- [x] **`.github/workflows/publish.yml`**: esqueleto (build JAR; publicación manual documentada) |
| 101 | +- [ ] **OWASP Dependency-Check** (o equivalente) en Gradle y/o CI del plugin |
| 102 | +- [ ] **Matriz CI** (p.ej. varias versiones AGP / Gradle) donde tenga sentido para el composite build |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +## Resumen rápido |
| 107 | + |
| 108 | +| Área | Estado | |
| 109 | +|-------------------|--------| |
| 110 | +| BuildService / JNI / ProcessBuilder | Listo | |
| 111 | +| XML SAX + DOM | Listo | |
| 112 | +| Backup atómico | Listo (sin locks ni dirs UUID dedicados) | |
| 113 | +| AGP wiring | Estable con `onVariants` + `tasks.matching(...).configureEach` | |
| 114 | +| Tests + JaCoCo | Listo con umbral bajo; subir cobertura | |
| 115 | +| OWASP / JMH / matriz AGP | Pendiente | |
| 116 | + |
| 117 | +--- |
| 118 | + |
| 119 | +*Si el plan original vive fuera del repo (p.ej. adjunto en Cursor), copia aquí los IDs `phase-*` y alinéalos con las secciones anteriores.* |
0 commit comments