image47dd1de4

Buenas,

el amigo Michael Perfetti ha actualizado su control para WorkItems para TFS2010. Este WorkItem custom control muestra información histórica de un control en formato gráfico y la verdad es que es muy fácil de utilizar y se agradece la funcionalidad del mismo.

Una vez instalado el WorkItem Custom Control, es posible modificar la definición de un WorkItem y agregar este control, como muestra la siguiente imagen.

WorkflowControl_In_Layout.png

A partir de este momento, cuando visualicemos o editemos un WorkItem podremos ver en el nuevo control diferentes aspectos de la historia del WorkItem, tanto en la vista de Visual Studio como en la vista WebAccess

Visual Studio 2010 View

image 

WebAccess View

image

 

Además posee diferentes opciones de agrupamiento:

Activity

image

Assigned To

image

Changed By

image

Integration Build (this one Rocks !!!!)

image

Iteration Path

image

Priority

image

En excelente control tanto para TFS2010, como para TFS2008.

 

 

 

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

Homepage: http://tfsworkflowcontrol.codeplex.com

Publicado 2/9/2010 19:38 por El Bruno | con no comments

image47dd1de4

Buenas,

ayer fue el turno de las condiciones, asi que es natural que el siguiente post esté relacionado con los CASE/Switch o MSBuild Conditional Constructs, como se definen en MSDN. Este elemento nos permite armar sentencias de selección utilizando:

Como lo mejor es leer un poco de código para comprenderlo, vamos con un proyecto de ejemplo. El siguiente proyecto define una propiedad $(Nino) (línea 3 a 5), que luego es utilizada dentro de un bloque <Choose> para actuar en consecuencia del valor de la misma. Utilizando un evaluador <When> (líneas 7 a 11), se compara el valor de la propiedad y además para el caso de que no coincida, se utiliza además la sentencia <Otherwise> (líneas 12 a 16).

En ambos casos se define un valor para la propiedad $(Msg) que luego se muestra en el MSBuild Target inicial del proyecto.

 

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
   2:          InitialsTargets="Target1">
   3:   <PropertyGroup>
   4:     <Nino>Martina</Nino>
   5:   </PropertyGroup>
   6:   <Choose>
   7:     <When Condition="'$(Nino)'=='Valentino'">
   8:       <PropertyGroup>
   9:         <Msg>Nino == Valentino</Msg>
  10:       </PropertyGroup>
  11:     </When>
  12:     <Otherwise>
  13:       <PropertyGroup>
  14:         <Msg>OtherWise -> Nino != Valentino</Msg>
  15:       </PropertyGroup>
  16:     </Otherwise>
  17:   </Choose>
  18:   <Target Name="Target1">
  19:     <Message Text="$(Msg)"/>
  20:   </Target>
  21: </Project>

El resultado es el siguiente:

image

Si defino otro valor para la propiedad $(Nino), por ejemplo por línea de comandos

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>msbuild "C:\srcBruno\Agile01\MsBuild Tests\Case_1.targets" /property:Nino=Valentino

El resultado es el siguiente:

image

 

 

 

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

image47dd1de4

Buenas,

las condiciones en MSBuild se aplican a casi todos los elementos y tareas que están disponibles para utilizar a través del atributo @Condition. En esta entrada de MSDN: MSBuild Conditions, se explican todos los tipos de condiciones soportados, pero viene bien mostrar un par de ejemplos.

El siguiente proyecto, define una propiedad $(Nino) (línea 4) y luego ejecuta una tarea para mostrar un mensaje, dependiendo de una condición donde se evalua si el valor de la propiedad es igual a [Valentino] (línea 8):

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
   2:   <!-- Grupo de Propriedades -->
   3:   <PropertyGroup>
   4:     <Nino>Valentino</Nino>
   5:   </PropertyGroup>
   6:   <Target Name="Target1">
   7:     <Message Text="'$ (Nino)'=='Valentino'"
   8:              Condition="'$(Nino)'=='Valentino'" />
   9:   </Target>
  10: </Project>

 

El resultado del proyecto es el siguiente:

image

 

Si en cambio definimos una condición que no se cumpla

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
   2:   <!-- Grupo de Propriedades -->
   3:   <PropertyGroup>
   4:     <Nino>Valentino</Nino>
   5:   </PropertyGroup>
   6:   <Target Name="Target1">
   7:     <Message Text="'$ (Nino)'=='Bruno'"
   8:              Condition="'$(Nino)'=='Bruno'" />
   9:   </Target>
  10: </Project>

En el resultado no veremos el mensaje.

Otra opción es trabajar con condiciones complejas, ya que podemos utilizar los operadores clásicos AND y OR para estas situaciones:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
   2:   <!-- Grupo de Propriedades -->
   3:   <PropertyGroup>
   4:     <Nino>Valentino</Nino>
   5:     <Nina>Martina</Nina>
   6:   </PropertyGroup>
   7:   <Target Name="Target1">
   8:     <Message Text="Condicion Simple"
   9:              Condition="'$(Nino)'=='Valentino'" />
  10:     <Message Text="Condicion Simple Inválida"
  11:              Condition="'$(Nino)'!='Valentino'" />
  12:     <Message Text="Condicion Compuesta"
  13:              Condition="'$(Nino)'=='Valentino' AND '$(Nina)'!='Valentino'" />
  14:   </Target>
  15: </Project>

 

En donde podremos ver que se muestran solo el primer y tercer mensaje:

image

 

Y si en lugar de tareas de mensajes, aplicamos condiciones a llamadas a Targets, con la tarea CallTarget

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
   2:   <!-- Grupo de Propriedades -->
   3:   <PropertyGroup>
   4:     <Nino>Valentino</Nino>
   5:     <Nina>Martina</Nina>
   6:   </PropertyGroup>
   7:   <Target Name="Target1">
   8:     <CallTarget Targets="Target2"
   9:              Condition="'$(Nino)'=='Valentino'" />
  10:     <CallTarget Targets="Target3"
  11:              Condition="'$(Nino)'!='Valentino'" />
  12:     <CallTarget Targets="Target4"
  13:              Condition="'$(Nino)'=='Valentino' AND '$(Nina)'!='Valentino'" />
  14:   </Target>
  15:   <Target Name="Target2">
  16:     <Message Text="Target 2" />
  17:   </Target>
  18:   <Target Name="Target3">
  19:     <Message Text="Target 3" />
  20:   </Target>
  21:   <Target Name="Target4">
  22:     <Message Text="Target 4" />
  23:   </Target>
  24: </Project>

pues el resultado es el mismo:

image

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

image

Buenas,

usualmente no suelo escribir opiniones sobre este tipo de decisiones, siempre tengo miedo de caer en un blog amarillista como esos que se dedican a opinar o especular sobre productos informáticos pero que nunca han dedicado más de 2 minutos a realmente ver el detalle que esconden los mismos –> alt1040 es el mejor ejemplo.

Otro ejemplo son aquellos que atacan a Microsoft y defienden el software libre, bajo las premisas:

“puedo conocer lo que hace la aplicación XXX, puedo modificar y compartir la aplicación XXY, etc.”

Pero cuando se les pregunta en cuantos proyectos de software libre han participado, o cuantas veces han leido el código fuente del product XAY, XPY o XBY; pues te terminas dando cuenta que en realidad lo que buscan es software gratis. Este comentario, en un post sobre el software libre lo dice todo independientemente de los errores ortográficos:

“pues yo eligo firefox por ser una exelente aplicacion , y si fuera cerrado y de pago , me lo bajaria con torrent keygen incluido”

El otro extremo son los apple fanboys, pero si empiezo con esos, puedo escribir otro libro … !!!!

Si has leido hasta aquí seguramente te preguntarás 2 cosas:

Para la primera respuesta, tendrás que pasar por casa/caja; pero la 2da es mucho más interesante.

Hasta hace poco tiempo, la licencia con la que se distribuía la información de SDL era una licencia propietaria de Microsoft, que básicamente cerraba todas las puertas sobre los contenidos. Sin embargo, desde hace un par de días, esta política se ha cambiado y de a poco la documentación relacionada con SDL se publicará bajo una licencia Creative Commons (el detalle completo de utilización de la información bajo esta licencia se puede leer aquí).

Yo no soy ningún experto en modelos de licenciamiento, pero si puedo augurar un par de escenarios muy interesantes:

  • A partir de este momento, muchas empresas podrán comenzar a utilizar SDL como base para construir sus propios modelos de seguridad. Todos sabemos que ningún producto o tecnología cubre 100% las necesidades de una organización, pues con este modelo será mucho más fácil.
  • A partir de este momento, muchas empresas podrán comenzar a incorporar información, que se encuentra dentro de SDL, y compartirla con partners, clientes, etc.
  • A partir de este momento, seguramente veremos en muchos más lados los Training Materials, Case Studies, WhitePapers, etc.; propios de SDL
  • Esto puede ser la base para que otros equipos de producto, comiencen a cambiar el modelo de licenciamiento de la información en MS.

 

Y la pregunta final:

¿Porqué cambia el modelo de licenciamiento Microsoft?

Obviamente no tengo la respuesta, pero si una teoría al respecto

Por todos es sabido que los productos de Microsoft tienen fama de inseguros. Esto sucede cuando eres dueño de una cuota muy grande en un mercado, y además cuando tus productos son la plataforma en la que se desarrollan muchas aplicaciones. Pero, ¿qué sucede cuando el problema no es la plataforma, sino los productos que se desarrollan para la misma? (un ejemplo), pues que los blogs amarillistas se llenan de noticias anti-Microsoft y solo unos pocos profesionales serios se ponen a estudiar estos “problemas de seguridad” y llegan a conclusiones que nada tiene que ver con las ideas originales.

¿Qué hacer en estos casos?, pues promover buenas prácticas de creación de productos en lo referido a seguridad y de eso se trata en gran parte SDL. Al cambiar la forma de licenciamiento, espero yo que más de uno comience a leer estos documentos y probar las herramientas.

Finalmente comentar que el cambio de licencia se aplica a la documentación relacionada con SDL, no a los productos; que Microsoft todavía no vive del aire y tiene que cobrar unos €urakos por utilizar los mismos. Y hablando de vivir del aire, me voy a jugar con mi enano, que de seguridad solo tiene el casco de su bici.

 

Saludos @ Home

El Bruno (@elbruno en Twitter)

 

PostDatas amarillistas

PD1: si este fuese un blog amarillista el título del post sería algo así como “Microsoft es software libre !!! con licencia Creative Commons !!!”

PD2: si este fuese un blog amarillista, debería poner una foto mía con gafas pasta a la moda, una barba de 2 días, y cara de pensar “tengo el gadget que tu nunca conocerás y que yo nunca aprenderé a utilizar”

Publicado 31/8/2010 19:02 por El Bruno | 3 comment(s)
Archivado en: ,,

image47dd1de4

Buenas,

después de hablar de uno de los elementos que nos permiten modularizar la ejecución de nuestros proyectos de MSBuild: los MSBuild Targets, otra opción que poseemos es poder importar/incluir archivos de proyecto de MSBuild en otros archivos de proyectos. Para esto se utiliza la etiqueta <Import>. La misma permite incluir el contenido de un archivo externo dentro del archivo de proyecto en la que se define.

Por ejemplo, si existe un archivo en [C:\srcBruno\Agile01\MsBuild Tests\Imports_1.targets] con el siguiente contenido dentro del mismo:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
   2:   <Target Name="TargetImport1">
   3:     <Message Text="Target Import 1" />
   4:   </Target>
   5: </Project>

El ejemplo siguiente muestra como, desde un nuevo archivo de proyecto de MSBuild, es posible incluir el contenido de este archivo e invocar al MSBuild Target: TargetImport1 ( línea 3), e invocar al target definido en el archivo externo (línea 6).

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          InitialTargets="Target1">
   3:   <Import Project="C:\srcBruno\Agile01\MsBuild Tests\Imports_1.targets"/>
   4:   <Target Name="Target1">
   5:     <Message Text="Target 1" />
   6:     <CallTarget Targets="TargetImport1"></CallTarget>
   7:   </Target>
   8: </Project>

 

La ejecución de este proyecto nos muestra como se ejecuta el mismo, con el target externo.

image

 

En este punto todo funciona, pero si eres una persona organizada seguramente te choca bastante que la ubicación del archivo externo necesite ser defina con el path completo. Para evitar este tipo de situaciones existen varias opciones.

El siguiente proyecto muestra una opción, en la que se define en una propiedad llamada $(SampleBuildLocation), el path con la ubicación de los archivos externos. Para definir el valor de esta propiedad, se crea un <PropertyGroup> (líneas 4 a 7), y dentro de la misma se realizan 2 acciones:

  • En primer lugar (línea 5), se intenta definir relativamente la ubicación del directorio, utilizando una Condición (ya hablaré de las mismas más adelante) y el valor de la propiedad $(BuildPath).
  • En segundo lugar (línea 6), se verifica el valor de la propiedad y si la misma es un string vacio, se define “en duro” el path con la ubicación de los archivos

A continuación, se realiza el <Import> del proyecto utilizando la propiedad $(SampleBuildCondition), y además se muestra el valor de las propiedades utilizadas en el MSBuild Target principal (líneas 10 y 11):

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          InitialTargets="Target1">
   3:   <!-- Imports de archivos de proyecto externos -->
   4:   <PropertyGroup>
   5:     <SampleBuildLocation Condition="Exists('$(BuildPath)\..\Tests\')">$(BuildPath)\..\Tests\</SampleBuildLocation>
   6:     <SampleBuildLocation Condition="'$(SampleBuildLocation)' == ''">C:\srcBruno\Agile01\MsBuild Tests\</SampleBuildLocation>
   7:   </PropertyGroup>
   8:   <Import Project="$(SampleBuildLocation)\Imports_1.targets"/>
   9:   <Target Name="Target1">
  10:     <Message Text="Build Path: $(BuildPath)" />
  11:     <Message Text="Sample Tfs Build: $(SampleBuildLocation)" />
  12:     <Message Text="Target 1" />
  13:     <CallTarget Targets="TargetImport1"></CallTarget>
  14:   </Target>
  15: </Project>

 

La ejecución de este proyecto nos muestra como la propiedad $(BuildPath) no posee valor y además el valor con el que se arma el path para incluir el archivo externo.

image 

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

image47dd1de4

Buenas,

una vez definidos nuestros MSBuild Targets, es momento de controlar el flujo de llamadas entre ellos. Para esto utilizamos la tarea de MSBuild: CallTarget. Esta tarea tiene una sintaxis muy simple, y el atributo @Targets, define los MSBuild Targets que se invocarán.

Por ejemplo, en el siguiente proyecto, existen definidos 3 Targets:

  • Target1
  • Target2
  • Target3

y utilizando la tarea CallTarget, se define el siguiente flujo de llamadas: Target1 –> Target2 –> Target3, en las líneas 5 y 9:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          InitialTargets="Target1">
   3:   <Target Name="Target1">
   4:     <Message Text="Target 1" />
   5:     <CallTarget Targets="Target2" />
   6:   </Target>
   7:   <Target Name="Target2">
   8:     <Message Text="Target 2" />
   9:     <CallTarget Targets="Target3" />
  10:   </Target>
  11:   <Target Name="Target3">
  12:     <Message Text="Target 3" />
  13:   </Target>
  14: </Project>

 

El resultado de la ejecución del prioyecto es similar al siguiente:

image

 

Ahora bien, esta tarea además de gestionar la llamada entre MSBuild Targets, analiza las dependencias entre los mismos al momento de ejecutar para evitar bucles infinitos.

El siguiente proyecto, muestra un ejemplo de un bucle infinito, donde el Target1 se llama a si mismo.

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          InitialTargets="Target1">
   3:   <Target Name="Target1">
   4:     <Message Text="Target 1" />
   5:     <CallTarget Targets="Target1" />
   6:   </Target>
   7: </Project>

 

Si intentamos ejecutar este proyecto, veremos que el compilador de MSBuild, se encarga de alertarnos sobre una dependencia circular:

image

 

Finalmente un caso común a tener en cuenta, es aquel en donde necesitamos invocar a un MSBuild Target, varias veces pero con diferentes valores. Es decir, similar a llamar a una función pasando diferentes valores a los parámetros de la misma.

El siguiente ejemplo muestra un proyecto en donde, en el MSBuild Target principal Target1, se invoca a un nuevo MSBuild Target denominado Target2, que muestra en ell output los valores de las propiedades $(Name) y $(Edad) (líneas 14 y 15).

Esta invocación no la realizo utilizando la tarea CallTarget, y además utilizo la tarea MSBuild Task para realizar la llamada, con las siguientes consideraciones:

  • Utilizo el proyecto actual como proyecto a compilar, asignando $(MSBuildProjectFile) al atributo @Projects.
  • Defino el Target2 como el MSbuild Target a invocar, en el atributo @Targets.
  • Defino las propiedades $(Name) y $(Edad) con valores diferentes en cada llamada (líneas 8 y 11).

 

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          DefaultTargets="Target1">
   3:   <Target Name="Target1">
   4:     <Message Text="Target 1" />
   5:     <CallTarget Targets="Target2" />
   6:     <MSBuild Projects="$(MSBuildProjectFile)"
   7:              Targets="Target2"
   8:              Properties="Name=Valentino;Edad=2" />
   9:     <MSBuild Projects="$(MSBuildProjectFile)"
  10:              Targets="Target2"
  11:              Properties="Name=Martina;Edad=Casi 1" />
  12:   </Target>
  13:   <Target Name="Target2">
  14:     <Message Text="Name = $(Name)" />
  15:     <Message Text="Edad = $(Edad)" />
  16:   </Target>
  17: </Project>

 

Este proyecto, invoca nuevamente al compilador de MSBuild y en lugar de comenzar por el Target1, definido como @DefaultTarget, inicia en el Target2, e inicializa las propiedades con los valores correspondientes. El resultado de la ejecución muestra como no existen valores para las propiedades en la primera llamada, pero si se muestran datos en las llamadas con la tarea MSBuild Task.

image

 

Saludos @ Here

El Bruno (@elbruno en Twitter)

image47dd1de4

Buenas,

en el post anterior comentaba como funciona un elemento básico de MSBuild, como son los MSBuild Target. Un detalle interesante a tener en cuenta cuando trabajamos con estos elementos es la captura de excepciones. Soy conciente de que muchos de ustedes no tienen errores en el código, pero como yo soy un poco corto de luces y en la cabeza solo tengo pelos, pues tengo que aprovechar la tarea <OnError> para gestionar este tipo de escenarios.

Sunpongamos el siguiente proyecto de MSBuild, donde el target principal <Target1>, invoca a una tarea que no existe <EstaTareaNoExiste> en la línea 4. Para controlar este error, en la línea 5, he utilizado el elemento <OnError> definiendo que se invoque al target <GestionError> en el caso de que se produzca un error:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          InitialTargets="Target1">
   3:   <Target Name="Target1">
   4:     <EstaTareaNoExiste />
   5:     <OnError ExecuteTargets="GestionError" />
   6:   </Target>
   7:   <Target Name="GestionError">
   8:     <Message Text="Ha ocurrido un error !!!" />
   9:   </Target>
  10: </Project>

 

La ejecución nos muestra como se dispara el error, relacionado con la tarea que no existe y a continuación se muestra el mensaje definido en el target de gestión de errores (línea 8).

image

 

 

 

 

Saludos @ Home

El Bruno (@elbruno en Twitter)

image47dd1de4

Buenas,

en el mini post de hoy, veremos uno de los componentes más importantes de MSBuild: los MSBuild Targets. Los mismos permiten definir bloques o secciones de acciones de manera que sea posible organizar la ejecución de un proyecto de compilación de una forma más ordenada. Haciendo una analogía con la programación que conocemos, un MSBuild Target, es algo similar a una función.

Un ejemplo simple de un proyecto donde se utilicen MSbuild Targets es el siguiente:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   2:   <Target Name="Target1">
   3:     <Message Text="Target 1" />
   4:   </Target>
   5:   <Target Name="Target2">
   6:     <Message Text="Target 2" />
   7:   </Target>
   8: </Project>

Donde podemos ver que el archivo de proyecto, posee 2 elementos <Target> definidos (líneas 2 y 5) y dentro de los mismos, se utiliza la tarea <Message> para mostrar información.  Si ejecutamos el archivo de proyecto, veremos que se toma el primer MSBuild Target (línea 2), como el predefinido y se ejecuta el mismo:

image

Si necesitamos definir uno o más targets por defecto, para nuestro proyecto, es posible hacerlo utilizando el atributo @DefaultTargets en el elemento <Project>.

En el siguiente ejemplo, definimos como target por defecto el Target2:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          DefaultTargets="Target2">
   3:   <Target Name="Target1">
   4:     <Message Text="Target 1" />
   5:   </Target>
   6:   <Target Name="Target2">
   7:     <Message Text="Target 2" />
   8:   </Target>
   9: </Project>

La ejecución del proyecto, nos muestra como en este caso se muestra el mensaje definido en el Target2 (línea 7):

image

 

 

 

 

Si necesitamos definir más de un target por defecto para nuestro proyecto, lo podemos realizar del mismo modo.

El siguiente proyecto de ejemplo muestra un caso, donde los DefaultTargets son Target1 y Target3:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
   2:          DefaultTargets="Target1;Target3">
   3:   <Target Name="Target1">
   4:     <Message Text="Target 1" />
   5:   </Target>
   6:   <Target Name="Target2">
   7:     <Message Text="Target 2" />
   8:   </Target>
   9:   <Target Name="Target3">
  10:     <Message Text="Target 3" />
  11:   </Target>
  12: </Project>

La ejecución de este proyecto muestra los mensajes correspondientes a cada <Target> (líneas 4 y 10).

image

Si bien es posible utilizar el atributo @DefaultTargets para indicar los MSBuild Targets que queremos ejecutar, también existen otras opciones:

  • Utilizar el atributo @InitialTargets para indicar los targets a ejecutar en el elemento <Project>.
  • Utilizar el comando /target en la llamada a la compilación del proyecto para definir el target a ejecutar.

El en 2do ejemplo volvemos al primer ejemplo de ejecución, donde no hemos definido un target por defecto, ni un target inicial:

   1: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   2:   <Target Name="Target1">
   3:     <Message Text="Target 1" />
   4:   </Target>
   5:   <Target Name="Target2">
   6:     <Message Text="Target 2" />
   7:   </Target>
   8: </Project>

 

Y en la compilación por línea de comandos indicamos la ejecución del Target2 como el punto de entrada del proyecto de Build, con el switch /target:Target2.

image

Pues bien, como siempre más información en MSDN http://msdn.microsoft.com/en-us/library/ee216359.aspx.

 

Saludos @ Home

El Bruno (@elbruno en Twitter)

Clipboard02

Buenas,

cuando hace unos días ví que estaba disponible una guía de despliegue para Visual Studio Lab Management 2010,  me dije “por fin, una guía decente para poder comenzar”. Así que me fuí a MSDN, y descargue la misma.

image

La sorpresa fue cuando, una vez descargado el instalador, me encontré un documento de texto de aprox 27KB, que básicamente posee links a las referencias de Visual Studio Lab Management 2010 en MSDN (si haces click en el link anterior ya tenes el 50% del doc).

Como es sábado y estoy cansado de escuchar quejas … paso de quejarme y recomiendo no perder el tiempo con la descarga. En su lugar, ir directamente a la documentación de MSDN.

 

 

 

 

Saludos @ Home

El Bruno (@elbruno en twitter)

image47dd1de4

Buenas,

el equipo de Microsoft Research a cargo de Pex, a creado un sitio más que interesante para que aprendamos un poco más sobre la utilización de Pex y que recordemos conceptos básicos de programacón en más de un caso.

El site Pex for Fun propone una serie de retos (Pex duels) para que sean analizados con Pex. Estos retos son fragmentos de código en C#, Visual Basic.Net y F# que se presentan para que los completemos directamente en el sitio web y luego sean analizados por el motor de Pex.

Por ejemplo, si se nos presenta el siguiente problema “puzzle”, tenemos una función con 2 parámetros de entrada y un código incierto por determinar.

   1: using System;
   2: using Microsoft.Pex.Framework;
   3:  
   4: public class Program
   5: {
   6:     public static int Puzzle(int x, int y)
   7:     {
   8:         // Can you write code to solve the puzzle? Ask Pex to see how close you are.
   9:         return x;
  10:     }
  11: }

 

Podemos ver que al momento de analizar el código, el mismo verifica los parámetros y suma los mismos:

image

 

La solución rápida que se nos ocurre es la siguiente:

   1: using System;
   2: using Microsoft.Pex.Framework;
   3:  
   4: public class Program
   5: {
   6:     public static int Puzzle(int x, int y)
   7:     {
   8:         // Can you write code to solve the puzzle? Ask Pex to see how close you are.
   9:         return x + y;
  10:     }
  11: }

 

Si analizamos nuevamente el reto, vemos que estamos más cerca pero no lo suficiente:image

 

A partir de aquí es necesario modificar un poco más el código, para que el mismo sea correcto. 

Lo interesante de esto, es que hay bastantes ejemplos diferentes que van desde escenarios donde hay que ordenar arrays, verificar si un string es un anagrama, etc. Lo recomendable es elegir uno al azar, juntarnos con un compañero y ver quien lo saca en menos tiempo. Eso sí, con una cerveza como premio final pagada por el perdedor.

 

 

 

 

Saludos @ Home

El Bruno (@elbruno en Twitter)

Recursos

image47dd1de4

Buenas,

gracias al amigo Javier (@jcalvarro), me entero de una interesante herramienta para configurar entornos con Team Foundation Server 2010 y Sharepoint 2007 o Sharepoint 2010. Si bien la versión 2010 de TFS simplifica mucho la instalación y configuración de estas herramientas, todavía es un poco infierno el tener que lidiar con algunos aspectos de Sharepoint+TFS. Esta herramienta que se puede descargar desde la Visual Studio Gallery, se gestiona en modo asistente.

Una vez seguidos los pasos básicos de configuración desde TFS con Sharepoint, que se explican en Add Integration with SharePoint Products to a Deployment of Team Foundation Server, estas son las opciones que se configuran para la integración en Office SharePoint Server 2007:

  • Shared Service Provider (SSP)
  • Excel Services
  • Single Sign-on

Y estas en SharePoint Server 2010:

  • Excel Services
  • Secure Store Service

La siguiente imagen muestra un ejemplo de la herramienta, para la configuración de varios servicios en Sharepoint 2010:

image

 

Luego podemos ver como se aplican los cambios definidos:

image

 

Y terminar con el clásico y tan esperado Success

image

Si ya tienes un entorno en marcha con Sharepoint y TFS, esta herramienta dejará de lado los pasos y opciones ya configuradas. Pero podrás ver que opciones adicionales tienes para trabajar.

 

 

 

 

Saludos @ Home

El Bruno (@elbruno en Twitter)


Descarga: http://visualstudiogallery.msdn.microsoft.com/en-us/db469790-5e3e-42f3-906e-411a73795a1b

image47dd1de4

Buenas,

se van acabando las vacaciones asi que me toca ponerme al día de a poco … en este caso con Microsoft Biology Foundation. Que si bien suena un poco a foundation maligna de película clase B para conquistar al mundo, se autodefine como:

The Microsoft Biology Foundation (MBF) is a language-neutral bioinformatics toolkit built as an extension to the Microsoft .NET Framework, initially aimed at the area of Genomics research. Currently, it implements a range of parsers for common bioinformatics file formats; a range of algorithms for manipulating DNA, RNA, and protein sequences; and a set of connectors to biological web services such as NCBI BLAST. MBF is available under an open source license, and executables, source code, demo applications, and documentation are freely downloadable.

Básicamente es una serie de lenguajes y herramientas (y extensiones de Excel), desarrolladas con Microsoft .Net para el estudio y análisis del genoma. Vamos que suena a japones encriptado, pero sé que de uno que le va a dar un vistazo (es lo que tiene ser hijo de un padre físico especializado en biología).

Más información en CodePlex: http://mbf.codeplex.com/, desde donde además es posible descargar el código fuente de todo el proyecto. Esto último para aquellas personas cortas de vista que piensan que todo lo que se desarrolla bajo tecnología MS es código cerrado y con licencia APS (Acuerdo de Privacidad con Satanás).

 

 

 

Saludos @ Home

El Bruno

Fuente: http://www.xconomy.com/seattle/2010/05/03/microsoft-builds-open-source-tool-for-biologists-drowning-in-data-an-on-ramp-for-customers-who-pay/

image47dd1de4

Buenas,

post cortito para un viernes. Hoy toca darle un repaso a una extensión para ReSharper, llamada WhySharper. Esta extension agrega una nueva opción de menú en las acciones que se proponen en ReSharper con el clásico Alt+Enter, en la que se agrega un “Why … action”, es decir, se explica el porqué de la propuesta de cambio por R#.

Como siempre, un par de imágenes valen más que un par de miles de palabras:

 

 

 

 

 

Saludos @ Here

El Bruno

Descarga: http://code.google.com/p/whysharper/

Clipboard02

Buenas,

hoy toca un poco de promoción:

La versión Release de Visual Studio 2010 Lab Management está disponible para comenzar a trabajar con la misma.

Seguramente te preguntarás de que hablo, ya que me pasé un par de meses escribiendo al respecto y en MSDN está disponible desde hace tiempo, pero lo que sucede es lo siguiente: la versión con la que actualmente estamos trabajando es una versión “Release Candidate”, la versión oficial se anunció que estaría disponible en Agosto y ayer se hizo oficial la misma.

Lo interesante de LM es que no se venderá como un producto separado, sino que estará disponible como parte de las suscripciones MSDN de Visual Studio 2010 Ultimate, y para la version de Visual Studio 2010 Test Professionals.

Finalmente, si quieres dar los primeros pasos con Visual Studio 2010 Lab Management (me autoplagio), estos son los links a seguir

 

 

 

 

Saludos @ Here

El Bruno

Homepage: http://www.microsoft.com/visualstudio/en-us/solutions/software-quality/lab-management

Publicado 5/8/2010 10:01 por El Bruno | con no comments
Archivado en: ,

image47dd1de4

Buenas,

hoy toca ver un poco somo funcionan el elemento <ItemGroup> en MSBuild. Este elemento permite definir una colección de elementos personalizados,en scripts de MSBuild, para luego poder trabajar con los mismos.

En el siguiente ejemplo, creo una colección de elementos <Cliente>, entre las líneas 6 y 11, con diferentes valores para cada uno de los mismos. Luego utilizo una tarea personalizada que concatena los valores de estos elementos (líneas 15 a 19); y los retorno en una propiedad llamada StringResult (línea 18). A continuación se muestra el valor de esta propiedad.

 

   1: <Project DefaultTargets="Inicio"
   2:          xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   3:   <UsingTask AssemblyFile="c:\srcBruno\Agile01\TfsBuild\bin\Debug\ElBruno.TfsBuild.dll"
   4:              TaskName="ElBruno.TfsBuild.StringConcatenate" />
   5:   <!-- Coleccion de elementos -->
   6:   <ItemGroup>
   7:     <Cliente Include="Bruno" />
   8:     <Cliente Include="Valentino" />
   9:     <Cliente Include="Martina" />
  10:     <Cliente Include="Pao" />
  11:   </ItemGroup>
  12:   <!-- Target Inicial -->
  13:   <Target Name="Inicio">
  14:     <!-- Concatena cadenas -->
  15:     <ElBruno.TfsBuild.StringConcatenate Items="@(Cliente)"
  16:                                         Separator=";" 
  17:                                         AppendLine="true">
  18:       <Output TaskParameter="StringResult" PropertyName="StringResult" />
  19:     </ElBruno.TfsBuild.StringConcatenate>
  20:  
  21:     <!-- Muestra el resultado -->
  22:     <Message Text="$(StringResult)" />
  23:   </Target>
  24: </Project>

El resultado de la ejecución de este proyecto es el siguiente:

image

 

Las colecciones de elementos, también pueden ser utilizadas para trabajar con cantidades “dinámicas” de elementos. El siguiente proyecto de MSBuild, define un ItemGroup en el que se agregan 2 elementos para trabajar con los archivos generados de Enterprise Library, que por lo general se almacenan en la ubicación [C:\EntLib50Src\bin]

  • <Dll>, obtiene todos los archivos con extensión .dll
  • <Exe>, obtiene todos los archivos con extensión .exe

Una vez definidos estos elementos, se concatena el valor de los mismos en 2 propiedades y se muestran las mismas en la consola de MSBuild.

   1: <Project DefaultTargets="Inicio"
   2:          xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   3:   <UsingTask AssemblyFile="c:\srcBruno\Agile01\TfsBuild\bin\Debug\ElBruno.TfsBuild.dll"
   4:              TaskName="ElBruno.TfsBuild.StringConcatenate" />
   5:   <!-- Coleccion de elementos -->
   6:   <ItemGroup>
   7:     <Dll Include="c:\EntLib50Src\bin\*.dll" />
   8:     <Exe Include="c:\EntLib50Src\bin\*.exe" />
   9:   </ItemGroup>
  10:   <!-- Target Inicial -->
  11:   <Target Name="Inicio">
  12:     <!-- Concatena cadenas -->
  13:     <ElBruno.TfsBuild.StringConcatenate Items="@(Dll)"
  14:                                         Separator=";"
  15:                                         AppendLine="false">
  16:       <Output TaskParameter="StringResult" PropertyName="StringResultDll" />
  17:     </ElBruno.TfsBuild.StringConcatenate>
  18:     <ElBruno.TfsBuild.StringConcatenate Items="@(Exe)"
  19:                                         Separator=";"
  20:                                         AppendLine="false">
  21:       <Output TaskParameter="StringResult" PropertyName="StringResultExe" />
  22:     </ElBruno.TfsBuild.StringConcatenate>
  23:     <!-- Muestra el resultado -->
  24:     <Message Text="$(StringResultDll)" />
  25:     <Message Text="=======================================" />
  26:     <Message Text="$(StringResultExe)" />
  27:   </Target>
  28: </Project>

 

El resultado de ejecución del proyecto es el siguiente:

image

 

 

 

 

Los proyectos de ejemplo se pueden descargar desde http://cid-bef06dffdb192125.office.live.com/self.aspx/Code%20Samples/2010%2008%2004%20MsBuild%20ItemGroups.zip

 

Saludos @ Here

El Bruno

image47dd1de4

Buenas,

continuando con el post anterior, donde expliqué un poco la sintáxis y los caractéres de escape que se utilizan en MSBuild para utilizar propiedades, hoy voy a mostrar un par de ejemplos al respecto.

El siguiente ejemplo, muestra un archivo muy simple de MSBuild, en el que:

  • Defino el target por defecto [Inicio] en la línea 1
  • Defino un grupo de propiedades entre las líneas 4 a 7, con 2 propiedades <Nombre> y <Edad>
  • En el target [Inicio] muestro un mensaje compuesto, utilizando los valores de las propiedades

 

   1: <Project DefaultTargets="Inicio"
   2:          xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   3:   <!-- Grupo de Propiedades -->
   4:   <PropertyGroup>
   5:     <Nombre>Bruno</Nombre>
   6:     <Edad>34</Edad>
   7:   </PropertyGroup>
   8:   <!-- Target Inicial -->
   9:   <Target Name="Inicio">
  10:     <Message Text="Nombre: $(Nombre); Edad: $(Edad)" />
  11:   </Target>
  12: </Project>

Para probar este ejemplo, la opción que recomiendo es abrir la consola de comandos de Visual Studio 2010, y desde la misma lanzar el comando

MSBUILD Archivo.proj

donde [archivo.proj] es un archivo de texto con el ejemplo anterior.

Una vez ejecutado el ejemplo, podremos ver un resultado similar el siguiente:

image

 

Además de utilizar las propiedades para mostrar información, podemos utilizar las mismas para evaluar condiciones. El siguiente ejemplo muestra como se han agregado 2 nuevas propiedades <Email> y <MostrarEMail> (líneas 7y 8), y como se muestra un mensaje en la línea 15, dependiendo del valor de la propiedad <MostrarEMail>.

 

   1: <Project DefaultTargets="Inicio"
   2:          xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   3:   <!-- Grupo de Propiedades -->
   4:   <PropertyGroup>
   5:     <Nombre>Bruno</Nombre>
   6:     <Edad>34</Edad>
   7:     <Email>elcorreo@elbruno.com</Email>
   8:     <MostrarEMail>false</MostrarEMail>
   9:   </PropertyGroup>
  10:   <!-- Target Inicial -->
  11:   <Target Name="Inicio">
  12:     <Message Text="Nombre: $(Nombre); 
  13: Edad: $(Edad); 
  14: Mostrar EMail: $(MostrarEMail)" />
  15:     <Message Text="EMail: $(Email)"
  16:              Condition="'$(MostrarEMail)'=='true'"/>
  17:   </Target>
  18: </Project>

 

 

 

 

El resultado de la ejecución del proyecto es el siguiente:

image

 

El último ejemplo de este post, está relacionado  con la tarea CreateProperty de MSBuild. La misma permite crear una propiedad a partir de una serie de valores. El siguiente ejemplo muestra como entre las líneas 11 y 13, se crea una nueva propiedad llamada <NuevaPropiedad> (línea 12), y a la misma se le asigna el valor una cadena de texto con las propiedades <Nombre> y <Edad>. Luego se muestra el valor de la nueva propiedad en la línea 15.

   1: <Project DefaultTargets="Inicio"
   2:          xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   3:   <!-- Grupo de Propiedades -->
   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>

El resultado de la ejecución de este proyecto es el siguiente:

image

 

Los ejemplos de MSBuild se pueden descargar desde http://cid-bef06dffdb192125.office.live.com/self.aspx/Code%20Samples/2010%2008%2003%20MSBuild%20Propiedades.zip

 

Saludos @ Here

El Bruno

image47dd1de4

Buenas,

como estamos en Agosto, a ver si esquivamos este tipo de chat:

- Hola Bruno, como sé que no tienes mucho trabajo, ¿te puedo hacer una pregunta?

- Hola campeón, dispara que yo esquivo como Neo

- ¿Cómo puedo hacer instalar mi TFS?, ¿se puede instalar en un Windows NT4 con 256MB de RAM?

- A ver ser mitológico sobrino de belcebú entre otras cosas, podríamos empezar por leer la guía de instalación de Team Foundation Server, ¿no?

- ¿Lo quééééé?

- La guía de instalación, criatura

- ¿Eso se compra?

- En tu mundo tan especial, ¿no existen Bing o Google no?, solo Percy Jackson. Para ahorrarte un problema, aquí van los links:

Sé que lo siguiente, es preguntar si viene en español o si se puede utilizar MySQL en lugar del “SQL Server ese”, pero para eso tengo que tomarme un par de cervecitas y después responder.

 

Saludos @ Here

El Bruno

PD: en mi 3er año de paternidad, tengo que agradecer al Valentino que ha logrado desarrollar mi paciencia, para poder sobrellevar la masividad de internet ^^

image47dd1de4

Buenas,

para cerrar una semana un tanto especial, hoy toca mostrar como crear un DataCollector personalizado, para agregar información extra al resultado de un set de pruebas de Visual Studio 2010. El gran Shai (ojo con la foto del header de su blog) explica un paso a paso detallado aquí. En el ejemplo de este post, crearé un DataCollector que agrega información muy importante al resultado de un proceso de test: el estado de mi página de Twitter @elbruno.

Para esto, me he basado en el siguiente código, que me permite descargar el contenido de una URI a un archivo temporal local, donde la función GetElBrunoTwitterInformation(), retorna la ubicación de un archivo temporal con el contenido de http://twitter.com/elbruno.

   public class TwitterInfo
    {
        public string GetElBrunoTwitterInformation()
        {
            // generate temp file
            var fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".htm");
            if (File.Exists(fileName))
                File.Delete(fileName);

            // save local file
            GetUrl(new Uri(@"http://twitter.com/elbruno"), fileName);
            return fileName;
        }


        private bool GetUrl(Uri uri, string localFileName)
        {
            var ret = false;
            var request = WebRequest.Create(uri) as HttpWebRequest;
            var response = request.GetResponse() as HttpWebResponse;
            try
            {
                // Hope GetEncoding() knows how to parse the CharacterSet
                var encoding = Encoding.GetEncoding(response.CharacterSet);
                var reader = new StreamReader(response.GetResponseStream(), encoding);
                using (var sw = new StreamWriter(localFileName, false, encoding))
                {
                    sw.Write(reader.ReadToEnd());
                    sw.Flush();
                    sw.Close();
                    ret = true;
                }
            }
            catch
            {
                ret = false;
            }
            finally
            {
                response.Close();
            }
            return ret;
        }
    }

Ahora a crear el DataCollector, para esto agregamos las siguientes referencias:

  • Microsoft.VisualStudio.QualityTools.Common
    C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.VisualStudio.QualityTools.Common.dll
  • Microsoft.VisualStudio.QualityTools.ExecutionCommon
    C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.VisualStudio.QualityTools.ExecutionCommon.dll

y heredamos de DataCollector. En mi caso particular, además he decorado la clase para indicar la URI y descripción del DataCollector.

    [DataCollectorTypeUri("datacollector://ElBruno/TwitterCollector/1.0")]
    [DataCollectorFriendlyName("El Bruno Twitter Collector")]
    public class TwitterCollector : DataCollector
    {
        private DataCollectionSink _sink;

        public override void Initialize(XmlElement configurationElement, DataCollectionEvents events, DataCollectionSink sink, DataCollectionLogger logger, DataCollectionEnvironmentContext environmentContext)
        {
            _sink = sink;
            // suscribe to test run session end
            events.SessionEnd += EventsSessionEnd;
        }

        private void EventsSessionEnd(object sender, SessionEndEventArgs e)
        {
            // add file
            var file = new TwitterInfo().GetElBrunoTwitterInformation();
            _sink.SendFileAsync(e.Context, file, string.Format(@"ElBruno Twitter Homepage -> {0}", DateTime.Now), false);
        }
    }

El punto de entrada es DataCollector.Initialize(), ya que en este punto podemos:

  • acceder a la configuración del test
  • trabajar con la colección de eventos propios de la ejecución de un test
  • trabajar con la colección de archivos relacionados con la ejecución de un test
  • acceder al contexto de ejecución del test

En este ejemplo, he creado una suscripción al evento SessionEnd(), y en el mismo agrego como un archivo adjunto al test un htm con el contenido de http://twitter.com/elbruno.

Aclaración: ya lo sé, solo en muy pocas ocasiones esto será necesario, pero bueno, es un ejemplo.

Una vez compilado el ensamblado, debemos copiar el mismo al directorio de DataCollectors de Visual Studio 2010, por lo general es:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\DataCollectors\

A partir de este momento, en la configuración de la ejecución de tests, en la sección [Data and Diagnostics]; podremos ver un nuevo adaptador llamado [El Bruno Twitter Collector]

image

Si activamos el mismo, y lanzamos la ejecución de uno o más tests, podremos ver que una vez que han pasado los mismos, en el link [Test run completed] hay información adicional agregada:

image

 

En la ventana de resultados de tests, en la sección [Collected Files], hay adjunto un archivo (con nombre de GUID) que posee el contenido de http://twitter.com/elbruno, con su descripción correspondiente:

image

 

 

 

 

Para finalizar, si accedemos a la ubicación de resultados de tests en el disco local (tengo un post pendiente al respecto), podremos ver el archivo htm generado al final de la sessión de ejecución de test:

image

 

Y claro, que placer más grande que nos da, poder abrir el htm :D

image

 

Descarga el código de ejemplo si puedes que hoy skydrive está como está en: http://cid-bef06dffdb192125.office.live.com/self.aspx/Code%20Samples/2010%2007%2030%20Custom%20DataCollector.zip

 

Saludos @ Here

El Bruno

Referencias:

image47dd1de4

Buenas,

hace un rato el amigo Alfredo me preguntó si era posible conocer las variables de entorno (environment variables) con las que estaba trabajando Visual Studio 2010. La respuesta es rápida, ya que como el panel Command Window, permite trabajar con .Net puro y duro, pues a utilizar System.Environment.GetEnvironmentVariables(). La siguiente imagen, muestra un ejemplo de esta función en ejecución en el IDE:

image

 

Pero claro, seguro que lanzaste el IDE y después de copiar y pegar el comando, te encontraste con un error como este:

image

 

 

 

¿La solución? –> Carga un proyecto que te de acceso a “lo mínimo” del IDE -> jejeje

 

Saludos @ Here

El Bruno

image47dd1de4

Buenas,

como hoy es casi viernes (es martes), me apunto un pequeño tip que uso hace tiempo, pero que nunca he posteado:

Cómo lanzar una build en TFS2008 desde la línea de comandos.

Si necesitamos lanzar builds frecuentemente en TFS2008, la opción del IDE de Visual Studio 2008, puede llegar a ser un poco tediosa. Ojo, esto si entendemos “tedioso”, a una acción que involucra los siguientes pasos:

1. Acceder al panel Team Explorer

2. Acceder al Team Project con el que deseamos trabajar (por ejemplo, TPDemo)

3. Acceder al nodo [Builds]

4. Seleccionar la Build que deseamos lanzar (por ejemplo BuildDemo)

5. Desplegar el menú contextual

6. Seleccionar la opción [Queue new Build]

7. Completar la información de la build (si es necesario).

8. Done !!!

Pues a todos estos pasos los podemos reemplazar por una única llamada desde la línea de comandos con el siguiente formato:

TFSBuild start http://TfsServer:8080 TeamProject BuildDefinition

Donde para el ejemplo anterior, podría ser algo similar a lo siguiente:

TFSBuild start http://TfsServer:8080 TPDemo BuildDemo

Esto en un bat, puede darnos muchas alegrias :D

 

Saludos @ Here

El Bruno

Referencia: http://msdn.microsoft.com/en-us/library/aa337631%28VS.90%29.aspx

Más artículos Página siguiente >