CodeNarc: Análisis estático de código Groovy

Cuando escribimos código es esencial proseguir ciertas reglas, buenas prácticas, reglas de estilo, congruencia en exactamente el mismo,… mas a veces esto no es tan simple, y más cuando trabajamos en un equipo en el que, al final, cada miembro tiene ciertas manías. Una forma de progresar todo esto es usando un analizador estático de código.

Para Java tenemos ciertas herramientas como FindBugs, PMD y Checkstyle que llevamos usando a lo largo de bastante tiempo, mas tienen el inconveniente de que con Groovy no marchan apropiadamente. Para sustituir esta necesidad aparece CodeNarc.

CodeNarc es un analizador estático de código Groovy que deja advertir defectos, malas prácticas, inconsistencias, inconvenientes con el estilo del código,… y considerablemente más. Se trata de un framework muy flexible que a través de reglas de manera fácil configurables examina nuestro código para mostrarnos un detallado informe para que podamos mejorarlo.

Añadiendo CodeNarc a nuestro proyecto

O.K., nos hemos resuelto a prosperar nuestro código Groovy, ¿de qué forma agregamos CodeNarc al proyecto? Tenemos distintas formas de agregarlo conforme nuestras necesidades y género de proyecto:

Desde línea de comandos: Una forma sencillísima de ejecutar CodeNarc si bien seguramente no la más útil.
Labor Ant: Seguramente se trata de una de las maneras más viejas de ejecutar CodeNarc. Si tu proyecto aún se fundamenta en Ant y no has pensado en mudar a Gradle tres.x, esta es tu solución.
Desde un test JUnit: Forma muy curiosa de ejecutar el análisis de CodeNarc si bien seguramente poco útil.
Complemento de Maven: Si utilizas Maven como herramienta de construcción de tu proyecto esta va a ser la opción mejor pues el complemento se hace cargo de configurar todo y la integración es sencillísima.
Complemento de Gradle: Del mismo modo que en el caso precedente, si Gradle es tu herramienta de build, entonces este es el complemento a usar.
De manera adicional asimismo existen complementos para diferentes IDEs como IntelliJ y Eclipse, frameworks como Grails y Griffon o bien aun para Sonar y Jenkins.

Tipos de reglas

La última versión de CodeNarc, la 0.27.0, incluye trescientos cuarenta y ocho reglas agrupadas en veintidos categorías:

Básicas: Por servirnos de un ejemplo para revisar que no hay bloques else or finally vacíos.
Llaves: ¿Cuántas veces habéis visto if o bien else de una sola línea sin las llaves? Yo personalmente los odio pues son una fuente de bugs a futuro. Podemos activar reglas en esta categoría a fin de que efectúen esta clase de comprobaciones.
Concurrencia: En esta categoría hay reglas que verifican la congruencia de nuestro código concurrente cuando usamos synchronized o bien volatile eminentemente.
Convención: Por servirnos de un ejemplo cuando escribimos un if invertido, un if que puede ser transformado a un operador elvis,…
Excepciones: Contiene reglas que van a fallar si por servirnos de un ejemplo hacemos un throw de un NullPointerException.
Y hay muchas más como ciertas que verifican imports duplicados, variables sin emplear, if superfluos,…

Veamos un ejemplo

Configuración mínima

He creado un pequeño proyecto de ejemplo basado en Gradle con la configuración precisa y varias clases con diferentes infracciones para poder entender mejor de qué manera marcha CodeNarc. Podeis ir examinando los commits de forma individual para entender mejors los cambios.

La primera cosa que hacemos es agregar el complemento al fichero build.gradle y configurarlo:

apply plugin: 'codenarc'

codenarc undefined

Ahora agregamos el fichero de las reglas. Como veis he habilitado varias.

ruleset undefined

Con esto ya podemos iniciar con el análisis del código. Solo debemos ejecutar la labor check para revisar (en las primeras 2 labores) que se está ejecutando CodeNarc (codenarcMain) tanto para nuestro código para los tests (codenarcTest). Eso sí, como no tenemos nada en el proyecto el informe no se ha generado.

dólares americanos ./gradlew check
:codenarcMain NO-SOURCE
:codenarcTest NO-SOURCE
:compileJava NO-SOURCE
:compileGroovy NO-SOURCE
:processResources NO-SOURCE
:classes UP-TO-DATE
:compileTestJava NO-SOURCE
:compileTestGroovy NO-SOURCE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:test NO-SOURCE
:check UP-TO-DATE

BUILD SUCCESSFUL

Total time: 0.67 secs

Agregando código de incierta calidad

Vamos a iniciar con algo sencillísimo, sencillamente creamos la clase src/main/groovy/demo/Example1.groovy con lo siguiente:

package demo

class Ejemplo1 undefined

Si ahora ejecutamos nuevamente la labor check podemos revisar que se produce el informe con las infracciones y que además de esto la build falla.

Primer hallamos un bloque con la data de ejecución y la versión de CodeNarc con la que se ha generado el informe. Ahora tenemos un bloque de resumen por bulto con el total de ficheros con infracciones y asimismo el total de infracciones de prioridad 1, dos y tres. Después vamos a tener un bloque por cada fichero en el que vemos todas y cada una de las infracciones del fichero con la línea de código en donde están y un pequeño fragmento del mismo. Además de esto el nombre de la regla es un link a una descripción un tanto más detallada de lo que significa.

Agregando más código

Creamos ahora otro fichero en src/main/groovy/demo/Example2.groovy:

package demo

class Example2 undefined

Y si ejecutamos nuevamente CodeNarc vemos que tenemos nuevas infracciones: Sentencia if sin llaves, sentencia else sin llaves y longitud máxima de una línea.

Configurando y deshabilitando reglas

La primera cosa que deseamos eludir es que CodeNarc haga que falle la build cuando tenemos alguna infracción. Para esto, agregamos a la configuración en build.gradle:

codenarc undefined

Ahora ejecutándolo nuevamente vamos a ver que la build no falla. Todavía de esta forma proseguimos teniendo infracciones con las que es posible que no estemos conforme o bien que deseemos personalizar de cierta manera.

Vamos a deshabilitar la regla ClassJavadoc pues si bien sea una buena práctica redactar el Javadoc de todas y cada una nuestras clases públicas, para este proyecto de ejemplo no nos interesa.Para ello, primero debemos buscar exactamente en qué categoría está incluída la regla. Esto podemos hacerlo de manera directa en el índice de reglas. Después, editamos el fichero de reglas rules.groovy para deshabilitarla:

ruleset undefined

Si ahora producimos nuevamente el informe vemos que hemos arreglado esas infracciones.

De forma adicional, asimismo podemos excluir una regla en una clase específica. Imaginad que precisamos la clase vacía creada previamente mas no deseamos ni desactivar la regla (por el hecho de que entonces no advertiría más clases vacías) ni deseamos tener de forma perpetua esa infracción en el informe. Para esto podemos hacer empleo de la anotación @SuppressWarnings de Java:

package demo

@SuppressWarnings('EmptyClass')
class Example1 undefined

Y entonces, solo para ese fichero esa regla específica es ignorada:

Otra alternativa que tenemos libre es configurar ciertas reglas para amoldarlas a nuestras necesidades. De este modo, previamente vimos en el ejemplo dos que teníamos una infracción de tipo LineLength por el hecho de que una línea era mayor de ciento veinte caracteres. Pongamos que hemos decidido que deseamos permitir líneas de hasta ciento treinta caracteres:

ruleset undefined

Haciendo esto arreglaríamos nuevamente esta nueva infracción.

¿Y como configuro esto para comenzar?

Si no sois cuidadosísimos con el código que escribís y vuestro proyecto tiene cierto tamaño, lo más probable que ocurra solamente instalar CodeNarc es que tengais cientos o bien aun miles y miles de infracciones.Incluso siendo muy aprensivos probablemente haya ciertas reglas que no os agraden o bien que su configuración por defecto no se adapte a las necesidades del equipo. Mi consejo es que vayais examinando una por una las infracciones, leyendo la documentación de exactamente las mismas y decidais si las desactivais, las configurais a fin de que se amolden a vuestro estilo y por último, las respetais y corregís.

Una vez decididas las reglas y configuración con las que el equipo se siente cómodo, el paso final va a ser decidir los umbrales para hacer que la build falle. Esto deja tener builds válidas con determinados niveles de infracciones conforme la severidad de exactamente las mismas mas que, superados esos niveles, la build por último falle y os fuerce a corregirlas.Para hacer esto, editamos de nuevo el fichero build.gradle:

codenarc undefined

De esta forma, la build no va a fallar salvo que superemos alguno de esos umbrales.

Conclusiones

Hemos visto por qué razón es esencial asegurar el estilo y la calidad del código en nuestro proyecto y de qué manera una herramienta de análisis estático de código como CodeNarc nos puede asistir a lograrlo. Además de esto asimismo hemos comprobado que es muy simple de agregar a un proyecto y de configurar y personalizar para amoldarlo a nuestras necesidades.

Pues a veces no basta solo con pensar que escribimos buen código y además de esto asimismo testarlo, sino hay que tener herramientas que nos aseguren su calidad, homogeneidad y estilo. Para todo esto tratándose de código Groovy, indudablemente CodeNarc es el mejor.

Más información | CodeNarc
En turincon.net | Testando tus aplicaciones Java con Spock: tests más expresivos, simples de leer y sostener