miércoles, 20 de marzo de 2013

Travis CI: Integración continua en la nube

Con la aparición de GitHub se ha ido difuminando el concepto de proyecto de software libre tradicional así como la forma de colaborar en ellos. Basta con querer compartir un pequeño módulo o ejemplo para crear un repositorio en GitHub; la comunidad ya decidirá la relevancia de tu aportación.

Pero GitHub no solo ha hecho florecer los pequeños proyectos de cada uno, también ha hecho crecer el número de servicios que la nube ofrece a los desarrolladores. Un ejemplo de estos servicios es Travis CI que ofrece un servicio de integración contínua gratuito en la nube. La idea me parece muy buena: la integración contínua no tiene que ser algo exclusivo de proyectos a partir de cierto tamaño, ya que la calidad tampoco lo es.

Travis CI te permite compilar y probar el código de tus repositorios de GitHub de forma automatizada. Basta con añadir un fichero .travis.yml a tu repositorio con los detalles de cómo se compila y prueba, entrar en http://travis-ci.org, loguearte con GitHub y activar el servicio para tu repositorio.

Actualmente son incontables los proyectos en GitHub que utilizan Travis CI. Un ejemplo de estos es https://github.com/joyent/http-parser, donde podemos ver su fichero .travis.yml así como el indicador del estado de su última build.

martes, 19 de marzo de 2013

Testacular

A riesgo de que esto se convierta en una recopilación de vídeos que me han gustado en algún momento, quiero destacar otro vídeo. Esta vez sobre Testacular: un framework para test de código JavaScript. La automatización de todo lo que rodea al proceso de desarrollo siempre me ha parecido muy necesaria y me sorprende gratamente el nivel de automatización del proceso de test al que se puede llegar. Con Testacular, la simple modificación de un fichero implica que se ejecuten automáticamente todos los tests asociados a ese fichero.


Del vídeo destaco la parte (breve) en la que cuenta la motivación que les llevó a desarrollar la herramienta: querían desarrollar AngularJS, querían automatizar el proceso de test en su desarrollo y no les convencía ninguna herramienta similar existente. Un buen ejemplo de lo que significa llevar la palabra ingeniero en el nombre.

Git, GitHub y el Social Coding

Hace algún tiempo alguien me preguntó cual era mi red social preferida. Una pregunta muy de los tiempos que corren, aunque yo no la entendí. ¿Por qué he de tener yo una red social preferida? pensé. Tiempo después pienso que quizá no entendí la pregunta porque no entendía la utilidad real que tienen las redes sociales. Como diría mi buen amigo Ginés: no sabía sacarle el pringue.

Si me volvieran a preguntar lo mismo hoy afirmaría sin vacilar que mi red social preferida es Youtube. Y lo es precisamente por su utilidad. Para alguien como yo, apasionado por la tecnología y el desarrollo software, Youtube es muy útil para aprender nuevas tecnologías y hacerlo directamente de sus creadores. Nadie mejor que el creador de una tecnología para entender la motivación que hay tras ella (salvo en el caso de Node.js, cuyo creador no tiene buenas dotes de comunicación: ver los 30 primeros segundos de este vídeo).

Cuento todo esto porque hoy me he visto en la necesidad de contarle a alguien qué es eso del social coding y de GitHub, y he recordado cómo lo entendí yo: mediante Youtube con el siguiente video.


En este caso no son sus creadores, pero sí gente que vive de ello, por lo que saben defender bien el tema.

PD: A quién dude de la utilidad de Youtube le recomiendo que vea este vídeo de Usman Ríaz en el que cuenta cómo encontró en Youtube la formación musical que quería y sus profesores no podían aportarle.

sábado, 24 de diciembre de 2011

El riesgo de la meta-progamación en C++


El riesgo de abusar de los templates es este: una compilación excesivamente costosa, casi inviable con muchos ordenadores. En la captura se muestra un ejemplo de corbasim donde se recorre varias veces durante la compilación una lista de tipos de 200 elementos. A su vez, cada iteración sobre esos 200 elementos conlleva iteraciones sobre otras listas de tipos derivadas. El resultado es una compilación que llega a provocar paginación, al consumir toda la memoria disponible (y más).

La versión de GCC que utilizo es la 4.4.3. Es probable que en versiones posteriores mejore algo la compilación, pero aún así a día de hoy resulta inviable una compilación de más de media hora para simples herramientas de test. toca optimizar la compilación para generar código eficiente en un tiempo razonable.

domingo, 11 de diciembre de 2011

Boost.Fusion: introspección en tiempo de compilación para estructuras en C++

Una de las librerías que más me gusta de las Boost C++ Libraries es la Boost.Fusion. No voy a entrar en detalle en lo que ofrece esta librería; básicamente permite el manejo de tuplas de elementos de distintos tipos.

Lo bueno de las tuplas que ofrece esta librería son las meta-funciones que ofrecen introspección en tiempo de compilación sobre estas tuplas. El disponer de esta introspección permite escribir código genérico sea cual sea el número y tipo de los elementos de estas tuplas.

La característica que más me gusta de esta librería es que permite poder adaptar estructuras convencionales de C++ para ser utilizadas como lo que realmente son: tuplas de elementos de distintos tipos. De esta forma, podemos utilizar las meta-funciones de esta librería sobre estructuras y así escribir código genérico. Creo que el poder adaptar estructuras para poder tener cierta introspección -siempre en tiempo de compilación- cubre una de las carencias principales del lenguaje C++.

Esta característica la he usado en varios proyectos. Uno de ellos es CORBASIM, donde se utiliza para generar automáticamente -en tiempo de compilación- formularios para introducir datos. También se utiliza para serializar estas estructuras en formato JSON.

Lo malo de esta característica, es que para poder utilizarla hay que definir dos veces la estructura: una -la propia estructura-, y otra con la macro BOOST_FUSION_ADAPT_STRUCT. Es decir, escribir dos veces la misma información semántica. En CORBASIM esto no supone ningún problema, ya que todo el código es generado a partir de ficheros IDL. Pero en otros ámbitos donde no hay un DSL ni código generado de por medio, esta duplicidad es un poco incómoda. La falta de esta introspección de por sí en el lenguaje es -en mi opinión- la mayor de sus carencias.

Para intentar cubrir esta carencia estaría bien disponer de una herramienta que realice esta adaptación de forma automática, generando código C++ adicional a partir de código C++. Esto no sería muy difícil; bastaría recorrer el AST del código en el que se definen las estructuras que queremos adaptar. El AST se puede recorrer por ejemplo con un plugin de GCC, solo hay que echarle tiempo. En una prueba rápida, he conseguido esbozar esta herramienta utilizando Dehydra.

Aunque Dehydra permite recorrer el AST mediante código JavaScript con el fin de implementar validadores de código C++, también se podría utilizar para generar automáticamente este código adicional. El código JavaScript del esbozo que he realizado con Dehydra para generar este código es tan sencillo como el que sigue:

function getHeader(name)
{
    return name.replace('::','_').toUpperCase() + '_ADAPTED';
}

function process_type(type)
{
    if (type.kind == "struct" && !type.typedef 
            && type.members.length > 0)
    {
        header = getHeader(type.name);
        print('#ifndef ' + header);
        print('#define ' + header);

        print('// Generated code for ' + type.name + 
                ' defined in ' + type.loc);
        // Uso de Boost.Fusion
        print('BOOST_FUSION_ADAPT_STRUCT (');
        print('\t' + type.name + ',');
        for each(let m in type.members)
        {
            print('\t(' + m.type.name + ', ' + m.shortName+')');
        }
        print(')');
        print('');

        print('#endif // ' + header);
        print('');
    }
}


Esta herramienta me parece interesante para poder generalizar parte del trabajo realizado en CORBASIM, haciéndolo independiente de CORBA. Extenderé la idea :)