Controla la calidad del código con SonarQube

El software SonarQube, anteriormente llamado Sonar es la plataforma abierta más popular para gestionar la calidad del software.

Todos los implicados en el desarrollo de software estamos concienciados en que es indispensable construir buen código, aunque estarás de acuerdo conmigo en que no siempre se consigue. Errores en el software han provocado graves problemas, pérdidas millonarias, e incluso muerte de personas. Podéis leer los siguientes ejemplos: List of software bugs y Top 8 de errores informáticos más costosos de la historia.

Sonarqube nos ayuda en nuestra tarea. Es software libre y evalúa el código fuente usando diversas herramientas de análisis cómo Checkstyle, PMD o FindBugs. Este análisis se consolida en métricas que nos ayudarán a medir y mejorar la calidad de nuestro software. La plataforma cubre 7 ejes para realizar el análisis:

  • Reglas de codificación
  • Diseño y Arquitectura
  • Código duplicado
  • Complejidad del código
  • Pruebas unitarias
  • Errores potenciales
  • Comentarios en el código

sonar1

SonarQube es extensible mediante plugins, de manera que es posible analizar más de 20 lenguajes de programación, incluidos Java, C#, C/C++, PL/SQL, Cobol… Estos plugins permiten de igual manera añadir nuevos lenguajes e incorporar nuevas reglas o métricas avanzadas.

SonarQube es una aplicación basada en web, por lo que las reglas, alertas, configuraciones y demás se pueden configurar online. Además, su base de datos embebida puede ampliarse y configurar una externa como MySQL, Oracle, PostgreSQL, etc. No sólo permite combinar métricas, sino también comparar con las medidas históricas. Otra característica primordial es que puede integrarse en servidores de integración continua.

Instalación

La plataforma está compuesta de tres elementos:

  • Una base de datos para almacenar la configuración de la instancia y los resultados del análisis de proyectos, vistas, etc.
  • Un servidor web para visualizar los análisis y configurar la instancia.
  • Uno o más analizadores para analizar proyectos.

Como hemos dicho SonarQube se distribuye con una base de datos embebida, así que para comenzar a trabajar tan solo tenemos que descargar la última versión del servidor y descomprimirla en un directorio.

Una vez completada, ejecutamos el proceso del servidor ejecutando:

  • Linux / Mac: <directorio_instalación>/bin/<tu_sistema_operativo>/sonar.sh
  • Windows: <directorio_instalación>/bin/windows-x86-XX/StartSonar.bat

Por defecto está configurado en el puerto 9000 (http://localhost:9000), pero es posible modificarlo en el fichero de configuración sonar.properties que se encuentra en el directorio conf del directorio de instalación.

Analizadores

Están disponibles los siguientes analizadores:

  • SonarQube runner: recomendado para proyectos sin Maven
  • Maven: recomendado para proyectos “mavenizados
  • SonarQube Ant Task: Para integrar proyectos con Ant
  • Gradle: Para integrar proyectos construidos con Gradle
  • Continuous integration: Plugins para Jenkins, Hudson, Bamboo o AnthillPro.

SonarQube runner es un analizador manual, de manera que ejecutaremos el programa cada vez que queramos realizar un análisis de código. Mediante un fichero de configuración indicaremos tanto la carpeta dónde se encuentra el código fuente como la versión de análisis. Los demás analizadores son programados, por lo que el analizador se ejecutará cuando sea necesario, bien sea una vez al día, cada vez que se construye el proyecto, cada vez que se sube al control de fuentes, todo a la vez, etc.

Métricas

El cuadro de mando de SonarQube es una interfaz web donde podemos ver los resultados del análisis con los puntos débiles a mejorar. Puedes ver un cuadro de mando SonarQube en nemo.sonarqube.org. Las métricas que puedes consultar las configuramos según nuestras necesidades pero por defecto se muestran las siguientes:

  1. Complejidad. Complejidad ciclomática. Cada vez que sonarqube encuentra una sentencia“if”,”for”,”while”,”case”,”catch”, “throw”,”return” (sin ser la última sentencia de un método), “&&”, “||”, “?”, “else”, se aumenta el contador global de complejidad ciclomática en 1. También se aumenta en 1 el contador por la cabecera del método. Otros valores para la complejidad son:
    • Complejidad/método. Media de la complejidad por cada método. debería sobrepasar el valor de 30.
    • Complejidad/clase. Media de la complejidad de todas las clases. Un valor muy elevado de complejidad ciclomática por clase, nos indica síntomas de un mal diseño.
    • Complejidad/fichero. Media de la complejidad por fichero.
  2. Código duplicado. Cuanto mayor sea la complejidad ciclomática y la duplicidad de código, más difícil será mantener el software, por tanto se trata de una métrica básica. Por defecto se considera una duplicidad de código cuando 10 líneas sucesivas de código se encuentran duplicadas. Sonarqube nos muestra las siguientes métricas para esta categoría.
    • Líneas duplicadas.
    • Bloques duplicados.
    • Archivos duplicados.
    • Número de líneas duplicadas (%). (Número de líneas duplicadas/Número total de líneas) *100
  3. Comentarios. La información mostrada para esta categoría:
    • Líneas comentadas. Número de líneas con comentario.
    • Comentarios (%). Si el valor es un 50% indica que la mitad del fichero es código y la mitad comentarios, si es un 100% indica que son todo comentarios.
  4. Test. Muestra el tanto por ciento de cobertura de pruebas unitarias del proyecto, y en caso de que las haya, cuántas de ellas ha pasado nuestro software. Si bien para otras métricas únicamente es necesario analizar el código fuente, para obtener resultados en esta categoría es necesario compilar el código para la ejecución de las pruebas.
  5. Violaciones.
    • “Issues”. Número de violaciones o malas prácticas en el código
    • Cumplimiento de reglas (%): Se calcula con la siguiente fórmula:

100 -((Violaciones ponderadas / Líneas de código) * 100)

Las violaciones ponderadas son la suma de todas las violaciones multiplicadas por su severidad (10 para las violaciones bloqueantes, 5 para las críticas, 3 para las mayores y 1 para las menores). Estos valores pueden ser modificados cuando accedemos como administradores.

 Deuda Técnica

Una de las medidas que no podemos obviar de Sonarqube es la deuda técnica. Es un valor en días que vendría a ser el tiempo aproximado que nos llevaría subsanar todos los problemas encontrados en nuestro software. Según la entrada de wikipedia, es un eufemismo tecnológico que hace referencia a las consecuencias de un desarrollo apresurado de software o un despliegue descuidado de hardware.

sonar2

El origen del término fue propuesto por Ward Cunningham en 1992. En el siguiente vídeo habla sobre este término.

En definitiva, Sonarqube nos va a ayudar a mantener una buena calidad del software construido, comparando las diferentes versiones y almacenando un histórico de las métricas informadas. Hoy en día es una herramienta clave, de uso casi obligado para evaluar el código entregado y liberado a nuestros clientes.

Integrar Twitter Bootstrap con Ruby on Rails

Twitter Bootstrap es un framework que nos ayuda a desarrollar de forma rápida aplicaciones web. Provee una amplia variedad de código CSS y Javascript para implementar layouts, navegaciones y formularios, así como soporte para diseño adaptativo (Responsive Web Design).

Una opción para usar Bootstrap es la de descargarnos desde la página del framework el CSS y el Javascript e importarlos en el directorio /app/assets/ de nuestro proyecto rails, pero esta no sería la mejor manera de hacerlo si usamos Rails. Twitter Boostrap está escrito con LESS, que es un preprocesador de CSS similar al que usa Rails (SASS), así que si queremos aprovechar todo el potencial de Bootstrap, deberíamos usar un lenguaje como LESS, en lugar de ficheros estáticos. Para integrar LESS con Rails debemos usar varias gemas, como twitter-bootstrap-rails, que es la que yo he usado, aunque hay otras opciones.

Para integrar Bootstrap debemos partir de una aplicación rails ya creada mediante la orden rails new [nombre_app], así como algún modelo del tipo rails g scaffold product name price:decimal –skip-stylesheets. Hemos utilizado la opción --skip-stylesheets porque queremos utilizar las CSS de Bootstrap en lugar de la que sería generada automáticamente. Después, generamos la tabla en base de datos con rake db:migrate. Una vez hecho esto ya es posible ejecutar la aplicación pero con un aspecto nada atractivo todavía. Es hora de integrar Bootstrap.

Lo primero que hay que hacer es añadir la gema twitter-bootstrap-rails al fichero Gemfile que se encuentra en el directorio raíz de la aplicación.

/Gemfile
# Gems used only for assets and not required
# in production environments by default.
group :assets do
        gem 'sass-rails',   '~> 3.2.3'
        gem 'coffee-rails', '~> 3.2.1'

        # See https://github.com/sstephenson/execjs#readme for more supported runtimes
        # gem 'therubyracer'

        gem 'uglifier', '>= 1.0.3'
        gem 'twitter-bootstrap-rails'
end

Instalamos twitter-bootstrap-rails y sus dependencias (libv8 y less-rails) ejecutando bundle install. Una vez ejecutada la orden anterior, llamamos al generador para finalizar el proceso de instalación y colocar Bootstrap (javascript, css) en el directorio /app/assets.

$ rails g bootstrap:install
insert  app/assets/javascripts/application.js
create  app/assets/javascripts/bootstrap.js.coffee
create  app/assets/stylesheets/bootstrap_and_overrides.css.less
gsub  app/assets/stylesheets/application.css
gsub  app/assets/stylesheets/application.css

En el directorio css está situado el fichero bootstrap_and_overrides.css.less, que es el sitio ideal para personalizar nuestros estilos de la aplicación. De echo, si ejecutamos a continuación la aplicación, veremos que la misma tiene otro aspecto, aunque aún es mejorable.

A partir de ahora empezaríamos a diseñar el layout de la aplicación. Editaremos el fichero application.html.erb para incluir el header (encabezado) de todas las páginas de la aplicación:

/app/views/layouts/application.html.erb 
<!DOCTYPE html>
<html>
    <head>
            <title>Store</title>
            <%= stylesheet_link_tag    "application", :media => "all" %>
            <%= javascript_include_tag "application" %>
            <%= csrf_meta_tags %>
    </head>
    <body>
        <div class="container">
                <%= yield %>
        </div>
    </body>
</html>

Con el código insertado entre los tags head mejoramos el comportamiento de HTML5 para versiones anteriores de Internet Explorer, e incluimos los META para incluir Responsive Design para su mejor visualización en los dispositivos móviles. A partir de este momento podemos incorporar cualquier elemento que aparece en la sección de componentes de Bootstrap siguiendo la documentación existente, de manera fácil e intuitiva y utilizando el fichero bootstrap_and_overrides.css.less para personalizar los estilos.

Lo Básico

Si nunca has utilizado Bootstrap debes saber que utiliza un sistema de rejilla de 12 columnas, lo que facilita la creación de un layout especificando la anchura de cada columna. Este layout será responsive, por lo que si modificamos el ancho de la ventana, el contenido se adaptará al nuevo ancho, ideal para visualizar el diseño con un smartphone o tablet. Un ejemplo sería el siguiente, que crea una barra lateral con tamaño de 3 columnas (span3) y el contenido de nuestra aplicación en 9 columnas (span9).

 /app/views/layouts/application.html.erb 
<!DOCTYPE html>
<html>
    <head>
            <title>Store</title>
            <%= stylesheet_link_tag    "application", :media => "all" %>
            <%= javascript_include_tag "application" %>
            <%= csrf_meta_tags %>
    </head>
    <body>
        <div class="container">
                 <div class="row">
                      <div class="span9"><%= yield %></div>
                      <div class="span3">
                         <h2>About Us</h2>
                         <p>Lorem ipsum dolor sit amet, 
consectetur adipisicing elit, sed do eiusmod tempor incididunt 
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 
consequat. Duis aute irure dolor in reprehenderit in voluptate 
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint 
occaecat cupidatat non proident, sunt in culpa qui officia deserunt 
mollit anim id est laborum.</p>        
                      </div>
                 </div>
       </div>
    </body>
</html>

Para añadir una barra de navegación responsive en la parte superior de la pantalla, cuyo menú se colapse en un icono desplegable con los enlaces del menú cuando el ancho de la ventana se reduzca, Bootstrap incluye estilos para el siguiente código:

/app/views/layouts/application.html.erb
<div>
    <div>
        <div>
            <a data-toggle="collapse" data-target=".nav-collapse">
                <span></span>
                <span></span>
                <span></span>
            </a>
            <a href="#">Some Store</a>
            <div>
                <ul>
                    <li><%= link_to "Browse Products", products_path %>
                          </li>
                    <li><%= link_to "Price List" %></li>
                    <li><%= link_to "Contact Us" %></li>
                    <li><%= link_to "Cart" %></li>
                </ul>
            </div>
        </div>
    </div>
</div>

 

somestore

En este post hemos visto como integrar Bootstrap en una aplicación rails mediante twitter-bootstrap-rails, como personalizar los estilos en el fichero bootstrap_and_overrides.css.less mediante LESS y como incorporar componentes básicos en nuestra aplicación.

Menú Contextual en tu Aplicación Web

Si necesitas incluir un menú contextual en tu página web, puedes hacerlo de una forma sencilla con el siguiente plugin jQuery

¿Quieres incluir un menú contextual en tu página web? Puedes hacerlo de una forma sencilla incorporando el plugin ContextMenu de jQuery. Se trata de un plugin ligero que te permite sobrescribir selectivamente el menú contextual del navegador al pulsar sobre el botón derecho del ratón. También comentaré la forma de que responda tanto a la pulsación sobre el botón derecho como al izquierdo.

Sus características son las siguientes:

  • Uso de múltiples menús diferentes en un página
  • Un menú puede ser asociado para que responda a varios elementos de la página
  • Los estilos de los menús son totalmente personalizables
  • Permite opciones de menú con iconos
  • Acciones asociadas a callbacks sensibles al contexto.

El único requisito es haber incluido en la aplicación el framework jQuery. Funciona en todos los navegadores, por lo que no tendremos problemas con compatibilidades. Puedes descargarlo desde aquí: jquery.contextmenu.r2.js para incluirlo en tus páginas o aplicaciones web

Uso

La estructura del menú se construye con HTML, incluyendo cada opción de menú en una lista no ordenada dentro de una capa, con la clase “contextMenu” y con el id que prefieras y que utilizarás para referenciarlo. Dentro de la página esta capa puede ir en cualquier posición.

Puedes definir tantos menús como necesites. Cada elemento <li> de la lista de la capa actuará como una opción de menú. Dando a cada <li> un id único las acciones pueden ser ligadas a ese menú.

A continuación se muestra un ejemplo. En la página HTML incluiremos el código del div del menú con las opciones que necesitamos:

    <div id="myMenu1" class="contextMenu" style="display: none">

      <ul>

        <li id="open"><img src="folder.png" /> Open</li>

        <li id="email"><img src="email.png" /> Email</li>

        <li id="save"><img src="disk.png" /> Save</li>

        <li id="close"><img src="cross.png" /> Close</li>

      </ul>

    </div>

El código javascript para enlazar cada opción con el código a ejecutar es el siguiente:

    $('span.demo1').contextMenu('myMenu1', {
      bindings: {

        'open': function(t) {
          alert('Trigger was '+t.id+'\nAction was Open');
        },

        'email': function(t) {
          alert('Trigger was '+t.id+'\nAction was Email');
        },

        'save': function(t) {
          alert('Trigger was '+t.id+'\nAction was Save');
        },

        'delete': function(t) {
          alert('Trigger was '+t.id+'\nAction was Delete');
        }
      }

    });

Menú de ejemplo

Parámetros

menu_id: Puedes asociar uno o más elementos de la página a un menú. Por ejemplo si invocamos al context menú de esta forma $("table td").contextMenu("myMenu1"), todas las celdas de una tabla mostrarán el menú al pulsar sobre ellas el botón derecho.

Configuración: Podemos usar la configuración por defecto o bien podemos opcionalmente  modificarla. En el ejemplo de arriba hemos visto cómo asociar la acción que se va a ejecutar para cada id del menú. Para añadir más deben ir separados por comas. El elemento que dispara el menú actual es pasado como parámetro.

  • menuStyle: Contiene pares nombre-valor para aplicar estilos al tag <ul> del menú.
  • itemStyle: Contiene pares nombre-valor para aplicar estilos a los elementos <li> del menú
  • itemHoverStyle: Idéntico al anterior pero aplica cuando se pasa el ratón sobre el elemento <li>, para resaltarlo, etc.
  • shadow: Boolean que identifica si se quiere mostrar la sombra del menú. Por defecto es true.

Puedes ver más en la página oficial del plugin. También es posible ampliar las opciones por defecto de todos los menús invocando al método defaults. Cualquier configuración excepto bindings puede ser usado como por defecto:

  $.contextMenu.defaults({
    menuStyle : {
      border : "2px solid green"
    },

    shadow: false,
    onContextMenu: function(e) {
      alert('Did someone asked for a context menu?!');
    }
  });

Menú contextual pulsando el botón izquierdo del ratón

Por defecto, este plugin funciona pulsando sobre el elemento que queremos que muestre el menú, con el botón derecho del ratón. Para modificar este comportamiento, y que se muestre igualmente al pulsar sobre el botón izquierdo, debemos abrir el fichero descargado del plugin (jquery.contextmenu.r2.js) y abrirlo para editar. Necesitamos modificar la línea:

return $(this).bind('contextmenu', function(e) {

por esta otra:

return $(this).bind('click', function(e) {

Placeholder en Internet Explorer

Placeholder es un atributo HTML5 utilizado como una pequeña pista o descripción corta del valor esperado en un campo de texto dentro de un formulario. Funciona en los campos input de tipo: text, search, url, tel, email y password. Es soportado por todos los navegadores (Firefox, Opera, Chrome, Safari, etc.), pero existe un problema si quieres utilizarlo con Internet Explorer (de momento ninguna versión lo soporta).

Placeholder es un atributo HTML5 utilizado como una pequeña pista o descripción corta del valor esperado en un campo de texto dentro de un formulario, como por ejemplo “Buscar”, “Introduzca su e-mail”, etc. Esta descripción se muestra dentro de la caja de texto cuando éste se encuentra vacío y desaparece cuando el elemento obtiene el foco.

Cómo hemos dicho se encuentra disponible desde la versión de HTML5 y su uso se encuentra bastante extendido en aplicaciones y páginas a lo largo y ancho de Internet. Funciona en los campos input de tipo: text, search, url, tel, email y password. Es soportado por todos los navegadores (Firefox, Opera, Chrome, Safari, etc.), pero existe un problema si quieres utilizarlo con Internet Explorer (de momento ninguna versión lo soporta).

Navegando por la web en busca de una solución para aplicar a uno de los proyectos en los que trabajo, cuya interfaz debe ser similar en todos los navegadores, encontré ésta que usa jQuery. jQuery es una librería javascript, que siempre es aplicable a multitud de problemas y usos, para alterar el comportamiento y visualización de los documentos web en navegadores, así como realizar peticiones asíncronas (ajax), y de la que ya os he hablado en otros artículos.

Podemos usar el siguiente código:

$(function() {
    if(!$.support.placeholder) {

            var active = document.activeElement;

            $(':text').focus(function () {
                    if ($(this).attr('placeholder') != '' && $(this).val() == $(this).attr('placeholder')) {
                            $(this).val('').removeClass('hasPlaceholder');
                    }

            }).blur(function () {
                    if ($(this).attr('placeholder') != '' && ($(this).val() == '' || $(this).val() == $(this).attr('placeholder'))) {
                            $(this).val($(this).attr('placeholder')).addClass('hasPlaceholder');
                    }
            });

            $(':text').blur();
            $(active).focus();

            $('form').submit(function () {
                    $(this).find('.hasPlaceholder').each(function() { $(this).val(''); });
            });

    }
});

Y este podría ser el css con el estilo, ya que el color de la letra del placeholder aparecería en un tono más grisáceo, como difuminado:

.hasPlaceholder { color: #777; } 

Lo que hace el código es sobreescribir el evento focus (posicionas el foco) y blur (el foco abandona el elemento) para elementos de tipo texto, en aquellos navegadores que no soportan el atributo placeholder, vamos en IE. Cuando se producen dichos eventos, leen el texto del atributo placeholder y lo muestran como valor del elemento (blur) aplicando la clase hasplaceholder, o bien borran el valor del campo (focus) y eliminan la clase hasplaceholder del campo de texto.

También se sobreescribe el evento submit, para borrar todos los valores de los campos de texto que muestran el texto placeholder, justo antes de enviar el formulario al servidor evitando que esos campos tengan valores incorrectos.

Se trata de una solución bastante elegante y nada intrusiva, porque sólo se aplica si el navegador no soporta el atributo. En caso de utilizar placeholder con Firefox, Safari, Chrome… el código jQuery no tiene efecto.