[MSBUILD] Utilizando trazas en tareas personalizadas (XVII)

image47dd1de4

Buenas,

ayer posteé un ejemplo muy básico para la creación de una tarea personalizada para MSBuild. Si eres un desarrollador, seguramente una de los primeros componentes que necesitas está relacionado con la capacidad de dejar trazas, en este caso en una Custom Task para MSBuild. Para esto tenemos a nuestra disposición la clase TaskLoggingHelper, ubicada en Microsoft.Build.Utilities.TaskLoggingHelper y que nos permite tareas como:

Como es posible ver, existen variantes para mostrar información “a pelo”, mostrar información desde un recurso, esto es muy útil para aplicaciones localizadas, a partir de un código, etc. Vamos que las opciones son muchas.

El siguiente ejemplo, muestra la capacidad para dejar trazas del tipo Error, Warning y Message, en las líneas 14, 15 y 16.

   1: using Microsoft.Build.Utilities;

   2: using Microsoft.Build.Framework;

   3: namespace ElBruno.MsBuild

   4: {

   5:     public class MySecondTask : Task

   6:     {

   7:         public string InputData { get; set; }

   8:         [Output]

   9:         public string OutputData { get; set; }

  10:         public override bool Execute()

  11:         {

  12:             bool ret = true;

  13:             OutputData = string.Format(@"{0} Input Data Procesada", InputData);

  14:             Log.LogMessage(OutputData);

  15:             Log.LogWarning(OutputData);

  16:             Log.LogError(OutputData);

  17:             return ret;

  18:         }

  19:     }

  20: }

 

Si generamos un proyecto que utilice esta nueva tarea

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

   2:          InitialTargets="Target1">

   3:   <UsingTask TaskName="ElBruno.MsBuild.MySecondTask"

   4:              AssemblyFile="c:srcBrunoAgile01MsBuild TestsSample 02binDebugElBruno.MsBuild.dll" />

   5:   <Target Name="Target1">

   6:     <MySecondTask InputData="Valentino">

   7:       <Output TaskParameter="OutputData" PropertyName="OutputData" />

   8:     </MySecondTask>

   9:   </Target>

  10: </Project>

 

Veremos un resultado similar al siguiente

image

 

 

Saludos @ Here

El Bruno

   

[MSBUILD] Creando tareas personalizadas (XVI)

image47dd1de4

Buenas,

hace un tiempo escribí un post donde comenté como crear una tarea personalizada para MSBuild que agrupe un set de strings. Pues este post es un primer paso para mostrar como crear una tarea personalizada para MSBuild, y luego iremos complicando un poquito el tema.

En primer lugar debermos crear un proyecto del tipo Class Library, y agregar las siguientes referencias:

  • Microsoft.Build.Framework
  • Microsoft.Build.Tasks.v3.5
  • Microsoft.Build.Utilities.v3.5

Luego, crearemos una clase llamada [MyFirstTask] que hereda de Task, de esta manera aprovecharemos la funcionalidad ya implementada en esta tarea de MSBuild (esta tarea está incorporada en Microsoft.Build.Utilities.dll). En este ejemplo, crearemos 2 propiedades llamadas InputData y OutputData para poder intercambiar datos con la tarea. El siguiente código muestra un ejemplo:

   1: using Microsoft.Build.Utilities;

   2: using Microsoft.Build.Framework;

   3: namespace ElBruno.MsBuild

   4: {

   5:     public class MyFirstTask : Task

   6:     {

   7:         public string InputData { get; set; }

   8:         [Output]

   9:         public string OutputData { get; set; }

  10:         public override bool Execute()

  11:         {

  12:             bool ret = true;

  13:             OutputData = string.Format(@"{0} Input Data Procesada", InputData);

  14:             return ret;

  15:         }

  16:     }

  17: }

 

Una vez compilado el proyecto, ya podemos crear un proyecto de MSBuild, donde probar la tarea. El siguiente ejemplo, muestra como importar y definir la tarea a partir de un path específico (líneas 4 y 5), y luego como invocar a la misma utilizando las propiedades de Input y output (líneas 8 y 9). Finalmente se muestra en un mensaje el dato que retorna la ejecución de la tarea (línea 11).

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

   2:          InitialTargets="Target1">

   3:   <!-- Tareas personalizada -->

   4:   <UsingTask TaskName="ElBruno.MsBuild.MyFirstTask"

   5:              AssemblyFile="c:srcBrunoAgile01MsBuild TestsSample 01binDebugElBruno.MsBuild.dll" />

   6:   <!-- Utilizacion de la tarea en un Target -->

   7:   <Target Name="Target1">

   8:     <MyFirstTask InputData="Valentino">

   9:       <Output TaskParameter="OutputData" PropertyName="OutputData" />

  10:     </MyFirstTask>

  11:     <Message Text="El resultado es: $(OutputData)" />

  12:   </Target>

  13: </Project>

El resultado de ejecución de la tarea es el siguiente

image

En los próximos posts, un poco de material más profundo 😀

 

Saludos @ Home

El Bruno

   

DISCLAIMER: No agrego mucho detalle sobre la creación del proyecto, ni explicaciones de funcionamiento, porque creo que viendo los 2 ejemplos de código; más el screenshot del resultadao mucha gente ya podrá darse una idea de como funciona. En caso contrario –> MSDN y curso de pago 😀

[EVENTO] Algunas reflexiones que me quedaron después de “Ciclo de Vida Unplugged” @ MadridDotNet

image

Buenas,

anoche llegué un poco tarde a la mesa redonda “Ciclo de Vida Unplugged” que organizamos con los chicos de MadridDotNet. La verdad es que era la primera vez que organizábamos un evento de este tipo, y siendo 10 o 12 personas, la verdad que, según mi punto de vista, el resultado fué bastante productivo. Como una de las lecciones aprendidas es intentar organizar las reuniones como “reuniones”, con un temario y un objetivo a tratar, dejaré algunos puntos que son los que me llamaron la atención.

  • Cuando llegué había una discusión muy buena sobre como llevar adelante proyectos, independientemente de la metodología, pero en todos los casos había una especie de capa gris en la capa de management.
  • Existe una sensación general de que los mandos de gestión de proyectos de informática no tienen la formación necesaria para llevar a cabo esta tarea.
  • Más sobre metodología, una frase que derrumba muros y que no me canso de escuchar: “si en un equipo tienes 5 cracks, no importa que metodlogía utilices, el proyecto seguramente será un éxito”.
  • Tema a discutir: sobre la base de que debes tratar a tu equipo como iguales, cómo gestionar cuando dentro de un equipo exista un crack y uno no tan crack? se debe incentivar más a uno que al otro? las diferencias son buenas?
  • Hablamos sobre trabajar con Factorías/Empresas de Software/Developers en la India, hubo experiencias buenas y malas. Eso sí, todos estamos de acuerdo que son más baratos, que todos tienen bigotito que son muy buena gente, y que muchas veces carecen de iniciativa.
  • J nos comentó como lleva adelante su equipo de 4 personas con SCRUM y cómo la experiencia es muy buena, aunque se dá cuenta de que siempre estima por debajo de la realidad. Lo bueno es que en su retrospectiva personal, ya sabe que estima por debajo 😀
  • No entramos en detalle para hablar de herramientas, pero sí hicimos una lista de los mínimos para trabajar, yo propuse la siguiente: Gestor de código fuente, Gestor de compilaciones. Gestor de Bugs, Tareas, Requisitos/Escenarios/Historias de Usuario y Pizarra. No todos tenían todas las herramientas, pero todos llevaban adelante el trabajo.
  • También hablamos de la mala gestión que existe en las reuniones aquí en España. Personalmente opino que es algo cultural, ya que muchas veces las reuniones son una excusa que tienen las personas para demostrar que están trabajando; pero cuesta mucho organizar una reunión (que no debería durar más de 20 min) e intentar llevarla adelante. Un gran ejemplo –> el evento de ayer 😀
  • El amigo C, que trabaja en una factoría de aviones, soltó una frase lapidaria para vender el porqué de la necesidad de las pruebas: “Sabés porqué no se caen los aviones? por todas las pruebas que les hacen a los mismos
  • ¿Porqué existe esa necesidad en muchas empresas de tener que verte para estar convencidos de que estás trabajando? V dió una respuesta demoledora sobre el problema cultural que existe detrás de todo esto, y que no permite que muchas personas trabajen desde casa.

La verdad que fueron 2 horas muy buenas, no apunté todo lo que hablamos y mucho menos las conclusiones a las que llegamos, pero si que me gustó participar en una reunión diferente donde la tecnología era lo secundario y donde las experiencias eran lo principal 😀

Saludos @ Here

El Bruno

   

[MSBUILD] #ReSharper –> analizando la estructura de los archivos de MSBuild con File Structure

image

Buenas,

hoy también toda hacer un poco de publicidad gratuita pero la verdad es que cuando trabajas con archivos grandes de MSBuild, el panel de Resharper File Structure (Ctrl + Alt +  F) es una de las mejores ayudas que puedes tener. El mismo te muestra una vista en modo árbol de un archivo .proj, en el que es posible distinguir, entre otras cosas:

  • definición de propiedades
  • definición de grupos de propiedades
  • la declaración de Imports
  • la declaración de Usings
  • los targets y los elementos internos de los mismos
  • etc …

El siguiente proyecto de ejemplo, tiene un poco de complejidad y varios elementos diferentes:

   1: <Project DefaultTargets="Inicio"

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

   3:   <UsingTask AssemblyFile="c:srcBrunoAgile01TfsBuildbinDebugElBruno.TfsBuild.dll"

   4:              TaskName="ElBruno.TfsBuild.StringConcatenate" />

   5:   <ItemGroup>

   6:     <Dll Include="c:EntLib50Srcbin*.dll" />

   7:     <Exe Include="c:EntLib50Srcbin*.exe" />

   8:   </ItemGroup>

   9:   <PropertyGroup>

  10:     <Nombre>Bruno</Nombre>

  11:     <Edad>34</Edad>

  12:   </PropertyGroup>

  13:   <Target Name="Inicio">

  14:     <CreateProperty Value="Nombre: $(Nombre) -> Edad: $(Edad)">

  15:       <Output TaskParameter="Value" PropertyName="NuevaPropiedad"/>

  16:     </CreateProperty>

  17:     <Message Text="$(NuevaPropiedad)" />

  18:   </Target>

  19:   <Target Name="Ejemplo">

  20:     <ElBruno.TfsBuild.StringConcatenate Items="@(Dll)"

  21:                                         Separator=";"

  22:                                         AppendLine="false">

  23:       <Output TaskParameter="StringResult" PropertyName="StringResultDll" />

  24:     </ElBruno.TfsBuild.StringConcatenate>

  25:     <ElBruno.TfsBuild.StringConcatenate Items="@(Exe)"

  26:                                         Separator=";"

  27:                                         AppendLine="false">

  28:       <Output TaskParameter="StringResult" PropertyName="StringResultExe" />

  29:     </ElBruno.TfsBuild.StringConcatenate>

  30:     <Message Text="$(StringResultDll)" />

  31:     <Message Text="=======================================" />

  32:     <Message Text="$(StringResultExe)" />

  33:   </Target>

  34: </Project>

  35:  

  36: </Project>

La vista de File Structure de este proyecto es la siguiente:

image

 

Simplemente genial !!!

 

 

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

[EVENTO] Ciclo de Vida Unplugged en MadridDotNet (no mates más gatitos !!!)

image Buenas,

con ganas de salir un poco del formato de las clásicas charlas sobre tecnología, el próximo jueves 23 de Septiembre, nos reuniremos con los amigos de MadridDotNet para hablar sobre el ciclo de vida en general.

El evento se titula “Ciclo de Vida Unplugged” y la idea es compartir experiencias e intentar llegar a algún lugar productivo entre todos:

En esta sesión, tipo mesa redonda, trataremos, entre todos de poner en claro como gestionamos el ciclo de vida de nuestras aplicaciones. El objetivo es que todos podamos aprender de todos e ir mejorando en la gestión de nuestros desarrollos. Desde el punto de ¿cómo gestionais los requisitos? ¿y el código fuente? ¿que repositorio de código usais? ¿estrategias de branching?, hasta ¿y cómo hacéis el testing? ¿y el seguimiento de los despliegues? ¿y el ciclo de vida del mantenimiento?

Los moderadores seremos Luis y el que publica el blog (porque el mono que escribe todavía no habla); y realmente esperamos pasar un buen rato con los que se apunten.

El lugar es donde siempre: las oficinas de MS en Pozuelo, y el registro oficial lo pueden hacer en: https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032462873&Culture=es-ES 

 

 

 

 

Saludos @

El Bruno (@elbruno en Twitter)

 

Homepage: http://madriddotnet.spaces.live.com/default.aspx?wa=wsignin1.0&sa=672549957

PD: la imgen que acompaña, es para que recuerdes que cada vez que:

  • no utilices algún mecanismo de control de código fuente
  • no integres frecuentemente
  • no hagas pruebas unitarias
  • etc …

estás matando un gatito !!!

[MSBUILD] ReSharper –> Navegando hacia la declaración/definición de las propiedades

image

Buenas,

que los chicos de JetBrains son unos cracks no es ninguna novedad, ReSharper es un excelente ejemplo de esto. Si programas con VB.Net o C# y lo utilizas, no hace falta que te explique las ventajas que te brinda y lo que te ayuda programando; personalmente yo lo tengo en la lista de las mejores extensiones para Visual Studio 2010.

Ahora bien, si tu vida no es tan agradable y te toca editar archivos de MSBuild, pues aquí también hay algunas ayudas, por parte de ReSharper que son interesantes. Por ejemplo, la capacidad de ir a declaración o definición de una propiedad.

Por ejemplo, supongamos el siguiente archivo de MSBuild. En el mismo hay 2 tipos de propiedades a tener en cuenta:

  • líneas 5 y 6, con una declaración de una propiedad
  • líneas 11 a 13, con la creación de una propiedad

Luego estas propiedades se utilizan en el Target Inicio, en varias ocasiones.

   1: <Project DefaultTargets="Inicio"

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

   3:   <!-- Grupo de Propriedades -->

   4:   <PropertyGroup>

   5:     <Nombre>Bruno</Nombre>

   6:     <Edad>34</Edad>

   7:   </PropertyGroup>

   8:   <!-- Target Inicial -->

   9:   <Target Name="Inicio">

  10:     <!-- Crea una nueva propiedad -->

  11:     <CreateProperty Value="Nombre: $(Nombre) -> Edad: $(Edad)">

  12:       <Output TaskParameter="Value" PropertyName="NuevaPropiedad"/>

  13:     </CreateProperty>

  14:     <!-- Muestra el valor de la nueva propiedad -->

  15:     <Message Text="$(NuevaPropiedad)" />

  16:   </Target>

  17: </Project>

 

Veamos que puede hacer ReSharper para ayudarnos.

Si posicionamos el cursor en la línea 11, donde se utiliza la propiedad $(Nombre) y presionamos Ctrl; podremos ver como la misma se convierte en un link:

image

 

Con un click en el mismo, obviamente iremos a la definición de la propiedad en la línea 5.

image

 

De la misma, forma si queremos acceder a la definición de la propiedad $(Nueva Propiedad), en la línea 15:

image

 

ReSharper nos llevará a la línea de la creación de la misma.

image

 

Cuando trabajas con archivos muy grandes, esto se agradece 😀

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

[MSBUILD] Recopilación de posts para comenzar a conocer MSBuild

image47dd1de4

Buenas,

después de casi un mes de escribir un poco de MSBuild, a continuación el listado de los posts como para ir comprendiendo un poco de que va MSBuild:

 

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

[MSBUILD] Nuevos Targets en MSBuild 4.0: BeforeTargets y AfterTargets (XV)

image47dd1de4

Buenas,

otra de las novedades en MSBuild 4.0, son dos nuevos targets BeforeTargets y AfterTargets. Hasta la versión 3.5 los MSBuild Targets se definen si el comienzo de un Target depende de la salida de otro Target; utilizando varios atributos para especificar el orden en el que se ejecutan los mismos:

  • Initial targets
  • Default targets
  • First target
  • Target dependencies

Ahora en MSBuild 4.0, se han agregado RunBeforeTargets y RunAfterTargets (MSBuild 4.0) que permiten definir los Targets que se ejecutarán antes y después de un determinado Target.

El siguiente ejemplo posee 3 Targets, y en el atributo de proyecto InitialTargets (línea 3) se los define en el siguiente orden:

  • Target 3
  • Target 2
  • Target 1
   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"

   2:          ToolsVersion="4.0"

   3:          InitialTargets="Target3; Target2; Target1">

   4:   <Target Name="Target1" >

   5:     <Message Text="Target1" />

   6:   </Target>

   7:   <Target Name="Target2">

   8:     <Message Text="Target2" Importance="high" />

   9:   </Target>

  10:   <Target Name="Target3">

  11:     <Message Text="Target3" Importance="high" />

  12:   </Target>

  13: </Project>

 

Cuando ejecutamos este proyecto el output del mismo es el siguiente, donde se puede ver como se respeta el orden definido en InitialTargets:

image

 

El siguiente proyecto agrega una pequeña modificación en el Target1 (línea 4), que se define que antes de ejecutar el Target1, se ejecute el Target2.

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

   2:          ToolsVersion="4.0"

   3:          InitialTargets="Target3; Target2; Target1">

   4:   <Target Name="Target1" BeforeTargets="Target2" >

   5:     <Message Text="Target1" />

   6:   </Target>

   7:   <Target Name="Target2">

   8:     <Message Text="Target2" Importance="high" />

   9:   </Target>

  10:   <Target Name="Target3">

  11:     <Message Text="Target3" Importance="high" />

  12:   </Target>

  13: </Project>

 

La compilación del proyecto es la siguiente, en la que se puede ver el cambio de orden en la ejecución de los Targets:

image

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

[MSBUILD] Otra novedad en MSBuild 4.0: Property Functions (XIV)

image47dd1de4

Buenas,

otra de las novedades incluidas en MSBuild 4.0 son las MSBuild Property Functions. Las mismas permiten trabajar con funciones básicas de scripting para evaluar los valores de una propiedad, incluyendo tareas básicas para trabajo con Strings y otras clases de .Net Framework.

El siguiente proyecto muestra diferentes ejemplos sobre una propiedad:

  • Línea 8: el valor inicial de la propiedad
  • Línea 9: el valor de la propiedad en mayúsculas
  • Línea 10: el valor de la propiedad en minúsculas
  • Línea 11: un substring a partir del valor de la propiedad
  • Línea 12: una evaluación para verificar si la propiedad contiene una cadena

 

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

   2:          ToolsVersion="4.0"

   3:          InitialTargets="Target1">

   4:   <PropertyGroup>

   5:     <Nino>Valentino</Nino>

   6:   </PropertyGroup>

   7:   <Target Name="Target1">

   8:     <Message Text="Valentino: $(Nino)" />

   9:     <Message Text="Upper: $(Nino.ToUpper())" />

  10:     <Message Text="Lower: $(Nino.ToLower())" />

  11:     <Message Text="Substring: $(Nino.Substring(5,4))" />

  12:     <Message Text="Contains Nino: $(Nino.Contains('Nino'))" />

  13:   </Target>

  14: </Project>

 

El resultado de este proyecto es el siguiente:

image

 

Además es posible trabajar con fechas, variables de entorno, etc. El siguiente proyecto muestra un ejemplo, con varios de estos casos:

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

   2:          ToolsVersion="4.0"

   3:          InitialTargets="Target1">

   4:   <Target Name="Target1">

   5:     <Message Text="Time: $([System.DateTime]::Now.ToString('hhmmss'))" Importance="high" />

   6:     <Message Text="Environment Variables: $([System.Environment]::GetEnvironmentVariables().Count)" />

   7:     <Message Text="Processor: $([System.Environment]::GetEnvironmentVariable('PROCESSOR_IDENTIFIER'))" Importance="high" />

   8:     <Message Text="New Guid: $([System.Guid]::NewGuid().ToString())" />

   9:   </Target>

  10: </Project>

 

El resultado es el siguiente:

image

 

La referencia completa de las MSBuild Property Functions se encuentra en http://msdn.microsoft.com/en-us/library/dd633440.aspx 

 

Saludos @ Here

El Bruno (@elbruno en Twitter)