Metro: Cómo cargar contenido en un fragmento desde un link

El modelo de navegación recomendato de las aplicaciones Metro hechas con Javascript utiliza un concepto que se conoce como fragmentos, básicamente es una página principal en la cual se van cargando dentro de un contenedor las páginas que navegamos, es decir, siempre estamos en la misma página y cambiamos el contenido.

El objeto Navigator

Lograr este tipo de navegación en HTML es posible gracias a un objeto que es parte de WinJS, el objeto WinJS.Navigation, si bien hace gran parte del trabajo no lo hace todo, en general es necesario “escuchar” algunos eventos y realizar la carga de los fragmentos, por ejemplo, cuando se invoca el evento onnavigated.

No es necesario que lo hagamos nosotros

No es necesario que nosotros agregemos el código que escuche los eventos y carga y descarge los fragmentos, podemos copiar el código de alguno de los templates como “Grid Application” o “Split Application”, o más fácil, crear una “Navigation Application”, que no es más que una aplicación en blanco con esta navegación ya resuelta.

image

Una vez de creamos la aplicación tenemos lo siguiente:

image

Como podemos ver dentro de la carpeta js tenemos un archivo navigator.js, justamente es quien se encarga de la carga y descarga de fragmentos, entre otras cosas.

Primer intento: agregando un botón para navegar a otra página:

Para comenzar modificamos homePage.html y agregamos un botón para poder navegar a una segunda página.

image

Ahora vamos a homePage.js y agregamos el código para que al hacer click en el botón navege a page.html

image

Bien sencillo, asociamos este código con la carga del fragmento utilizando WinJS.UI.Pages.define y le indicamos que cuando se carge el fragmento llame a la función ready, dentro de ésta seleccionamos el botón haciendo:

document.querySelector("#boton")

y asignamos el evento click

document.querySelector("#boton").addEventListener("click", function () {
});

e invocamos al navigator para cargar el fragmento

(function () {
    "use strict";

    // This function is called whenever a user navigates to this page. It
    // populates the page elements with the app's data.
    function ready(element, options) {
        // TODO: Initialize the fragment here.
        document.querySelector("#boton").addEventListener("click", function () {
            WinJS.Navigation.navigate("/html/page.html");
        });
    }

    WinJS.UI.Pages.define("/html/homePage.html", {
        ready: ready
    });
})();

El hecho de que se cargen los fragmentos depende de que el archivo navigator.js extiende la funcionalidad del objeto WinJS.Navigation y gestiona el mecanismo.

Cómo cargar un fragmento con un hipervínculo como si fuera un botón?

El principal problema es que si le indicamos al hipervínculo como url page.html no se cargará el fragmento sino que se cargará la página completa, para evitarlo hacemos lo siguiente:

image

(function () {
    "use strict";

    // This function is called whenever a user navigates to this page. It
    // populates the page elements with the app's data.
    function ready(element, options) {
        // TODO: Initialize the fragment here.
        document.querySelector("#link").addEventListener("click", function () {
            WinJS.Navigation.navigate("/html/page.html");
            return false;
        });
    }

    WinJS.UI.Pages.define("/html/homePage.html", {
        ready: ready
    });
})();

Nótese que ponemos como href el valor # y cuando atrapamos el evento hacemos return false, con esto evitamos que se ejecute el evento por defecto, o sea que cargue la otra página.

image

image

Además de manejar la carga de fragmentos el objeto Navigator también controla el poder volver a la página anterior por medio de un fragmento, es decir, si hacemos Alt+izq vuelve a la página anterior manteniendo el marco.

Hasta la próxima.

Haciendo las cosas sencillas

Se me ocurrió hacer una serie de consejos que a mi parecer hacen el código más sencillo. Desde el vamos comento que es mi criterio y cualquier persona es bienvenida para opinar y estar en desacuerdo. Voy a tratar de proponer siempre un ejemplo bien concreto de aplicación.

Supongamos que tenemos un sistema que trabaja con otro externo. Nuestro sistema maneja ciertas transacciones que cambian de estado en este otro. Entonces tenemos un método de consulta de estado como sigue:

public TransactionStatus QueryAndProcces(int transactionId)
{
	Transaction localTransaction = this.Repository.GetById(transactionId);

	if (localTransaction.Status != TransactionStatus.Complete)
	{
		this.Log("Consulto el estado de la transacción en el servicio externo");
		TrasactionStatus newStatus = this.ExternalService.QueryStatus(transactionId);
		// Múcho código complicado sobre manejo del estado una vez obtenido
		return newStatus;
	}
	else
	{
		this.Log("No se busca en el servicio porque está completa");
		return TransactionStatus.Complete;
	}
}

Se entiende que el método realiza algún trabajo cuando recibe un nuevo estado. Eso está representado en el comentario del código.

Bien, en esta oportunidad lo que quiero proponer es usar la técnica llamada “early return”. La idea es cortar el flujo cuando sabemos que la transacción está completa. A continuación el código después de ser refactorizado:

public TransactionStatus QueryAndProcces(int transactionId)
{
	Transaction localTransaction = this.Repository.GetById(transactionId);

	if (localTransaction.Status == TransactionStatus.Complete)
	{
		this.Log("No se busca en el servicio porque está completa");
		return TransactionStatus.Complete;
	}

	this.Log("Consulto el estado de la transacción en el servicio externo");
	TrasactionStatus newStatus = this.ExternalService.QueryStatus(transactionId);
	// Múcho código complicado sobre manejo del estado una vez obtenido
	return newStatus;
}

Ventajas:

  • Claridad. Me parece que el código escrito así deja bien claro que cuando la transacción está completa el flujo debe terminar.
  • Complejidad. Si la parte del comentario es muy complicada, en el código original nos veríamos inmersos en su lógica. Cuando llegáramos al final veríamos un “else” que poco tiene que ver con el manejo del nuevo estado. Es más, con esta técnica se puede bajar un nivel la complejidad ciclomática del método.
  • Legibilidad. Una vez leído el código ya he comprendido el primer “if” y no necesito releerlo para entenderlo, me alcanza con un golpe de vista. En el código original es probable que deba releer el “if” para interpretarlo y luego saber cuál es la parte que me interesa.
  • Estética. Me parece más bonito XD

¡Guarda con el encoding!

Tres días pasamos con mi compañero buscando el bug en la generación del hash.

La aplicación generaba 4c2768d1f6858e92d3d00e3f20da58eb que no coincidía con a45eb95c318b47d6e71f8713364ad82a. En ambos casos se encodeaba “José”.

¿Por qué? ¡Si el string es el mismo!

Sí era el mismo, semánticamente. Pero en 2 idiomas diferentes. Nosotros encodeabamos “José” en UTF-8 y ellos encondeaban “José” en ISO-Latin.

En UTF-8 se encodea a “Jos%C3%A9” y en ISO-Latin a “Jos%E9”. Origen distinto, hash distintos.

Lectura recomendada: http://www.joelonsoftware.com/articles/Unicode.html

Creando una aplicación MVC en Ruby on Rails en 5 minutos

Ruby es un lenguaje de programación dinámico y de código abierto enfocado en la simplicidad y productividad. Su elegante sintaxis se siente natural al leerla y fácil al escribirla. Sus características principales son:

• Interpretado: se ejecuta inmediatamente sin necesidad de compilador, aunque la ejecución es más lenta.

• Orientado a objetos: absolutamente todo es un objeto.

• Portable: funciona en múltiples plataformas (UNIX, Windows, DOS, Mac, etc.) sin necesidad de cambios.

• No-tipado: las variables no tienen un tipo.

• Garbage collector: built-in, sin necesidad de preocuparse por liberar memoria.

• Sintaxis fácil y clara.

• Totalmente gratuito, incluso para aplicaciones comerciales.

Ruby on Rails, también conocido como RoR o Rails es un framework de aplicaciones web de código abierto escrito en Ruby siguiendo el paradigma de la arquitectura MVC. Trata de combinar la simplicidad con la posibilidad de desarrollar aplicaciones del mundo real escribiendo menos código que con otros frameworks y con un mínimo de configuración. El lenguaje de programación Ruby permite la metaprogramación, de la cual Rails hace uso, lo que resulta en una sintaxis que muchos de sus usuarios encuentran muy legible. Está absado en los siguientes principios:

• Don’t Repeat Yourself: no duplicar las “piezas de información”.

• Convention Over Configuration: ganar simplicidad especificando sólo aspectos no convencionales.

• REST: patrón de diseño web basado en identificación de recursos.

ActiveRecord

ActiveRecord es la capa de Rails de mapeo relacional de objetos. Provee una interfaz orientada a objetos que se relacionan con una base de datos, para hacer el desarrollo más simple y amigable para el desarrollador. Es un ORM (object-relational mapping): hace las traducciones entre objetos Ruby y la base de datos, manejando registros y relaciones. La librería ActiveRecord de Ruby crea un modelo de negocio persistente desde los objetos de negocio y las tablas de datos, unificándose la lógica y los datos en un solo paquete. ActiveRecord agrega herencia y asociaciones al patrón Active Record común, dándole más potencia.

Scaffolding

Rails provee Scaffolding, una técnica para construir vistas, modelos, controladores, bases de datos, etc. a partir de operaciones simples. Veamos cómo se utiliza:

1. Creación de la aplicación

Ejecutar en la consola el siguiente comando:

$ rails new videoclub
Esto armará toda una estructura de carpetas para la aplicación, tales como config, db, doc, controllers, views, script, tests, etc.

2. Creación de la base de datos

Ejecutar en la consola el siguiente comando:
$ rake db:create

Esto creará en la carpeta db dos bases de datos: la de desarrollo y la de tests. Por default, la base de datos es SQLite3, pero desde ya que puede ser otro motor.

3. Crear un controlador

Ejecutar en la consola el siguiente comando:
$ rails generate controller home index
Rails creará no sólo el archivo del controlador, sino además la vista correspondiente a la acción index: app/views/home/index.html.erb

4. Establecer la homepage

Ejecutar en la consola el siguiente comando:
$ rm public/index.html

5. Crear una clase del modelo

Ejecutar en la consola los siguientes comandos:
$ rails generate scaffold Cliente name:string lastname:string
$ rake db:migrate

Estas instrucciones no sólo crearán el archivo app/models/cliente.rb, sino que además modificarán la base de datos (ActiveRecord mediante) para incluir este modelo en la estructura de tablas.

6. Levantar el web server y ver la aplicación

Ejecutar en la consola el siguiente comando:
$ rails server

Con el web server corriendo, la aplicación podrá ser visualizada accediendo a http://localhost:3000.

¡Y listo! Ahora habrá que modificar la vista para que haga algo con el modelo, complejizar el controlador, etc., pero ya disponemos, tras unos breves pasos, de una aplicación con estructura MVC, una vista, un controlador y un modelo, así como la base de datos asociada al mismo.

Algunos links interesantes

http://guides.rubyonrails.org/getting_started.html (sobre el que basamos este ejemplo de aplicación)

http://railsinstaller.org/

http://www.ruby-doc.org/

Primeros pasos con Microsoft Kinect

Holaaaa.

Mi idea es contar mi experiencia desarrollando con Kinect.

Nació como otro proyecto de I+D acá en Kinetica y después encontró una área de aplicación como prototipo para una exposición en CasaFOA (http://www.casafoa.com/ ). Esta historia es para otro post, ahora prefiero contar cómo comenzar.

Cuando arrancamos, en plural porque trabajé con Fernando Kahan, no había salido aun el SDK. En ese entonces hacer funcionar las cosas era muy difícil. Configurar todo para ejecutar una aplicación simple llevaba horas, días o semanas. Por suerte no tardó en salir el SDK y ahí cambió la cosa.

Bien, la Kinect es un dispositivo con varios sensores. Tiene varias cámaras de video y un micrófono. Usando las diferentes cámaras interpreta la profundidad. Algo así como hacemos nosotros con nuestros ojos. Así nos informa sobre la posición en 3D de las cosas. También tiene la capacidad de decir de dónde viene el sonido (izquierda, derecha). Alguien me dijo alguna vez que también tiene un sensor infrarrojo pero de esto ya no estoy seguro.

Demasiada introducción, ¿cómo arrancamos?
Bueno, te comprás una Kinect (XD), te bajás el SDK: http://www.microsoft.com/en-us/kinectforwindows/develop/overview.aspx y lo instalás. ¡Fantástico!

Ahora veamos un ejemplo sencillo (C#).
Primero nos creamos nuestro objetito Runtime y hacemos algunas magias para configurarlo:

using Microsoft.Research.Kinect.Nui;

(...)

Runtime runtime = new Runtime();
runtime.Initialize(RuntimeOptions.UseDepthAndPlayerIndex |
    RuntimeOptions.UseSkeletalTracking);
runtime.DepthStream.Open(
    ImageStreamType.Depth,
    2,
    ImageResolution.Resolution320x240,
    ImageType.DepthAndPlayerIndex);

Las magias son para informarle a la Kinect que vamos a usar y que no. Es importante solo inicializar lo que realmente vamos a usar para no afectar la performance. En mi ejemplo digo que voy a usar el índice de jugador (ver 1) y sus posiciones.

¿Sus posiciones? ¿En plural?
Sí, en plural. La Kinect reconoce Skeletons con Joints. Cada Joint representa una parte del cuerpo. Por ejemplo: la cadera, la cabeza o la muñeca izquierda.

Hay 2 formas de obtener esta información. Pidiéndola expresamente en un instante de tiempo; o bien, registrándose al evento que nos brindará la información cuando está disponible. En el siguiente ejemplo voy a tratar de ilustrar la segunda forma:

// Nos registramos al evento
runtime.SkeletonFrameReady += SkeletonFrameReadyHandler;

(...)

// Mi handler del evento. Se llamará cada vez que haya nueva información
public void SkeletonFrameReadyHandler(object sender, SkeletonFrameReadyEventArgs eventArgs)
{
    SkeletonFrame skeletonFrame = eventArgs.SkeletonFrame;

    SkeletonData data = skeletonFrame.Skeletons.First(sk => sk.TrackingState == SkeletonTrackingState.Tracked);

    if (data == null)
    {
        return;
    }

    foreach (Joint joint in data.Joints)
    {
        Console.WriteLine("Joint:{0} X:{1} Y:{2} Z:{3}", joint.ID, joint.Position.X, joint.Position.Y, joint.Position.Z);
    }
}

Este ejemplo imprimirá, cada vez que llegue información, las coordenadas de cada Joint que detecte. Esto nos brinda la posibilidad de buscar relaciones entre las posiciones de los Joints y descubrir distintas posiciones del jugador. Incluso podemos tener las posiciones históricas y encontrar gestos, como un swing de golf.

Creo que con esto ya tienen para divertirse un rato.

¡Saludos!

PD: Esto fue desarrollado con la primera versión de la SDK, en febrero de este año (2012) ya salió una nueva. Tengo entendido que algunas cosas pueden cambiar pero el ejemplo, en esencia, es similar.

1. Si los jugadores se cruzan se tiene un registro de quien es quien a través de un ID. Muy útil para no confundir jugadores durante un juego.

Cómo implementar Share Contract para una aplicación Metro en Windows 8

Aclaración: La información en este artículo es válida para la Developer Preview de Windows 8 y es probable que sufra cambios en futuras versiones.

Hechas las aclaraciones del caso vamos a explicar cómo implementar Share Contract en una aplicación Metro desarrollada en Javascript

Herramientas necesarias

Una vez instalada la Developer preview de Windows 8 en un disco virtual, en una máquina de cero o como en mi caso en una máquina virtual, vamos al Visual Studio para comenzar

image

Share Contract, el copy-paste con esteróides.

En Windows 8 existe el concepto de Share Contract, el cual es básicamente preparar nuestra aplicación para que, gracias a una funcionalidad del sistema operativo, comparta cierta información con otras aplicaciones, o todo lo contrario, que nuestra aplicación sea destino de información que otras aplicaciones comparten.

Qué tipo de información se puede compartir?

  • Texto plano
  • URIs
  • HTML
  • Texto con formato
  • Bitmaps
  • Archivos
  • Datos definidos por el usuario

En nuestro caso vamos a compartir texto plano.

Creando la aplicación

Creamos una aplicación Javascript del tipo Blank Application ya que no necesitamos nada más para implementar Share Contract como proveedor para que otras aplicaciones (las declaradas como consumidor) puedan utilizar los recursos que hagamos disponibles.

image

Una vez creada la aplicación, vamos al código de nuestra página default.html el cual como sabemos se encuentra en default.js

(function () {
    'use strict';
    // Uncomment the following line to enable first chance exceptions.
    // Debug.enableFirstChanceException(true);

    WinJS.Application.onmainwindowactivated = function (e) {
        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
            // TODO: startup code here
        }
    }

    WinJS.Application.start();
})();

El objeto con el que tenemos que interactuar para implementar Share Contract (tanto para ser proveedor o consumidor) es DataTransferManager, vamos a ver un poco de código auto-descriptivo

(function () {
    'use strict';
    // Uncomment the following line to enable first chance exceptions.
    // Debug.enableFirstChanceException(true);

    // obtenemos una instancia de DataTransferManager para la vista actual
    var dtm = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();

    // atachamos el evento 'datarequested' que se ejecutará cuando se llame al botón de share
    dtm.addEventListener('datarequested', function (e) {
        // obtenemos el request desde el parámetro que nos da el callback
        var request = e.request;
        // cargamos el request con los datos que queremos compartir
        request.data.properties.title = 'Título';
        request.data.properties.description = 'Descripción';
        request.data.setText('Texto que será compartido');
    });

    WinJS.Application.onmainwindowactivated = function (e) {
        if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
            // TODO: startup code here
        }
    }

    WinJS.Application.start();
})();

Como vemos la implementación es muy simple, obtenemos una instancia de DataTransferManager y luego “atachamos” el evento datarequested el cual se ejecuta cuando se dispara el botón de Share de Windows 8, en la siguientes líneas configuramos los datos que queremos compartir.

Probando el Share Contract

image

image

Presionamos el botón Share de Windows y nos aparecen las aplicaciones que están “escuchando” como receptoras de Share Contract

Seleccionamos Tweet@rama y voilá

image

En resumen, Share Contract nos permite compartir información de diferentes tipos entre aplicaciones, y si estamos con una tablet acceder al botón Share es muy fácil y compartir de este modo muy intuitivo.

Nos leemos, Leonardo.

Reconocimiento Microsoft Student Partner

MSP

Finalizaba la semana pasada y todo señalaba que sería un fin de semana largo y sin sorpresas.

Pero esto estaba por cambiar, ya que en mi bandeja de entrada había un correo electrónico sin leer y el título de “Bienvenido a Microsoft“.

Al abrirlo me encontré con algo que no esperaba para nada, el reconocimiento, y bienvenida, al programa Student Partner de Microsoft. Este programa tiene como uno de sus objetivos el de colaborar con los estudiantes y su aprendizaje de nuevas tecnologías, tanto de desarrollo de software y codificación como de I.T. y gestión.

Un MSP se convierte en el nexo entre la empresa y otros estudiantes, sirviendo de facilitador, guía y colaborador, tanto para la transmisión de conocimientos, creación de eventos, entre muchas otras actividades.

Esta no es la primera vez que soy reconocido como MSP, ya que hace varios años atrás, había tenido el privilegio de obtener tal reconocimiento, con el que pude (Pudimos, MSPs y alumnos) crear diferentes grupos de estudio, brindar conferencias técnicas y muchas otras actividades, con el objetivo de potenciar los conocimientos de todos los estudiantes.

En esta oportunidad el reconocimiento es, de igual forma, por ayudar a otros alumnos universitarios (Y a las mismas universidades) con el acceso a las tecnologías de desarrollo de software. De esta forma he podido participar y colaborar de eventos como CodeCamp 2011 en Buenos Aires, dando charlas sobre desarrollo de juegos, o más recientemente, en Córdoba, mostrando cómo desarrollar aplicaciones para Windows Phone 7 y Android en la universidad Siglo 21. Por supuesto, las actividades no se limitan a estos eventos, si no que existen otras posibilidades pensando, también, en los alumnos, como el libro Programador.Net publicado a mediados del año pasado. Este libro fue pensado para cubrir necesidades sobre desarrollo de software para aquellos que están iniciándose en el mundo del desarrollo, especialmente para estudiantes que se inician en las carreras de sistema.

Pero como comenté, un MSP no se limita a esto, si no que es parte activa de la comunidad de estudiantes. Si quieres saber más sobre el programa, puedes entrar al sitio oficial.

Matías Iacono

HTML5 y la belleza de la web

Hace algunas semanas tuve la oportunidad de dar una presentación sobre HTML5 en dos eventos que se realizaron en Microsoft Argentina. En ambas ocasiones el público era muy heterogéneo, y no toda la audiencia estaba constituida por desarrolladores, o incluso roles relacionados con IT. Teniendo en cuenta esto, decidí centrar mi presentación en mostrar ejemplos de sitios web existentes, y contar qué cosas se pueden hacer hoy en día utilizando alguna de las tecnologías enmarcadas dentro del paragüas de HTML5.

En este post comparto los ejemplos que mostré y una breve descripción de qué características de HTML5 implementan. La mayoría de los ejemplos están tomados de http://www.beautyoftheweb.com/.

Antes que eso: para entender de qué se trata el estándar HTML5 recomiendo los siguientes videos que armaron Miguel Saez e Ignacio Lopez para Channel9:

Ahora sí, van los ejemplos:

Video & Audio

Bing (http://www.bing.com): hace unas pocas semanas, Bing incorporó videos como background para su sitio web de búsqueda. No todos los días se publica un video como fondo, además que esto momentáneamente está habilitado para usuarios de Estados Unidos (basta con elegir United States como país entre las opciones que ofrece el sitio). Me gusta mucho este ejemplo porque se ve claramente cómo el video puede integrarse con los restantes elementos HTML.

Mike Tompkins Video Mixer (http://www.beautyoftheweb.com/firework/index.html): se puede apreciar el uso del audio y varios tag videos en paralelo. También se utilizaron transiciones y animaciones CSS al manipular el mixer.

GeoLocation

Foursquare Playground (http://www.foursquareplayground.com/): se utiliza la API de geolocalización de HTML5 para ubicar al personaje en el área donde se encuentre el usuario.

Transiciones y Animaciones

Never mind the bullets (http://www.nevermindthebullets.com): muy bueno el uso de estas nuevas características de CSS3 para mostrar una historieta tal como si estuviesemos leyendo un comic en revista pero manipulando el mouse.

Tron (http://disneydigitalbooks.go.com/tron/): similar a “Never mind the bullets” pero con el archiconocido comic Tron.

SVG & Canvas

Todos estos son espectaculares ejemplos del uso de estas dos tecnologías. Mucho para decir no hay, simplemente es verlos y asombrarse de las capacidades que hoy tenemos para desarrollar sitios web:

SVG Girl (http://jsdo.it/event/svggirl)

The Shodo (http://www.theshodo.com/)

BMW – Joy defines the future (http://joydefinesthefuture.com/)

World’s Biggest Pacman (http://worldsbiggestpacman.com/)

Otros

Santas media queries (https://developer.mozilla.org/es/demos/detail/santas-media-queries/launch): muy buen ejemplo de media queries. La imagen se adapta al ancho de la pantalla. Pruébenlo achicando el tamaño del browser.

South Park CSS3 (http://www.wagon-bertrand.fr/southParkCSS3/index.html): siguiendo con el rubro animado, muestra a los personajes de South Park utilizando solo divs y la nueva propiedad de redondeo de bordes.

Associated Press (http://html5.labs.ap.org/): la gente de Associated Press repensó cómo sería un diario digital utilizando las nuevas características de HTML5. Combinaron muchas de las nuevas tecnologías, pero vale la pena destacar el uso de WOFF (Web Open Font Format) para poder leer las noticias utilizando el font que más nos agrade y el uso de Offline Storage, para poder almacenar localmente las noticias que más nos interesen para leer offline.

Agregando un proyecto a integración continua con Jenkins

Vamos a mostrar, muy sucintamente, cómo agregar un proyecto de Visual Studio a un servidor de integración continua Jenkins. Para eso, veamos primero las herramientas que utilizaremos:

- Jenkins (http://jenkins-ci.org/): es una aplicación que monitorea la ejecución repetida de jobs automatizados que se utilizan para integración continua (compilación de proyectos, ejecución de tests unitarios, análisis de cobertura de código, etc.).

- MSBuild: es una plataforma que permite ejecutar builds automatizados de proyectos de Visual Studio, sin necesidad de tener el IDE instalado.

Ahora vayamos paso por paso.

1. Crear el archivo de MSBuild

Este es un posible archivo de msbuild utilizado para un proyecto:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>        

    <PropertyGroup>
        <WorkingDirectory>C:\.hudson\workspace\DM.API\CheckoutService\branches\APIv1.1\src</WorkingDirectory>
        <ConnectionStringNoDB>Server=DMCI01\SQL02;Trusted_Connection=True;</ConnectionStringNoDB>
        <ConnectionString>Server=DMCI01\SQL02;Trusted_Connection=True;database=DMSandboxAPI;</ConnectionString>
    </PropertyGroup>    

    <ItemGroup>
        <CreateDBScripts Include="$(WorkingDirectory)\DM.Services.Process.API\Sandbox Scripts\DB\*.sql" />
        <TableScripts Include="$(WorkingDirectory)\DM.Services.Process.API\Sandbox Scripts\Tables\*.sql" />
        <DataScripts Include="$(WorkingDirectory)\DM.Services.Process.API\Sandbox Scripts\Data\*.sql" />
    </ItemGroup>        

    <Target Name="CreateSandboxDB">
        <ExecuteDDL ConnectionString="$(ConnectionStringNoDB)" Files="@(CreateDBScripts)" ContinueOnError="false" />        <ExecuteDDL ConnectionString="$(ConnectionString)" Files="@(TableScripts)" ContinueOnError="false" />
        <ExecuteDDL ConnectionString="$(ConnectionString)" Files="@(DataScripts)" ContinueOnError="false" />
    </Target>        

</Project>

Los tags <PropertyGroup> especifican que existen propiedades que toman cierto valor. Por ejemplo, la propiedad <WorkingDirectory> determina el path donde se encuentra el código, así como la propiedad <ConnectionString> especifica el string de conexión a base de datos a utilizar.

El tag <ItemGroup> representa un archivo a utilizar. En el caso de TableScripts, por ejemplo, referencia a todos los archivos .sql de una carpeta.

El tag <Target> contiene un conjunto de tareas a ejecutar secuencialmente. En nuestro ejemplo, el target “CreateDatabase” define la ejecución de tareas ExecuteDDL, que ejecutan scripts de base de datos, en nuestro caso archivos .sql.

2. Agregar el proyecto a Jenkins

CreateProject

Basta con navegar a Jenkins y agregar una nueva tarea desde el menú especificándole un nombre.

3. Configurar el proyecto Jenkins

Existe un link de Configurar dentro de la pantalla del proyecto creado. La vista de configuración es esta:

Config_1

Config_2

3.1 Código fuente

Bajo la sección “Source Code Management”, establecemos que el código fuente se obtiene desde un repositorio de tipo subversion, vía una URL. La opción de “Local module directory” permite especificar bajo qué subcarpeta del proyecto se guardará el código fuente.

3.2 Build triggers

La opción “Poll SCM” bajo la sección “Build Triggers” tiene el valor “* * * * *”, que significa que se hará un poll cada un minuto para verificar si existen cambios en el código fuente que disparen el proceso de build.

3.3 Build

3.3.1 Ejecución del archivo msbuild

En el primer item “Build a Visual Studio project or solution using MSBuild”, informamos a Jenkins que cuando se dispare el proceso ejecute el archivo de msbuild en el que definimos las tareas a realizar (creación de base de datos).

3.3.2 Compilación

En el segundo item “Build a Visual Studio project or solution using MSBuild”, definimos que se compile la solución en modo Debug.

3.3.3 Ejecución de Tests

En el item “Execute Windows batch command”, establecemos que EL NUnit ejecute los tests unitarios implicados en la dll del proyecto de test unitarios, y arroje esos resultados en un archivo xml.

Global Day of Code Retreat en Buenos Aires

El próximo 3 de diciembre de 2011 se llevará a cabo en todo el mundo un evento denominado Global Day of Code Retreat, el cual reunirá a más de 2000 desarrolladores de software distribuidos en 7 continentes y aproximadamente 100 ciudades alrededor del mundo, todos participando el mismo día de una actividad denominada code retreat.

Según palabras de Corey Haines, uno de los creadores del formato e impulsor del evento mundial, un code retreat es “una práctica intensiva que se realiza durante todo un día, focalizando en los fundamentos de desarrollo y diseño de software. Brindando a los desarrolladores la oportunidad de formar parte de una práctica enfocada, y aislada de las presiones diarias de ‘terminar las cosas’, el formato code retreat ha demostrado ser un medio altamente efectivo para mejorar nuestros skills”.

Resumidamente, se trata de realizar iteraciones de codificación de 45 minutos y programando de a pares, durante las cuales se debe resolver un problema de programación intentando hacerlo siempre de la mejor manera posible y sin preocuparnos por si lo resolvemos de forma completa o no. Luego de cada iteración el código se debe deshechar, se rotan los pares y se comienza con la resolución del problema desde cero. No importa si luego de 45 minutos hemos logrado escribir una sola línea de código ó si resolvimos el problema completo, siempre y cuando esa línea o todo el código lo hayamos resuelto de la mejor manera posible (o al menos lo hayamos intentado :) ).

En el siguiente video, Corey Haines explica la dinámica de un code retreat y el objetivo del mismo un poco más detalladamente:

Cleveland Code Retreat Introduction from Corey Haines on Vimeo.

Volviendo al Global Day of Code Retreat, como era de esperar Buenos Aires tendrá su code retreat local, co-organizado por Kleer, 10 Pines y Kinetica Solutions, el cual se llevará a cabo en oficinas de Kleer. La inscripción –si es que aún quedan lugares- se puede realizar a través de este link: https://eventioz.com/events/code-retreat-global-day-buenos-aires/registrations/new.