Introducción
El control de versiones de Team Foundation Sever (TFVC) cuenta con las funcionalidades más comunes usadas en la mayoría de las aplicaciones de este tipo (Ej. SourceSafe, Source Gear, CVS, Subversion, etc.) tales como controlar las diferentes versiones del código fuente, administrar usuarios y permisos asociados con el código o la creación de diferentes ramas (branches) dentro de un mismo proyecto. TFVC además introduce nuevas funcionalidades entre las que encontramos el aplazamiento de cambios pendientes del código fuente (shelving and unshelving changes), Políticas de Protección de cambios (Check-in policies) entre otras (más información MSDN).

Utilizando TFVC el usuario o administrador del proyecto se verá involucrado en varias tareas tales como la administración de espacios de trabajo (Workspaces), configuración de permisos de usuario, comprobación del estado de los ficheros (¡¡¡quien ha dejado un fichero bloqueadooo!!!), comparando las versiones de un fichero en su historial, o eliminando carpetas y archives del servidor. Algunas de estas funcionalidades solo están disponibles a través de líneas de comandos y debido a esto al final del día puedes haber escrito muchas líneas de comando para cumplimentar tus tareas. Es aquí donde entra en juego “Team Foundation Sidekicks”.

Buscando en la web una herramienta que me permitiera realizar alguna de las tareas descritas anteriormente de forma visual (sin utilizar líneas de comando), encontré este sitio en el que describía uno de sus productos (Team Foundation Sidekicks) como un conjunto de herramientas para administradores y usuarios avanzados de TFVC con una interfaz de usuario gráfica y que permitía tareas de este tipo, y lo mejor de todo es gratis y puede ser usada con fines tanto comerciales como no comerciales bajo la licencia.

Por lo que me cree un proyecto de prueba en Team Foundation Server (TFS) y comencé a evaluar las funcionalidades del producto, mas información aquí. Después de estar un rato jugando y probando todas sus interesantes funcionalidades encontré algo que me llamo la atención. Un elemento en el menú que decía “Add Sidekick…” por lo que pensé que quizás podría crear mi propio Sidekick y acoplarlo en esta herramienta.

El problema
Existen ocasiones en las que por alguna razón es necesario eliminar del control de versiones algunos archivos y carpetas debido a requerimientos de espacio en disco, o a la eliminación de proyectos que fueron creados para pruebas, etc. Esta característica solo está disponible a través de las líneas de comandos, así que dependiendo de donde estén ubicados los ficheros que quieres eliminar dentro del proyecto, puede ser que acabes escribiendo rutas (path) a ficheros lo suficientemente largas como para equivocarte varias veces, por lo que sería buenísimo poder contar con una especie de explorador de ficheros (algo así como el explorador de Windows para el sistema de directorios) que te permitiera eliminar aquellos ficheros o directorios que necesites. Así que vamos a tratar de implementar esta funcionalidad utilizando una interfaz gráfica.

Creando un control para Team Foundation Sidekick.
Lo primero que necesitaremos es descargar e instalar la herramienta “Team Foundation Sidekick” (Debes tener instalado Team Explorer 2005 o 2008 en el ordenador para utilizar esta herramienta, ver las notas de implementación). Una vez que hayamos instalado Team Explorer y Team Foundation Sidekick tendremos a nuestra disposición todo el API para extender las funcionalidades de TFVC.

Los controles de Team Foundation Sidekicks deben heredar de la clase base BaseSidekickControl y sobrescribir la propiedad pública Image, esto nos servirá para crear un elemento en el menú y otro en la barra de herramientas que nos servirá como punto de entrada para nuestro sidekick.

namespace MySidekick.Control
{
    public partial class DestroyFilesAndFoldersViewControl : BaseSidekickControl
    { 
        DestroyFilesAndFoldersController _controller = null;
        public DestroyFilesAndFoldersViewControl()
        {
            InitializeComponent();
            base.Name = "Destroy Sidekick";
        } 

        public override Image Image
        {
            get
            {
                return new Bitmap(@"c:\Test\Resources\Destroy.bmp");
            }
        }
    }
}

También es recomendable crear una clase controladora que derive de TfsController para utilizar los contextos de conexión y de seguridad que nos ofrece Team Foundation Sidekick.

Es en esta clase es donde escribiremos todo el código necesario para lograr nuestro objetivo.

namespace MySidekick.Controller
{
    public class DestroyFilesAndFoldersController : TfsController
    {
        public DestroyFilesAndFoldersController(TfsController baseController) : base(baseController)
        {
        }
    }
}

Una vez hecho esto y de regreso en nuestro control DestroyFilesAndFoldersViewControl necesitaremos sobrescribir el método Initialize el cual será llamado por la clase base cada vez que necesitemos cargar nuestro control en la aplicación y este creará una instancia de nuestra clase controladora en la cual está implementada la funcionalidad que queremos utilizar.

namespace MySidekick.Controls
{
    public partial class DestroyFilesAndFoldersViewControl : BaseSidekickControl
    { 
    DestroyFilesAndFoldersController _controller = null;

        public override Image Image
        {
            get
            {
                return new Bitmap(@"c:\Test\Resources\Destroy.bmp");
            }
        }

        public override void Initialize(TfsController controller)
        {
            this._controller = new DestroyFilesAndFoldersController(controller);
        }
    }
}

En este punto lo único que tenemos que hacer es escribir el método que realmente destruye los ficheros o carpetas en el TFVC.

Si exploramos la clase VersionControlServer dentro del ensamblado Microsoft.TeamFoundation.VersionControl.Client podremos ver un método público llamado Destroy con la siguiente firma.

public Item[] Destroy(ItemSpec itemSpec, VersionSpec versionSpec, VersionSpec stopAt, DestroyFlags flags);

Sin embargo en la referencia SDK para Team Foundation Server, no existe ninguna información acerca del método Destroy.

Además podemos intentar obtener información acerca de los parámetros que se le pasan a este método como por ejemplo ItemSpec y todo lo que encontraremos es la frase “Esta API forma parte de la infraestructura de Team Foundation Server y no está pensada para que la uses desde tu código.”

Toda esta falta de información tiene sentido porque eliminar ficheros permanentemente del TFVC es una operación muy peligrosa y para realizarla necesitamos evitar toda la ambigüedad posible sobre los ficheros que queremos eliminar. (Por supuesto también debemos tener privilegios administrativos en el proyecto). Particularmente creo que es una buena práctica “Destruir” aquellos ficheros que hayan sido borrados previamente. (En TFVC el borrado de un fichero consiste solamente en marcar al fichero como borrado, además existe la opción de recuperarlo “UnDelete”).

De los tres constructores que tiene la clase ItemSpec, de la cual necesitamos pasar una instancia al método Destroy, utilizaremos el siguiente:

public ItemSpec(string item, RecursionType recursionType, int deletionId);

Donde item es la ruta completa al fichero o carpeta que quieres eliminar en el servidor RecursionType es el tipo de Recursividad y deletionId es un entero que se le asigna un fichero (o a un conjunto de ficheros y carpetas) cuando es marcado como borrado.

Una vez que podemos crear una instancia de la clase ItemSpec

public ItemSpec GetItemsSpec(string path, int deletionID)
{
    return new ItemSpec( path, RecursionType.Full, deletionID);
}

Solo nos queda llamar al método destroy utilizando la clase base y completar todos sus parámetros.

public void Destroy(string path, int deletionID)
{
    base.VersionControl.Destroy(GetItemsSpec(path, deletionID), VersionSpec.Latest, null, DestroyFlags.None);           
}

Para mas información acerca del método destroy consulte MSDN

Luego solo necesitamos compilar el control para generar la DLL que cargaremos usando el ítem de menú "Add Sidekick.."

y como pueden ver en la siguiente imagen, aparecerá un nuevo elemento en el menú y otro en la barra de Herramientas.

haciendo clic en uno de ellos veremos la pantalla siguiente, y ya solo nos queda buscar el o los ficheros que queremos eliminar y pulsar la tecla Delete en el teclado.

Y esto es todo espero que este artículo te sea de utilidad. Puedes bajarte el código fuente desde aquí


 |