Sonarqube

Sonarqube

Después de escuchar mucho sobre la agilidad y medir la calidad del código en muchos blogs, comencé a preguntar a amigos como revisaban sus proyectos.

La mayoría no lo hacían por que en sus empresas tienen un departamento de 'QA', a lo que yo les recomendé usar FindBugs , un plugin sencillo para Eclipse que conocí allí por el 2014 y que me salvo de muchas.

Al instalarlo y correrlo por primera vez me di cuenta de la falta que me hacia, ¿solo se media la calidad por los bugs?, ¿no había otra cosa que medir? , cuanto mas ví el termino deuda técnica en los blogs, sentí que algo estaba mal en mi código.

Creo que fue en este post donde encontré algo llamado Sonar.

Su nombre completo es Sonarqube, es un Software Open Source que te ayuda a medir la calidad del código, donde combina FindBugs con otros proyectos para medir prácticamente TODO y te lo da en una amigable interfaz web a modo de reportes.

¿Como se instala?

Al ser una aplicación cliente/servidor se necesita una base de datos SQL Server / Oracle / PostgreSQL y debemos blablabla ...
Puff! las instalaciones son tediosas, puedes irte a la antigua instalando base de datos desde 0 , pero en estos años, ¿quien no tiene Docker instalado en su maquina ?.

Instala Docker y docker-compose

Una vez hecho esto, debemos crear un directorio llamado Sonarqube y el archivo docker-compose.yml

version: "2"

services:

  sonarqube:
    image: sonarqube:latest
    ports:
      - "9000:9000"
    networks:
      - sonarnett
    environment:
      - SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar
    volumes:
      - sonarqube_conf:/opt/sonarqube/conf
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins

  db:
    image: postgres:9.6
    mem_limit: 256m
    networks:
      - sonarnett
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
    volumes:
      - postgresql:/var/lib/postgresql
      - postgresql_data:/var/lib/postgresql/data

networks:
  sonarnett:
    driver: bridge
  default:
    driver: bridge

volumes:
  sonarqube_conf:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_bundled-plugins:
  postgresql:
  postgresql_data:

Así se ve la salida de tree:

perales@linux-h4ne:~/Escritorio> tree sonarqube/
sonarqube/
└── docker-compose.yml

0 directories, 1 file
perales@linux-h4ne:~/Escritorio> 

Y ejecutamos docker-compose up

Veremos algo así:

Creating network "sonarqube_sonarnett" with driver "bridge"
Creating volume "sonarqube_sonarqube_conf" with default driver
Creating volume "sonarqube_sonarqube_data" with default driver
Creating volume "sonarqube_sonarqube_extensions" with default driver
Creating volume "sonarqube_sonarqube_bundled-plugins" with default driver
Creating volume "sonarqube_postgresql" with default driver
Creating volume "sonarqube_postgresql_data" with default driver
Pulling sonarqube (sonarqube:latest)...
latest: Pulling from library/sonarqube
e79bb959ec00: Pull complete
d4b7902036fe: Pull complete
1b2a72d4e030: Pull complete
d54db43011fd: Pull complete
1a97c78dad71: Pull complete
6dcb79eeeda4: Pull complete
bd56246cf4fd: Pull complete
88cea60f56c5: Pull complete
7ed4501359c8: Pull complete
4bbf191118e2: Pull complete
11032ed7b930: Pull complete
c59744850b29: Pull complete
Digest: sha256:7e3086215d86430bb1bde555d755605e351f59ed7fa721aaff0d7478b665086a
Status: Downloaded newer image for sonarqube:latest
Pulling db (postgres:9.6)...
9.6: Pulling from library/postgres
27833a3ba0a5: Already exists
ed00742830a6: Already exists
dc611c2aceba: Already exists
a61becab5279: Already exists
8dcff41e7aea: Already exists
820bf1bbf0d7: Already exists
050804429905: Already exists
782c81275334: Already exists
89de6f9e489b: Pull complete
6fd7948190c1: Pull complete
2b248dfe0f9f: Pull complete
2bb82f5734a9: Pull complete
6165fd6c366d: Pull complete
b91f3b4e0a77: Pull complete
Digest: sha256:ee723e25ac72edaede1c7209c33f295b56875bdee62fa08f913117c2fbca9287
Status: Downloaded newer image for postgres:9.6
Creating sonarqube_db_1        ... done
Creating sonarqube_sonarqube_1 ... done
Attaching to sonarqube_db_1, sonarqube_sonarqube_1

Al terminar el log de la consola entramos a la liga http://localhost:9000 y podremos ver la interfaz web.

Para loguearnos usamos admin, admin.

sonarqube

sonarqube

sonarqube

¿Como se usa?

Sonar esta vació, ¿como lo usamos?, la dinámica a seguir es la siguiente:

  • Tenemos un código fuente.

  • Agregamos un archivo de configuración de sonar(sonar-project.properties).

  • Generamos un token de autentificación y lo agregamos a la configuración.

  • Ejecutamos el analizador de código de nuestra preferencia.

Analicemos un proyecto de ejemplo:

Clonamos el repo

git clone https://github.com/ripper2hl/fuego.git

Agregamos el archivo sonar-project.properties

cd fuego/

touch sonar-project.properties

Aquí la documentación de como configurar lo

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner

Así debería de quedarnos:

sonar.projectName=fuego
sonar.projectKey=com.perales:fuego
sonar.host.url=http://localhost:9000
sonar.sources=src/
sonar.sourceEncoding=UTF-8

Para generar el token debemos ir a My Account que se encuentra en la parte superior derecha y después a la pestaña de Security, esta es la liga http://localhost:9000/account/security/ .

El token se agrega al archivo de propiedades como sonar.login

sonar.projectName=fuego
sonar.projectKey=com.perales:fuego
sonar.host.url=http://localhost:9000
sonar.sources=src/
sonar.sourceEncoding=UTF-8
sonar.login=1d5a5466cec2a33ead727a2082454e25b9cdef49

Ahora debemos ejecutar un Sonar Scanner , de los cuales existen diferentes tipos, para java existe uno que se combina con maven , pero nosotros usaremos un binario de propósito general, el cual funciona para cualquier lenguaje de programación.

En esta liga puedes descargar los binarios, GNU/Linux, Mac OS o Windows

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner

En GNU/Linux creamos un enlace simbólico para poder ejecutarlo desde terminal

ln -s ~/Descargas/sonar-scanner-3.3.0.1492-linux/bin/sonar-scanner ~/.local/bin/sonar-scanner

Si ejecutamos sonar-scanner --version nos debe mostrar esto:

sonar-scanner --version
INFO: Scanner configuration file: /home/perales/Descargas/sonar-scanner-3.3.0.1492-linux/conf/sonar-scanner.properties
INFO: Project root configuration file: NONE
INFO: SonarQube Scanner 3.3.0.1492
INFO: Java 1.8.0_121 Oracle Corporation (64-bit)
INFO: Linux 5.0.11-1-default amd64

Para analizar nuestro proyecto , solamente ejecutamos sonar-scanner en la raíz del proyecto y la terminal mostrara lo siguiente:

INFO: Scanner configuration file: /home/perales/Descargas/sonar-scanner-3.3.0.1492-linux/conf/sonar-scanner.properties
INFO: Project root configuration file: /home/perales/Documentos/git/fuego/sonar-project.properties
INFO: SonarQube Scanner 3.3.0.1492
INFO: Java 1.8.0_121 Oracle Corporation (64-bit)
INFO: Linux 5.0.11-1-default amd64
INFO: User cache: /home/perales/.sonar/cache
INFO: SonarQube server 7.7.0
INFO: Default locale: "es_MX", source code encoding: "UTF-8"
INFO: Load global settings
INFO: Load global settings (done) | time=275ms
INFO: Server id: 243B8A4D-AWqQ27WJuNHxbkg6tnXs
INFO: User cache: /home/perales/.sonar/cache
INFO: Load/download plugins
INFO: Load plugins index
INFO: Load plugins index (done) | time=125ms
INFO: Load/download plugins (done) | time=4077ms
INFO: Process project properties
INFO: Execute project builders
INFO: Execute project builders (done) | time=34ms
INFO: Project key: com.perales:fuego
INFO: Base dir: /home/perales/Documentos/git/fuego
INFO: Working dir: /home/perales/Documentos/git/fuego/.scannerwork
INFO: Load project settings for component key: 'com.perales:fuego'
INFO: Load project repositories
INFO: Load project repositories (done) | time=32ms
INFO: Load quality profiles
INFO: Load quality profiles (done) | time=305ms
INFO: Load active rules
INFO: Load active rules (done) | time=6580ms
INFO: Indexing files...
INFO: Project configuration:
INFO: 6 files indexed
INFO: 0 files ignored because of scm ignore settings
INFO: Quality profile for js: Sonar way
INFO: Quality profile for web: Sonar way
INFO: ------------- Run sensors on module fuego
INFO: Load metrics repository
INFO: Load metrics repository (done) | time=200ms
INFO: Sensor JaCoCo XML Report Importer [jacoco]
INFO: Sensor JaCoCo XML Report Importer [jacoco] (done) | time=11ms
INFO: Sensor SonarJS [javascript]
INFO: 3 source files to be analyzed
INFO: 3/3 source files have been analyzed
INFO: Sensor SonarJS [javascript] (done) | time=2646ms
INFO: Sensor ESLint-based SonarJS [javascript]
INFO: 3 source files to be analyzed
INFO: Sensor ESLint-based SonarJS [javascript] (done) | time=9792ms
INFO: Sensor JavaXmlSensor [java]
INFO: 3/3 source files have been analyzed
INFO: Sensor JavaXmlSensor [java] (done) | time=20ms
INFO: Sensor HTML [web]
INFO: Sensor HTML [web] (done) | time=395ms
INFO: ------------- Run sensors on project
INFO: Sensor Zero Coverage Sensor
INFO: Sensor Zero Coverage Sensor (done) | time=115ms
INFO: SCM provider for this project is: git
INFO: 4 files to be analyzed
INFO: 4/4 files analyzed
INFO: Calculating CPD for 4 files
INFO: CPD calculation finished
INFO: Analysis report generated in 451ms, dir size=91 KB
INFO: Analysis report compressed in 165ms, zip size=21 KB
INFO: Analysis report uploaded in 1700ms
INFO: ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard?id=com.perales%3Afuego
INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
INFO: More about the report processing at http://localhost:9000/api/ce/task?id=AWqie1fuYKZYNF3HzZ-O
INFO: Analysis total time: 36.800 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 44.311s
INFO: Final Memory: 18M/291M
INFO: ------------------------------------------------------------------------

Si vamos a la interfaz web, podremos ver los reportes generados.

sonarqube

sonarqube

sonarqube

sonarqube

Fuentes: