martes, 15 de febrero de 2011

YAML. Un lenguaje estructurado pero no de marcado

YAML, cuyas iniciales dicen YAML Ain't Markage Language, es un lenguaje que me ha sorprendido. Lo descubrí a raíz de un artículo en el que comentaban su uso en la introducción de estructuras de datos por personas que no estaban relacionadas con el desarrollo software.
Y es que es cierto que estamos muy acostumbrados a usar lenguaje XML o derivados, del que .NET tiene muchas librerias, o incluso JSON para otras plataformas.
Xml no está pensado realmente para ser leido por una persona. Aunque para ficheros pequeños y con no demasiadas estructuras anidadas, podamos apañarnos bien.

YAML es un lenguaje estructurado, pero sin etiquetas. Lo cual lo hace extremadamente fácil de leer para una persona. Definido a partir de una serie de reglas muy símples que hace que escribir un documento con este formato sea realmente fácil.

Las andaduras de este lenguaje comenzaron en Mayo de 2001 por Clark Evans. Y actualmente está en la versión de especificación 1.2. La página de referencia la podeis encontrar aquí. Y que precisamente tiene todo su contenido escrito con estructura YAML.

Una pequeña lista de sus características son:

  • YAML tiene un formato de lectura sencillo para las personas.
  • YAML es conciso y compacto.
  • YAML es expresivo y extensible.
  • YAML no es un lenguaje de marcado!

Si esta lista la quisiera expresar con XML necesitaría algo así:

<ul>
   <li>YAML tiene un formato de lectura sencillo para las personas.</li>
   <li>YAML es conciso y compacto.</li>
   <li>YAML es expresivo y extensible.</li>
   <li>YAML no es un lenguaje de marcado!</li>
<ul>

En YAML se definiría de la siguiente manera:

- YAML tiene un formato de lectura sencillo para las personas.
- YAML es conciso y compacto.
- YAML es expresivo y extensible.
- YAML no es un lenguaje de marcado!

Otros ejemplos de estructuras que pueden hacerse con YAML:

Diccionarios:

---
Clave 1: Valor de la clave 1.
Clave 2: Valor de la clave 2.
Clave 3: Valor de la clave 3.

Listas de diccionarios anidados:

---
- Clave 1: Valor de la clave 1.
- Clave 2:
     Subclave 1: Valor de la Clave 2, Subclave 1.
     Subclave 2: Valor de la Clave 2, Subclave 2.

Mapas:

---
Seat Leon: {Color: Rojo, Carburante: Diesel, Velocidad Máxima: 185 Km/h, Kilometros: 25000}
Nissan Micra: {Color: Blanco, Carburante: Hibrido, Velocidad Máxima: 172 Km/h, Kilometros: 12000}
 

Existen implementaciones de este formato en muchos lenguajes, incluyendo .NET, el cual dispone de una implementación en Codeplex y que acompaña con un minitutorial de Yaml en 5 minutos.

miércoles, 9 de febrero de 2011

Versionado de ensamblados de .NET

Uno de los temas que menos cuidado se le suele prestar en el desarrollo de software es el del versionado de componentes. Y es que gracias a las versiones, podemos saber exactamente cuando se compiló un ensamblado (e incluso saber la etiqueta de la versión de código fuente que la generó) y si hay otros ensamblados que son compatibles.

En .NET, las versiones se establecen en el fichero AssemblyInfo.cs que se puede encontrar dentro de la carpeta de “Properties” del proyecto:

    1 using System.Reflection;

    2 using System.Runtime.InteropServices;

    3 

    4 // General Information about an assembly is controlled through the following

    5 // set of attributes. Change these attribute values to modify the information

    6 // associated with an assembly.

    7 [assembly: AssemblyTitle("Project Title")]

    8 [assembly: AssemblyDescription("Some description")]

    9 [assembly: AssemblyConfiguration("Debug")]

   10 [assembly: AssemblyCompany("My Company of Software")]

   11 [assembly: AssemblyProduct("Product Name")]

   12 [assembly: AssemblyCopyright("Copyright © My Company, 2011")]

   13 [assembly: AssemblyTrademark("")]

   14 [assembly: AssemblyCulture("")]

   15 

   16 // Setting ComVisible to false makes the types in this assembly not visible

   17 // to COM components.  If you need to access a type in this assembly from

   18 // COM, set the ComVisible attribute to true on that type.

   19 [assembly: ComVisible(false)]

   20 

   21 // The following GUID is for the ID of the typelib if this project is exposed to COM

   22 [assembly: Guid("f446dcb3-68fb-49d9-a057-fe50383ce4c3")]

   23 

   24 // Version information for an assembly consists of the following four values:

   25 //

   26 //      Major Version

   27 //      Minor Version

   28 //      Build Number

   29 //      Revision

   30 //

   31 // You can specify all the values or you can default the Build and Revision Numbers

   32 // by using the '*' as shown below:

   33 // [assembly: AssemblyVersion("1.0.*")]

   34 [assembly: AssemblyVersion("1.0.0.0")]

   35 [assembly: AssemblyFileVersion("1.0.0.0")]

Las últimas líneas del fichero están relacionadas con la versión del ensamblado y con la versión del fichero.

AssemblyFileVersion

Su principal objetivo es el de identificar de manera uniequivoca a un ensamblado. A partir de los valores de la versión podemos saber la versión de código fuente que compiló el ensamblado. Tambien nos permite reconocer si se trata de una versión de “Service Pack” o de “Hotfix”.

Las versiones de un fichero están basadas en un código de 4 números. El uso de cada uno de los valores depende de cada equipo de desarrollo. Personalmente, les doy el siguiente significado a los valores de versión:

  • Major Version: Versión principal de producto. No suele cambiar a lo largo de todo el ciclo de desarrollo salvo que el desarrollo requiera rehacer todo el código desde cero. Evidentemente no se mantiene ninguna compatibilidad con versiones anteriores.
  • Minor Version: Cambio importante en las interfaces del ensamblado que hace que se rompa la compatibilidad con versiones anteriores. Al igual que la versión principal, este valor se cambia de manera manual.
  • Build Number: Número calculado automáticamente por el proceso de compilación en orden creciente de manera que dos compilaciones seguidas no generen el mismo valor. Existen muchos esquemas de generación de este valor. Quizá el más conocido es el de basado en el número de días transcurridos desde el 1 de Enero de 2000.
  • Revision: Número tambien generado automáticamente por el sistema de compilación. Por ejemplo, si se generan varias versiones el mismo día, la versión de Build no cambia, por lo que está va incrementandose de uno en uno por cada compilación.

AssemblyVersion

Los ensamblados de .NET usan esta versión para enlazarse con otros ensamblados. Esto es, cuando por ejemplo el ensamblado A.dll referencia al ensablado B.dll con version “1.0.0.0”, si sustituimos este último ensamblado por la versión “1.0.0.1”, A.dll no será capaz de encontrarlo pues espera encontrar la versión con la que fue compilado. Por este motivo no se debe dejar a la ligera la opción de Visual Studio de autoincrementar la versión del ensamblado en cada compilación.

El significado de los valores de la versión puede ser:

  • Major Version: Se actualiza de manera manual. Normalmente significa un cambio radical en la estructura del ensamblado. Por ejemplo porque se ha vuelto a reescribir gran parte del código. Normalmente implica rompe la compatibilidad con versiones anteriores.
  • Minor Version: Se han añadido nuevas funcionalidades al ensamblado. Y por tanto, puede suponer cambios en la interfaz pero tratando de mantener la compatibilidad con versiones anteriores. Su modificación es manual.
  • Build Number: Valor calculado automatiamente y que identifica el número de compilación realizado sobre el código fuente.
  • Revision: Normalmente identifican ligeros cambios sobre el código. Por ejemplo solución de hotfixes. Aquellos ensamblados donde únicamente varíe el número de revisión son totalmente intercambiables entre sí.

AssemblyInformationalVersion

Este es otro atributo que puede ser usado dentro de AssemblyInfo. Su objetivo es el de exponer una versión del ensamblado a nivel de producto, documentación, instalador, etc. En ningún momento esta información es usada por Windows o por otros ensamblados de .NET.

Esta versión se identifica con tres valores:

  • Major Release: Normalmente asociada a la versión principal de producto y no suele variar en todo el ciclo de desarrollo del proyecto salvo que se tenga que rehacer todo el contenido del ensamblado.
  • Minor Release: Este número se asocia a incrementos en la funcionalidad del ensamblado.
  • Maintenance Release: Los incrementos en este valor suelen reflejar pequeños cambios normalmente asociados a correción de errores, rendimiento o estabilidad. Los clientes del ensamblado no aprecian un cambio en la funcionalidad importada.