sábado, marzo 29, 2014

PlasticSCM: ¡Houston, tenemos problemas!

[Última actualización: 12/11/2017 - Registro de la clase visualfoxpro.application.9]
Por: Fernando D. Bozzo

...Y es normal, todo no puede salir siempre bien o tal cual se pone en los tutoriales, en los artículos o en los videos. Además, quienes los hacemos, intentamos de que salga todo perfecto, haciendo pruebas previamente y equivocándonos "antes" de publicar algo, pero el problema es que al no mostrarse los posibles fallos, entonces no se puede aprender de ellos, y este artículo intenta llenar un poco ese hueco, con problemas comunes y cómo resolverlos.



1. Quiero cancelar el merge que estoy haciendo, ¡pero no sé cómo salir!


Este problema tiene 2 partes:

a) Mientras se está haciendo el merge

Cuando se hace merge de muchos archivos y no se quiere estar cancelando uno por uno 200 veces, se puede cancelar todo el proceso desde la ventana principal, para lo que es importante no intentar cerrar la ventana actual de merge (que pueden haber muchas, una tras otra), sino conmutarse a la ventana principal, pulsar el botón Cancelar y recién ahí se puede volver a la ventana de merge que quedó abierta y cancelar.

Luego se debe comprobar si hay Cambios Pendientes (no olvidar refrescar la vista) y deshacer todo, si hubiera algo.


b) Una vez hecho el merge

Si hay Cambios Pendientes (no olvidar refrescar la vista) y deshacer todo, si hubiera algo.



2. ¡No puedo hacer un Merge, sale una pantalla rara!


Ok, estamos haciendo un Merge y nos sale esto:


¿Qué pasó, si lo elegido era un archivo de texto, no un binario?

Pueden haber pasado dos cosas:

1.  Que el archivo efectivamente sea un binario:


Y si es un binario, entonces no hay otra opción que elegir quedarse con el Origen (el archivo desde donde se hace el Merge), con la Base (de donde partieron origen y Destino) o con el Destino (el archivo del workspace). Pero esto solo debe hacerse si no se trabaja con VFP o si no se usan las herramientas de FoxPro para Plastic.

También puede haber pasado que se haya configurado mal la herramienta de Merge de FoxPro en Plastic, ya que esa configuración sirve para que esta pantalla no aparezca. Por las dudas, la configuración, que está en el README.txt, es esta:


CONFIGURACIÓN DE MERGE EN PLASTICSCM:
------------------------------------------------------------------------

  • Clickear en el icono de Preferencias de PlasticSCM
  • Seleccionar "Herramientas Merge" y "agregar" esto:
    • Herramienta Merge externa: "<path-a-las-herramientas>\foxpro_plasticscm_dm.exe" "'PRESERVE_WS' '@sourcefile'"
    • Pattern: .pjx;.pjt;.vcx;.vct;.scx;.sct;.frx;.frt;.lbx;.lbt;.mnx;.mnt;.dbf;.fpt;.cdx;.dbc;.dcx;.dct     (¡usar misúsculas!)
  • Clickear OK
  • Mover la extension agregada al inicio de la lista, para priorizarla


2.  Que no esté reconociendo el archivo como texto:


En ese caso se debe cancelar el merge cerrando la ventana de la imagen anterior, cerrar la solapa e merge, Deshacer los cambios pendientes (ver el tema anterior: "Quiero cancelar el merge que estoy haciendo, ¡pero no sé cómo salir!") y cambiar el tipo de archivo a texto en la vista de Items:


Luego de solucionar esto, podremos volver a reintentar el Merge, y ahí sí que ya debería salir la ventana de merge normal, y no olvidar "saltear" los binarios que queden, como ya expliqué en el artículo "PlasticSCM: ¿Qué es el Merge".

Para más detalle, también está este video corto:





3. ¡No puedo hacer un Diff, sale un error!


Si sale esta pantalla:


Es porque Plastic no reconoció bien un archivo de texto y lo toma como tipo binario, o porque elegimos un archivo para el que no hay conversor disponible, o porque es un archivo binario normal.
Trabajando con las herramientas de FoxPro 9 esto puede pasar en 3 casos:

1.  Plastic no reconció bien un archivo de texto:


Este es el mismo caso que comenté en el punto (2) del problema anterior con el Merge, y tiene la misma solución.

2.  Elegimos un archivo para el que no hay conversor disponible:


Si el archivo es un pjx, vcx, scx, frx, lbx, mnx, dbf o dbc, el problema es que se configuró mal, o no se configuró, la opción de DIFF en las opciones de Plastic. El README.txt indica como hacerlo:

CONFIGURACIÓN DE DIFF EN PLASTICSCM:
------------------------------------------------------------------------

  • Clickear en el icono de Preferencias de PlasticSCM
  • Seleccionar "Herramientas Diff" y "agregar" esto:
    • Herramienta Diff externa: "<path-a-las-herramientas>\foxpro_plasticscm_dm.exe" "'DIFF' '@sourcefile' '@destinationfile' '@sourcesymbolic' '@destinationsymbolic'"
    • Pattern: .pjx;.vcx;.scx;.frx;.lbx;.mnx;.dbf;.dbc     (¡usar misúsculas!)
  • Clickear OK
  • Mover la extension agregada al inicio de la lista, para priorizarla

3.  Elegimos un binario normal:


En este caso hemos querido hacer Diff sobre un EXE o SCT o VCT o cualquier otro binario no soportado.




4. ¡No puedo borrar el workspace!


Cuando hay una sola solapa, será el workspace activo, y no se podrá eliminar:


Para poder borrarlo necesitamos tener un segundo workspace, que podemos crear apuntando a un directorio cualquiera (ya que no lo usaremos) o aprovechar y crear otro repo que necesitemos, lo que creará una segunda solapa que deberemos elegir.

Ahora sí, si en el panel izquierdo seleccionamos "Workspaces", podremos eliminar el workspace anterior.

Nota: Eliminar el workspace solo borra el "alias" del repositorio, no borra el repositorio ni su contenido. Esto permite poder crear un workspace distinto con un nuevo directorio para el mismo repositorio.



5. ¡Me equivoqué al crear el workspace y lo asocié a un directorio equivocado!

En este caso debemos borrar el workspace (no el repositorio!) y volverlo a crear. Si al hacerlo nos da un error como este:


Es porque es el único workspace y está activo. Ver el punto anterior "¡No puedo borrar el workspace!"




6. Error al intentar abrir el cliente Plastic (1)


Si aparece un mensaje de error como este:


Entonces hicieron mal el paso 5 o el 14 de la guía de Instalación de PlasticSCM paso a paso

Si están queriendo usar otro modo de autenticación porque lo van a usar, por ejemplo, en la oficina con autenticación de Directorio Activo u otro, entonces deben verificar que la configuración del cliente y la del servidor son iguales.

Para comprobarlo, deben ir al menú Programas / PlasticSCM y a continuación:

> Para el cliente, abren la opción: Client Tools / Client Configuration Wizard

> Para el servidor, abren la opción: Server Tools / Server Configuration Wizard




7. Error al intentar abrir el cliente Plastic (2)


Si ocurre el siguiente error, es muy probable que el servicio "Plastic Server 5" no esté levantado:


Para solucionarlo, lo primero que se puede hacer es reiniciar la PC si no se hizo al instalar Plastic, y si no también se puede abrir la consola de Servicios, verificar si está levantado, y si no lo está, iniciarlo:


Esta es la configuración que tengo por defecto para este servicio:









8. ¿Cómo se cambia el idioma?

Cuando se instala un programa, a veces no miramos bien las opciones de la pantalla y le damos "aceptar", "aceptar", "aceptar"... hasta que nos damos cuenta de que se nos pasó algo.

Plastic por suerte viene con 2 programas de configuración, uno para el cliente y otro para el servidor, que permiten configurar el idioma, el servidor, el puerto de conexión, el modo de autenticación, etc.

Para reconfigurar el cliente o el servidor, deben ir al menú Programas / PlasticSCM y a continuación:

> Para el cliente, abren la opción: Client Tools / Client Configuration Wizard

> Para el servidor, abren la opción: Server Tools / Server Configuration Wizard

En ambos casos, vayan avanzando en las pantallas hasta encontrar lo que buscan.

Recuerden que si acaban de instalar el programa, es probable que deban reiniciar la PC o probablemente les de errores al intentar ejecutar Plastic.



9. ¡No puedo descargar Plastic, da un error la página!


Aquí hay un enlace a una versión de Plastic actualizada a agosto 2014 que temporalmente va a servir (versión evaluación 30 días y 5 desarrolladores), así que luego hay que bajarse el archivo de licencia gratuita anual para 15 desarrolladores antes de que caduque:
PlasticSCM-5.0.44.596-windows-installer.exe.7z



10. Hice un checkin erróneo en un archivo, ¿cómo lo arreglo?



11. ¡Borré el directorio del workspace sin querer y se perdió todo! ¿Qué hago?


Lo que has borrado es solamente los archivos del directorio, no lo que tienen guardado en la Base de Datos, por lo que hay 2 soluciones, una rápida y otra algo menos rápida:

  • Opción 1: Si no has borrado el directorio oculto ".plastic" del directorio del workspace, entonces puedes ir al Explorador de Ramas, buscar el último changeset y ubicar la casa ahi (click-derecho -> Apuntar workspace a este changeset). Este último paso descargará de la BDD de Plastic todos los archivos en sus ubicaciones.
  • Opción 2: Si has borrado el directorio oculto ".plastic", entonces debes borrar el workspace de Plastic desde el panel izquierdo (Workspaces), volver a crearlo, asociándolo al mismo directorio (u otro), buscar el último changeset y ubicar la casa ahi (click-derecho -> Apuntar workspace a este changeset). Este último paso descargará de la BDD de Plastic todos los archivos en sus ubicaciones.




12. Quiero ver/comparar el contenido de un archivo tx2 (texto) y dice que es binario!



Cuando esto ocurre, es porque la información del tipo de archivo se perdió en algún momento, o directamente no se indicó en el archivo filetypes.conf del directorio raíz del workspace.


Para solucionarlo, vamos a la vista de Items, seleccionamos los archivos de texto que figuran como binarios, hacemos click-derecho sobre alguno de ellos y elegimos Camiar tipo de revisión -> Texto, y listo, problema resuelto.


13. No me reconoce la licencia plastic.lic

El archivo de licencia plasticd.lic que reciban, se debe copiar en el subdirectorio server dentro del directorio de instalación de Plastic (hay un directorio client y uno server), pero antes de copiarlo deben "bajar" el servicio de Plastic ("Plastic Server 5"), luego copiar al archivo y luego volver a levantar el servicio, para que reconozca la licencia.



14. No se puede crear el objeto "visualfoxpro.application.9"

Esto pasa cuando el IDE de Visual FoxPro (vfp9.exe) no está registrado en el registro de Windows. Aunque se puede usar manuelmante el IDE sin registrarlo, el no tenerlo regitrado impide poder usarlo como clase de automatización.
El arreglo es simple: Se abre una ventana de comandos como admin, y se pone esto, adaptando la ruta donde realmente se encuentre VFP9.exe:

"c:\program files (x86)\microsoft visual foxpro 9\vfp9.exe" /regserver



15. ¡No puedo borrar un changeset! ¿qué hago?


Aunque el mensaje es bastante explícito y "técnicamente" correcto, vamos a comentarlo por partes, ya que no siempre es fácil ni evidente determinar el motivo que impide borrarlo.

Etiquetas: Eso es lo más fácil de ver, porque visualmente se puede comprobar si el changeset que se quiere borrar tiene etiquetas o no (pueden haber varias etiquetas en un mismo changeset). Si las tiene, las mismas se deben borrar antes de poder borrar el changeset.

Ramas: PlasticSCM mantiene y comprueba la integridad de los changesets, por lo que si una rama depende de un changeset, el mismo no se podrá borrar hasta que se eliminen las ramas que dependen de él. Esta solución (borrar ramas) es un tanto brusca y debe usarse como último recurso siempre que realmente sea muy importante borrar un changeset y todas sus ramas dependientes. Normalmente esto solo se hace cuando se realizan pruebas con la herramienta de Control de Código, donde se crean ramas y changesets de prueba para luego eliminarlos. Al igual que las etiquetas, ver las ramas dependientes es visualmente comprobable.

Shelves: Esto ya es más complejo, porque los shelves se crean a partir de un changeset bajo la idea de poder proteger los cambios temporalmente para poder continuar con otra cosa en otra rama y luego volver a aplicarlos en el mismo sitio cuando se vuelva a trabajar en la misma rama. El problema radica en que por un lado los shelves no son visuales y por el otro en que la información del shelve no indica en qué changeset se hizo, por lo que visualmente es imposible verlo.

Una solución (algo salvaje) podría ser borrar todos los shelves guardados, y con eso se solucionaría el problema, pero hay otra solución mucho más moderada, que consiste en preguntar a Plastic qué shelves se basan en el changeset que se quiere borrar.

Por ejemplo, si se quisiera saber qué shelves se basan en el cs:4236, la consulta desde la ventana de comandos sería esta:

cm find shelves where parent = '4236' --format="{parent} # {owner} # {guid} # {date} # {comment}"

Esto listará todos los shelves que se crearon desde ese changeset.
Para evitar tener que recurrir a esto y poder resolverlo visualmente desde la vista de Shelves, es muy recomendable que antes de crear un shelve se ponga como inicio de comentario en la vista de cambios pendientes el changeset del que parte. Por ejemplo: "cs:4236 - Arreglo bug cálculo precio"



Observaciones:


De algunos de los errores comentados, también puede deducirse que a veces vamos tan a las apuradas que no prestamos atención al instalar o configurar algo, lo que luego nos trae un sinfín de problemas que en muchos casos se podían haber evitado. Es mejor dedicar el tiempo necesario a configurar bien y sobre todo a entender cómo funciona lo que estamos configurando, y no quedarse solo con los paso-a-paso, para no perder tiempo luego y dominar mejor nuestras herramientas.


Este contenido lo iré actualizando con otros problemas comunes que me vayan surgiendo o que me sugieran.


Hasta la próxima!

martes, marzo 25, 2014

Control de Código Fuente: Terminología común que hay que conocer

Por: Fernando D. Bozzo

Esta entrada fue motivada por las inquietudes de algunos de ustedes durante las pruebas que hicimos en marzo 2014, y que me recordaron que en este tema hay términos de uso común que el que recién comienza no domina (obviamente), y por eso quiero hacer una breve reseña de los términos más usados y de lo que significan, y que iré completando a medida que me hagan nuevas preguntas sobre "¿qué significa tal término?".

Para facilitar las cosas, pondré alguna imagen cuando sea necesario y relacionaré los términos con los de FoxPro cuando pueda aplicarse.



Workspace


El workspace, que se traduce como "espacio de trabajo", es un alias que se le asigna a un directorio. Así como en FoxPro podemos usar un alias para usar una tabla bajo otro nombre, donde el alias "clientes" apunta a "c:\un-directorio\clientes.dbf", el workspace es eso mismo, pero aplicado a un directorio, de modo que si creamos un workspace llamado "dvcs_vfp9" para referirnos al directorio "c:\desa\tests\dvcs_vfp9", realmente estamos creando ese alias para que sea más fácil de manejar en Plastic, ya que es más cómodo mostrar un alias significativo en una de las solapas superiores que todo el nombre de un directorio, lo que dejaría poco lugar para las solapas de otros workspaces. De modo que hablar de "workspace" y de "directorio de trabajo" es lo mismo.

Vista del workspace "vfp_test_grupo" y el directorio que representa en Plastic





Checkin y Checkout



Check-in significa algo así como "verificar o realizar entrada", que es lo opuesto a Check-out, que es "verificar o realizar salida". Tanto la entrada como la salida se refiere a archivos, entrada o salida de archivos, o lo que es lo mismo, enviar/subir (checkin) o recuperar/bajar (checkout) archivos al servidor del Control de Código fuente.

El paralelismo con FoxPro sería el buffering de tablas, donde uno agrega, elimina o modifica registros en vez de archivos, en cualquier momento se pueden comprobar qué registros han cambiado con GetFldState (en Plastic se revisa la vista de Cambios Pendientes que actúa sobre los archivos del workspace) y luego se confirma la grabación de los mismos con TableUpdate (equivale al Check-in) o bien se pueden deshacer todos los cambios usando TableRevert (en Plastic equivale a "Deshacer Cambios"). El Checkout en Plastic solo es un estado que indica si un archivo está marcado para modificar o no. En otros SCM el checkout es la operación que se baja la última versión de un archivo al workspace, pero en Plastic esto se hace seleccionando un workspace por su solapa, o eligiendo "Actualizar workspace" en la vista de Items, o con el comando cm getfile en una ventana de comandos DOS.



Hacer un "Diff"


Versión corta: Hacer un Diff es buscar y mostrar las "Diferencias" (Differences en Inglés) entre dos archivos. Se usa para saber qué líneas o bloques de código se han cambiado entre dos versiones de un programa, por ejemplo trabajamos un rato en un programa, donde vamos guardando los cambios cada tanto (con checkin) y luego queremos ver los últimos cambios visualmente (a diferencia de tener que recordarlos)
Para la versión larga aplicada a Plastic, leer este artículo.



Hacer un "Merge"


Versión corta: Hacer un Merge es realizar la mezcla de las modificaciones hechas por separado a un mismo programa, para volver a tener un solo programa que tenga todos los cambios. Si yo tengo un programa copiado en dos directorios, a una copia le agrego un método "A" y a la otra copia le agrego un método "B", el merge sería tomar el programa original y agregarle los métodos "A" y "B".
Para la versión larga aplicada a Plastic, leer este artículo.



Cherry Pick


Versión corta: Es un tipo de Merge que permite seleccionar changesets o ramas específicas, sin incluir el resto de archivos heredados.
Para la versión larga aplicada a Plastic, leer este artículo.



Rama


Una rama es una línea paralela de trabajo, una copia completa del workspace (o directorio del proyecto) en la cuál poder trabajar sabiendo que a la copia original no la afectamos en lo más mínimo.
Una rama está compuesta por uno o más changesets.
En la práctica es como hacerse una copia del sistema en otro directorio y trabajar en él para, al terminar, pasar los cambios al directorio original.

Para la versión larga aplicada a Plastic, leer este artículo.

Imagen de la rama v1.19.17 de FoxBin2Prg con 4 changesets y una etiqueta de versión




Repositorio


En Plastic un repositorio es una base de datos (archivos de SQL Server, MySQL, etc) que contienen un grupo de tablas y esquemas que contendrán los archivos y relaciones que se hagan entre ellos.

Los archivos contenidos serán los que nosotros "subamos" al control de código, mediante las opciones "Agregar al control de código" o mediante los "checkin", y que también se pueden marcar opcionalmente como modificables con un checkout.

Normalmente se usa un repositorio por cada proyecto.



Changeset


"Changeset" significa "juego de cambios" o "conjunto de cambios", y se usa para identificar las operaciones de agregado, borrado o modificación hechos a uno o varios archivos que luego se guardan con checkin.
En Plastic se puede ver el contenido de las operaciones de un changeset haciendo doble click sobre uno de ellos.

Ejemplo de las operaciones contenidas en un changeset (archivos Movidos, Borrados y Añadidos):




Lista de archivos ignorados (ignore.conf)


Los archivos ignorados son aquellos archivos Privados que no nos interesa ver en la vista de Items de Plastic para mantenerla más despejada y poder enfocarnos en los archivos que sí nos interesa controlar. Es un filtro, un archivo de texto que contiene una lista de archivos o especificaciones de archivo donde generalmente se suelen anotar los .tmp (temporales), .fxp (compilados), .bak (backups), y demás archivos que no queramos ver.

Ejemplo de parte de un ignore.conf:

*.FXP
*.LNK
!/_iniciar aqui.lnk
*.SCC
*.TMP
*.BAK
*.ZIP
*.7Z

foxuser.dbf
*/FXUResults.*




Detalle de la especificación: 


En el ejemplo anterior tenemos los 4 tipos de ignore soportados, que se interpretan como un filtro con la función LIKE() en FoxPro:
  • La extensión sola (ej: *.FXP): Se ignoran todos los .fxp dentro del workspace, incluyendo subdirectorios
  • Un nombre de archivo (ej: foxuser.dbf): Se ignora el archivo indicado dentro del workspace, incluyendo subdirectorios
  • Un directorio con especificación de archivo (ej: */FXUResults.*): Se ignora el archivo dentro del directorio indicado. La raíz del workspace siempre es "/", que como se ve no es la contrabarra de Windows, sino el signo dividido que se usa en Linux y Mac para los directorios, ya que Plastic es multiplataforma
  • Una excepción a la regla (ej: !/_iniciar aqui.lnk): Este tipo realmente actúa como "anti-filtro" y es muy útil en los casos en los que tenemos definido un filtro, pero no queremos que se aplique en un directorio en particular. En el ejemplo dado se ignoran todos los accesos directos (*.lnk), pero se exceptúa de esta regla a un archivo en particular que está en la raíz y que se usa para abrir una sesión de FoxPro


Lista de archivos cloaked (cloaked.conf):


Los archivos cloaked son aquellos archivos controlados por Plastic, donde no nos interesa que se vuelvan a descargar o actualizar desde la base de datos.
Su uso habitual es para evitar que algunos archivos pesados (como un DBF con datos o un binario) se descarguen cada vez que actualizamos el workspace o nos cambiamos de changeset.
Se usa mucho en la industria del videojuego, donde ciertos mapas de textura pueden tener cientos de MB que tardarían un buen rato en descargarse y que al programador no le aporta nada para sus pruebas.

En FoxPro, un buen caso de uso podría ser el archivo "/_iniciar aqui.lnk" del ejemplo anterior, donde por un lado nos interesa controlarlo con Plastic para que todos los programadores se lo puedan descargar y que luego cada uno lo pueda personalizar según dónde tenga instalado FoxPro, poniéndolo en el cloaked.conf para que no se le vuelva a descargar y se pierda su configuración particular.

La especificación de archivos es la misma que para los ignorados.



Lista de cambios ocultos (hidden_changes.conf):


Los "cambios ocultos", como podría llegar a deducirse, son los archivos controlados por Plastic que no queremos ver en la vista de Cambios Pendientes aunque hayan sido modificados.
Un ejemplo podría un archivo LOG que se protegió inicialmente vacío, pero que suele cambiar frecuentemente y cuyo contenido no nos interesa que se guarde en la base de datos.

La especificación de archivos es la misma que para los ignorados.




Nivelar una rama


Nivelar una rama significa actualizarla con el contenido más actualizado de otra rama, y se hace tomando el contenido de otra rama (origen) y haciendo un merge sobre la rama a nivelar (destino).

Para nivelar una rama se debe estar ubicado sobre ella, en el último changeset más actualizado (en Plastic es donde se debe ubicar la casa)

Para la versión larga aplicada a Plastic, leer este artículo.



Si creen que faltan términos, me comentan y los voy agregando.


Saludos!



Nueva versión v2.4.12 de las herramientas FoxPro 9 para PlasticSCM (contiene FoxBin2Prg v1.19.18)

Por: Fernando D. Bozzo

Está liberada la versión v2.4.12 de las herramientas Visual FoxPro 9 para PlasticSCM, con los siguientes cambios:

- Actualizada la versión de FoxBin2Prg (solo el EXE) a la versión v1.19.18


Estas herramientas son un grupo de scripts vbs y programas Visual FoxPro 9 que se configuran dentro de PlasticSCM para poder invocar a FoxBin2Prg (incluye solo el EXE) desde dentro de la interfaz de Plastic.

El README.txt explica como se configura en Inglés y Español.

Nota: Los fuentes de FoxBin2Prg están en CodePlex, en el link indicado arriba en la versión.


Como actualizar las existentes:
Con descargarlas y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link de descarga:
https://github.com/fdbozzo/foxpro_plastic_diff_merge


Saludos!

Nueva versión v1.19.18 de FoxBin2Prg (arreglos)

Por: Fernando D. Bozzo

Está liberada la versión v.1.19.18 de FoxBin2Prg con los siguientes cambios:

  • Arreglo bug scx/scx: Los controles imagen con imagenes estrechadas, se redimensionan a su tamaño original (Arturo Ramos). Si, por ejemplo, se usa un control imagen con una imagen de 32x32 pixels y se redimensiona a 16x16, al regenerar el binario se pierde la nueva dimensión y se restablece a la original. Regenerando el binario desde el vc2/sc2 existente se soluciona el problema.
  • Arreglo bug vcx/scx: Los comentarios a nivel de librería no se mantienen (Ryan Harris). Si se usan comentarios a nivel de librería (hasta donde sé, solo desde el Class Browser se pueden modificar), estos no se exportan al vc2/sc2 y por lo tanto tampoco al binario al regenerarlo. Ya se exportan estos comentarios

Como actualizar el FoxBin2Prg existente:
Con descargar el zip y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link  de descarga:
https://vfpx.codeplex.com/releases/view/116407


 Saludos!

martes, marzo 18, 2014

PlasticSCM: ¿Qué es el Merge?

27/09/2014 - Actualizadas algunas partes de "Qué son los conflictos de un merge"
16/09/2014 - Actualizado con explicación de "Qué son los conflictos de un merge"
02/04/2014 - Actualizado con explicación de la opción "Proteger los cambios a otra rama..."

Por: Fernando D. Bozzo

El Merge es la operación que permite "mezclar" el código correspondiente a dos modificaciones simultáneas hechas en paralelo a un mismo programa.

Para quienes vienen de usar SourceSafe con FoxPro, esto es algo casi desconocido, porque con SourceSafe se usaba el scctext.prg que venía de serie y que sólo permitía hacer Diff. Algunos más aventurados puede que hayan intentado usar TwoFox para generar vistas XML de las clases e intentar hacer un merge manual, pero quienes lo hayan usado sabrán el cuidado que había que tener con no tocar ningún tag XML que nada tenía que ver con la programación y que dificultaba bastante entender lo que se estaba tocando.

La vida con SourceSafe era: o toco yo, o toca él, pero los dos no! La única excepción eran los PRG, que al ser texto sí que permitían más libertad, pero para todo lo demás, los checkout eran exclusivos, lo que significa que si un desarrollador bloqueaba una librería, nadie más podía modificarla hasta que ese desarrollador finalizara sus cambios, ¡y qué problemas se generaban si se enfermaba o se iba de vacaciones y la dejaba así! Claro que siempre se podía recurrir al truco de quitar el atributo de read only del archivo y modificarlo, pero subir los cambios al proyecto era imposible, y esto a muchos proyectos los bloqueaba literalmente, o como mínimo los retrasaba.


Volviendo al presente, las cosas cambiaron en FoxPro, y ahora con FoxBin2Prg un mismo programa, como clases, forms, menús, etc, puede ser modificado por varios desarrolladores de forma simultánea, cada uno en su equipo, y al momento de subir esas modificaciones al control de código se puede hacer el merge, en algunos casos de forma automática (para el primero en llegar: ¡siempre es automático!:) y en otros casos de forma manual.


[27/09/2014 - 16/09/2014 - Actualizado >>]

¿Qué son los conflictos de un Merge?


Cuando se hacen modificaciones sobre un mismo componente pero en distintas ramas, al tener que mezclar los cambios es probable que haya que resolver (seleccionar/mezclar) las diferencias entre 2 modificaciones realizadas al mismo form, clase, etc, de forma que tanto los cambios de una rama como de la otra queden incluidos.

Las ramas a mezclar pueden ser, por ejemplo, distintas características hechas por uno o más desarrolladores trabajando en paralelo, como una rama para cambiar el aspecto visual y otra rama para cambiar la funcionalidad de un botón de comando, lo que permite que al final se pueda seleccionar la característica o funcionalidad que se quiere incorporar individualmente y mezclarlas para obtener el resultado completo final.

Al trabajar en funcionalidades en ramas paralelas, es probable que se modifique algo en común, como una propiedad o un método, lo que provocará un conflicto al hacer el merge, que podrá ser automático o manual dependiendo de la calidad del algoritmo de la herramienta y de las características del código (si está bien estructurado, encapsulado y normalizado, será más fácil)

La idea de generar código estilo PRG con FoxBin2Prg, es justamente para que a la hora de hacer un merge sea casi tán fácil como hacerlo con un PRG de verdad, y dado que conocemos el lenguaje, ver el código de esta forma nos facilita la tarea lo más posible, ya que no hay que lidiar con códigos o símbolos extraños, sino sólo con el PRG y con los metadatos que se muestran como comentarios, donde suele ser muy poco lo que debe hacerse.

Obviamente, es necesario entender qué hace el código antes de realizar esta operación, y en eso ayuda bastante usar la nomenclatura de objetos y variables que dan una idea conceptual de para qué sirve cada cosa y qué tipo de dato maneja.
[<<]

Para los que les toque hacerlo de forma manual, los SCM traen herramientas para realizar la tarea, que suele mostrar las dos versiones del programa a unificar en dos paneles izquierdo-derecho. En la siguiente imagen se puede ver un ejemplo de WinMerge, un programa para Windows gratuito que permite ver diferencias entre archivos:



Este tipo de vista es muy útil cuando comparamos dos momentos de la historia del mismo archivo, como la versión de ayer y las modificaciones de hoy, pero no sirve cuando se quieren comparar 3 archivos, donde uno es la base, o sea, de donde partieron los otros dos archivos, el segundo es el mismo archivo base, pero modificado por un desarrollador y el tercero es el mismo archivo base, pero modificado por otro desarrollador.

En esta situación se requiere un visualizador de 3 vías, que muestre la base y los 2 cambios, y el programa que incorpora Plastic para esta tarea es increíble:


En la imagen puede verse en el panel izquierdo (Source, u Origen) los cambios que hizo Dev-2, que agregó Los métodos pagCalculos.Activate y cmdCalcular.Click (abajo se ve el nombre entero), pero resulta que mientras él estaba programando este cambio, Dev-1 terminó el suyo antes y lo mergeó primero (panel derecho, que es Destination o Destino) donde se ve que agregó en el mismo form el método pagDatos.Activate, seguramente con un merge automático en el que no tuvo que hacer nada.

En el panel central se ve el código original (Base) antes de que ambos hicieran sus cambios, que si bien en este caso no muestra cambios en sí mismo, cuando los muestra lo hace coloreado en amarillo.


En la cabecera de los tres paneles, los títulos coloreados Source, Base y Destination, además son selectores de cambios:



donde al clickearlos sus cambios se activan o desactivan en el panel inferior que muestra el resultado. En este caso están habilitados los cambios de ambos desarrolladores en el panel izquierdo de Dev-2 y en el derecho de Dev-1, por lo que aquí se muestra cómo quedaría la mezcla de los mismos:


Algo que también se puede ver, aunque no resulte evidente, es que esta mezcla se muestra bien y con lógica coherente porque la nomenclatura usada le permite a los algoritmos internos de la herramienta diferenciar ambos cambios y gracias a eso no es necesario modificar nada a mano.

Esto último lo comento porque puede darse el caso de que, incluso con una buena nomenclatura, dada la complejidad de los cambios puedan presentarse varias diferencias que puedan no ser coherentes para quien las esté mirando, y que requieran modificar o mover manualmente líneas o bloques de código para terminar de ajustar el merge, que también consiste en eso. Este panel inferior permite hacer dichas modificaciones manuales.

Por ejemplo, uno de los casos que puede requerir modificación manual, es cuando se trabaja con un pageframe y mientras otro desarrollador agrega una página y hace checkin, nosotros modificamos algo en la actual y hacemos checkin. Como nosotros teníamos una página de menos, podría ser necesario actualizar el PageCount manualmente.
Quice hacer esta prueba para hacerles una captura, pero resulta que Plastic me hizo este cambio de forma automática y me dejó sin nada que hacer ;-)

Igualmente hago la captura para que lo vean: La zona horizontal del medio es donde está el PageCount, el panel izquierdo tiene mis cambios, que en esta parte del código no tengo, en el medio está el origen del que partí y donde se vé que había 2 páginas, y el de la derecha es el destino, o sea, donde estoy intentando hacer el merge, y automáticamente desactivó los cambios 1 (Origen) y 2 (Base) y seleccionó el del panel 3 (Destino), además se puede observar en la parte superior izquierda el título:

"Tipo de conflicto: Automático. No es necesaria la intervención del usuario"... =D


También puede verse en la cabecera, que de los 10 cambios detectados, solo 1 no es automático!, o sea que los otros 9 los resolvió automáticamente por los algoritmos internos, y yo debo resolver el restante, que en este caso es este:


Observen que el selector de cambios (izquierda) y el selector de cambios no automáticos (derecha) tienen botones de navegación independientes, lo que permite navegar por todos los cambios o solo por los cambios no automáticos (1 en este caso). Revisar todos los cambios es buena idea, aunque sea para asegurarse de que la parte automática fue bien resuelta.

Solo para que vean como resolví este cambio manual, desactivé los cambios del lado izquierdo, ya que pueden verse que un poco más arriba (imagen de abajo), aunque en este caso daba igual, porque con el lado izquierdo activo ya los marcaba tachados antes, lo que significa que no se iban a incluir esas líneas, pero que igualmente requería nuestro visto bueno.

El caso anterior se podía resolver de dos formas:
  1. Desmarcando el Origen y dejando solamente la Base y el Destino (fue como lo hice)
  2. Eligiendo el botón superior que en la captura anterior decía "Marcar como resuelto", ya que las líneas tachadas iban a excluirse de todas formas
Nota: Es importante comprobar siempre todos los cambios, y si la activación o desactivación de los paneles superiores no ofrece el resultado esperado, siempre se puede recurrir al 4 panel (el inferior, de resultado) donde se puede modificar manualmente.


Así quedó la resolución del conflicto anterior, donde desmarqué el origen:


Finalmente, se guardan los cambios de este merge con el botón superior izquierdo, lo que cerrará esta ventana y puede que muestre otros merges para hacer.

Hay 3 cosas importantes que se deben conocer y recordar en esta etapa:

  1. Que si se necesita dejar esto para luego, se puede cerrar la ventana de merge "sin guardar cambios". Si hubiera muchos archivos por resolver, al cerrar la ventana se puede ver brevemente el botón "Cancelar" en la principal, al que hay que darle rápido antes de que aparezca una nueva ventana de merge. Parece un juego, pero es algo que deberían mejorar en la interfaz :D
  2. Que una vez guardados los cambios del merge, quedarán todavía los binarios de FoxPro, los cuales se deben seleccionar e ignorar, ya que luego deberán regenerarse en la siguiente ventana de Cambios Pendientes, ya que el merge en Plastic tiene 2 etapas: Procesar Merge, donde se resuelven los conflictos, y Regeneración de binarios y Checkin en la ventana de Cambios Pendientes.
  3. Que una vez se esté en la ventana de Cambios Pendientes, se debe recordar que por haber hecho un Merge con las versiones texto ¡los binarios que hay allí no sirven y hay que regenerarlos!

Comento un poco más estas opciones, ya que cuando hagan merge será vuestro día a día.

En el ejemplo anterior yo cancelé el merge porque solo quería mostrarles la pantalla, así que "cerré sin guardar cambios" (o sea, hice el paso 1)

El paso 2 implica seleccionar todos los binarios que se muestran en esta ventana de Merge y descartarlos, lo que significa dejar los que ya existen en el workspace (también llamado Destino), ya que han quedado desactualizados porque los cambios reales del Merge los hicimos en las versiones texto, como vemos en la siguiente imagen:


Nota: Si hubiera confirmado los cambios del merge, esta ventana no mostaría ahora las versiones de texto de los archivos, ya que hubieran pasado a la ventana de Cambios Pendientes.

El paso 3 ya se realiza en la ventana de Cambios Pendientes, pero a diferencia de lo que venimos haciendo cuando modificamos un binario en el IDE de FoxPro (generar texto y luego binario), en este caso solo debemos regenerar el binario, ya que es el texto el que estuvimos modificando. Si no lo hacemos así, perderemos todos los cambios del merge y nos estaremos quedando con los archivos binarios del workspace y en el peor caso también con las versiones texto mezcladas que ya no corresponderán a esos binarios!

Lo repito para remarcar: Luego de un Merge, mandan siempre las versiones texto, ya que es con lo que se ha trabajado en esta operación, por lo que sólo se deben regenerar los binarios usando el script de "Cambios Pendientes: Regenerar Binarios".

Y luego se hace el checkin para guardar todo.

Les dejo un video de ejemplo con explicación incluida:
http://youtu.be/ytMpWP69YMo


[02/04/2014 - Actualizado >>]
Respecto al checkin hay una opción que debemos conocer, y que es "Proteger los cambios a otra rama...", y la verdad es que es una opción muy útil que me ha tocado usar más de una vez.

Imaginemos que abrimos FoxPro en el workspace y comenzamos a trabajar, hacemos algunos cambios, algunas pruebas y vamos a Plastic para guardar los cambios, pero nos encontramos con que, sin quererlo, estábamos trabajando en la rama principal (esa en la que no se deben hacer cambios directamente, sino solo merge :-) y nos olvidamos de crear una rama nueva para trabajar. ¡Por Dios! ¿qué hacemos ahora? Fácil: usamos esta opción y creamos el changeset en una nueva rama, todo en un mismo paso:


Se nos pregunta el nombre de la rama y al confirmar nuestros cambios irán directamente a ella, dejando la rama principal como estaba.

En esta pantalla donde nombramos la nueva rama además tenemos otra opción interesante, que es un checkbox que nos permite pasar los cambios a la nueva rama, pero sin hacer checkin (por defecto hace checkin), lo que viene muy bien si solo queremos pasar nuestros cambios aún sin terminar a la nueva rama para hacer más tarde el checkin nosotros cuando realmente hayamos acabado los cambios:



[<<]


Como nota final, es interesante saber que este programa de merge se puede usar por separado, o sea, viene con Plastic y está un su directorio de instalación, pero se puede ejecutar por separado. Se llama "mergetool.exe" y tiene una opción dedicada en le menú de Windows, dentro del menú "Client Tools" de Plastic.

Nada más por hoy.

Hasta la próxima entrada! :D




lunes, marzo 17, 2014

PlasticSCM: ¿Qué es el Diff?

[03/04/2014 - Actualizado con la opción de Diff modificable si se hace checkout del archivo]

Por: Fernando D. Bozzo

El Diff es una operación para obtener las diferencias entre dos archivos, o entre dos versiones del mismo archivo, y se usa para poder ver de un vistazo qué ha cambiado.

En general todas las herramientas de control de código fuente incorporan alguna herramienta de Diff, e incluso existen herramientas externas que permiten comparar diferencias entre archivos o incluso entre directorios, como el WinMerge (gratuito) o el EditPlus (de pago).


En Plastic hay varias formas de invocar un Diff, se puede desde la vista de Cambios Pendientes, desde la de Items, desde la vista del Explorador de ramas, etc, y se pueden comparar dos momentos cualquiera de la historia de un archivo o de un changeset (conjunto de archivos y/o directorios), por lo que no solo se pueden ver los cambios hechos en un archivo, sino también los cambios hechos de un changeset a otro, donde por ejemplo, se puede ver si se agregó, modificó o eliminó un archivo o directorio.


En la siguiente imagen se puede ver una parte de la historia de FoxBin2Prg comprendida etre la versión v1.16 y la v1.17, donde se desarrolló el soporte para trabajar en modo Batch y además se solucionaron algunas incidencias reportadas del soporte de menús de la versión anterior.

Los dos changesets que tienen los círculos verdes (etiquetas de versión) corresponden a la rama principal, y los dos changesets de más abajo corresponden a la rama de desarrollo que comenzó en la v1.16


Si queremos ver las diferencias entre estos dos changesets, marcamos (click) el de la derecha, y luego marcamos (ctrl+click) el de la izquierda, veremos como se iluminan o aclaran al seleccionarlos.

Acto seguido hacemos click-derecho sobre cualquiera de los dos y elegimos "Mostrar diferencias entre changesets seleccionados", lo que enviará la información de estos dos changesets a la herramienta interna de Diff para que los compare. En la imagen de abajo se puede ver el Diff resultante (click en la imagen para ampliar):




En la parte superior de la imagen se puede ver la información del changeset: nombre de usuario (fernando), número de changeset (cs:128), fecha/hora y comentarios sobre el desarrollo y las modificaciones realizadas.



Bajo esa sección hay una barra con controles para navegar entre los archivos que se muestran en el panel de debajo, un botón de estadísticas y a la derecha de todo un filtro que permite ubicar rápidamente uno o varios archivos escribiendo parte del nombre.




Luego está el panel de archivos, donde se puede ver:   Cambiados: 5 elementos
con los 5 archivos modificados, y luego se ve:   Añadidos: 12 elementos
con los 12 archivos que fueron agregados, de los que solo se ve el primero



Bajo este panel hay una barra de controles para navegar por las diferencias, un contador de diferencias, un menú de Opciones donde se pueden configurar varios aspectos sobre cómo ver las diferencias, si se deben ignorar fines de línea y espacios en blanco, codificación de caracteres, etc, y una opción de búsqueda para ubicar algo rápidamente.



Finalmente está el panel de diferencias, donde en la parte superior de cada uno, a modo de cabecera, se muestra que changeset se está viendo, de qué rama y qué usuario lo creó. En este ejemplo se está comparando el changeset cs:125 contra el cs:128, y debajo está el código, donde el antiguo está del lado izquierdo y el más nuevo del derecho.



Entre ambos paneles de código hay una serie áreas grises que suelen mostrar los bloques de código coincidentes que se han modificado, agregado o quitado, y unas áreas violeta que muestran los bloques movidos de un sitio a otro (en este caso, en el menú de opciones superior tengo habilitada la detección de bloques movidos)

[03/04/2014 - Actualizado >>]
Hay una opción muy interesante en el Diff, que solo se habilita si de los archivos que comparamos, al del workspace le hacemos previamente checkout, y lo que se habilita permite seguir editando el archivo del workspace desde la ventana del merge, no solo como un editor de código manual, sino también permitiendo pasar bloques de modificaciones del panel izquierdo (versión histórica del archivo) al panel derecho (archivo del workspace) o incluso permitiendo desactivar grupos de cambios con una "x" que aparece en el bloque cuando corresponda. Los 3 tipos de edición se pueden apreciar en esta imagen:


Una vez realizados los cambios, se pueden confirmar con el botón "Save" o descartar con "Discard".
[<<]


Aprender a usar bien esta herramienta y conocer y probar sus opciones nos permitirá poder hacer las comparaciones de forma óptima, ahorrando un montón de tiempo.


Hasta la próxima!

domingo, marzo 16, 2014

Nueva versión v2.4.11 de las herramientas FoxPro 9 para PlasticSCM (contiene FoxBin2Prg v1.19.17)

Por: Fernando D. Bozzo

Está liberada la versión v2.4.11 de las herramientas Visual FoxPro 9 para PlasticSCM, con los siguientes cambios:

- Actualizada la versión de FoxBin2Prg a la versión v1.19.17


Estas herramientas son un grupo de scripts vbs y programas Visual FoxPro 9 que se configuran dentro de PlasticSCM para poder invocar a FoxBin2Prg (incluye solo el EXE) desde dentro de la interfaz de Plastic.

El README.txt explica como se configura en Inglés y Español.


Como actualizar las existentes:
Con descargarlas y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link de descarga:
https://github.com/fdbozzo/foxpro_plastic_diff_merge


Saludos!

Nueva versión v1.19.17 de FoxBin2Prg (arreglos)

Por: Fernando D. Bozzo

Está liberada la versión v.1.19.17 de FoxBin2Prg con los siguientes cambios:

  • Arreglo bug frx/lbx: Las expresiones con comillas corrompen el fx2/lb2 (Ryan Harris). Si dentro de una campo, por ejemplo Comment, Tooltip u otro, contiene expresiones combinadas con cadenas entrecomilladas (ej: "este dato" + " este otro"), el archivo fx2/lb2 generado es inválido. Regenerando el fr2/lb2 se corrige
  • Arreglo bug frx/lbx: La propiedad Comment se pierde si es multilínea (Ryan Harris). En los reportes hay una parte de las propiedades del generador que permite escribir comentarios y tooltips multilínea. Normalmente no se usan, pero si se usan y además se escribe alguna línea con <CR>, el archivo fr2/lb2 generado es inválido. Regenerando el fr2/lb2 se corrige
  • Arreglo bug frx/lbx: Si la condición de impresión de un campo contiene una expresión con <CR>, se corrompe el archivo fr2 y luego el binario. Los reportes y etiquetas permiten indicar una condición para imprimir, o no, según devuelva True o False. Si de alguna forma se logra saltear la validación del editor de expresiones para poner un <CR>, el archivo fr2/lb2 generado es inválido. Regenerando el fr2/lb2 se corrige
  • Mejora de tag2 en frx/lbx para que muestre el valor real y no el codificado b64. El campo tag2 de los frx/lb2 puede contener información en texto limpio, como los tooltips, o información binaria y por eso siempre los codifiqué en base 64. Desde esta versión distingo si el campo se usa para tooltips o no, y si contiene texto plano no lo codifico para que se pueda leer en claro. Regenerando el fr2/lb2 se codificará como se indicó. Están afectados los archivos fr2/lb2 anteriores que usen tooltips y siguen codificados en b64
  • Arreglo bug mnx: Los comentarios multilínea en los Bars/Pads corrompen el MN2 y el MNX regenerado (Ryan Harris). Mismo problema que lo comentado para los frx/lbx, y aplicable solo si se han usado comentarios multilínea. Regenerando el mn2 se corrige
  • Arreglo bug mnx: Algunos procedimientos no se generan correctamente (Ryan Harris). Esto realmente tiene que ver con condiciones mal formadas o hacks raros en los archivos MNX, pero igualmente algunos valían la pena prevenirlos para evitar errores. Regenerando el mn2 se corrige
  • Correcciones al archivo de traducción al Inglés foxbin2prg_en.h (Ryan Harris). Agradezco a Ryan el haberme enviado el archivo de traducción al inglés con las correcciones de sintaxis.
  • Arreglo bug vcx/scx: Si la propiedad Dataenvironment se guarda en minúsculas, no se calcula el valor de Reserved2. Esto tiene que ver con una de las últimas mejoras de capitalización de nombres de clase y de objetos para evitar diferencias en las herramientas SCM, pero los vcx/scx parece que funcionan igual. Regenerando el vc2/sc2 se corrige
  • Adaptaciones en algunos tests unitarios FoxUnit para permitir diferencias de capitalización en algunos campos
  • Arreglo bug mnx: Usar comillas en el prompt de una opción genera un mn2 inválido (Ryan Harris). Esto tiene que ver con hacks raros en los nombres de las opciones. Regenerando el mn2 se corrige

Como actualizar el FoxBin2Prg existente:
Con descargar el zip y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link  de descarga:
https://vfpx.codeplex.com/releases/view/116407


 Saludos!

PlasticSCM: Cómo trabajar en FoxPro 9 con ramas por tarea

Por: Fernando D. Bozzo

En esta ocasión vamos ver una forma de trabajar con ramas, que sirve tanto para uno como para varios desarrolladores. Si no sabes lo que es una rama, antes de seguir te convendría leer el artículo anterior sobre este tema: PlasticSCM: Cómo crear una rama para comenzar a trabajar


La norma básica a seguir es muy simple: Jamás hacer cambios en la rama principal!. Nunca!


(Bueno, las únicas excepciones son el primer add/checkin con un archivo README.txt, que recomiendo absolutamente, y la subida del proyecto FoxPro 9, que será el segundo add/checkin)

A partir de quí, lo único que se debe hacer en la rama Principal es el merge final de las demás ramas para etiquetar la versión. Todo el trabajo se debe hacer en ramas derivadas de la principal.

Antes de continuar un aviso: Para todo lo que sigue voy a asumir que la estructura de directorios de tu proyecto está encapsulada de forma que en la raíz está el proyecto (pjx) y el programa principal, y en los subdirectorios están los componentes, y que no se referencian componentes externos a esta estructura de directorios, por ejemplo apuntando a otra aplicación o ubicación de librerías como las FFC de FoxPro. Si esto no se cumple entonces no podrás obtener todas las ventajas de trabajar con control de código por las dependencias externas que tengas y tal vez de convendría leer antes: Crear un proyecto FoxPro: ¿por dónde comenzar?


Pasos a seguir para comenzar a trabajar con un proyecto nuevo


En este caso tenemos un proyecto FoxPro 9 que se crea desde cero y que desde el mismo inicio se pone bajo control de código.






Cómo agregar un proyecto existente al control de código para trabajar


Este es el caso típico para muchos desarrolladores que tienen proyectos hechos, y que ahora deciden meterlos en control de código para continuar trabajando de esta forma.
Los pasos para agregar un proyecto FoxPro existente al control de código está explicado en este artículo.
Para comenzar a trabajar con este proyecto FoxPro ya controlado, ver el siguiente punto.


Pasos a seguir para comenzar a trabajar con un proyecto existente


En este caso tenemos un proyecto FoxPro 9 que ya estaba bajo control de código fuente previamente, por lo que los nuevos desarrolladores solo deben unirse para tener lo último, crearse sus ramas y comenzar a trabajar en ellas, por lo que deben:
  • Crear el directorio en el disco donde se alojará el proyecto FoxPro 9 (ojo, el directorio vacío!)
  • Crear el repositorio Plastic para el proyecto
  • Crear el workspace asociado al directorio para poder actualizar el repositorio
  • Sincronizar el repositorio Plastic local con el repositorio remoto (esto se bajará el proyecto con archivos y directorios)
  • Crear una rama personal de desarrollo desde el último changeset de la rama Principal
  • Ya se puede comenzar a trabajar en la rama de desarrollo

Ejemplo de la rama de desarrollo v1.19.17 de FoxBin2Prg, que se creo a partir de la última versión v1.19.16 (círculo verde) de la rama Principal /main. Al finalizar se hará merge de la v1.19.17 de desarrollo en la rama principal nuevamente y se etiquetará la nueva versión como v1.19.17



Trabajo en ramas cuando se trabaja en solitario


Este caso es el que uso para trabajar en FoxBin2Prg, y es el modo de trabajo mínimo recomendado.

Se basa en tener:
  • La rama principal (/main) donde solo se hará merge y se etiquetarán las versiones
  • La rama secundaria para desarrollar
  • Alguna rama puntual para solucionar incidencias solamente

Pantallazo de un momento del historial de FoxBin2Prg
(click en la imagen para agrandarlo):


Como puede verse en la captura anterior, en la versión v1.15 de la rama principal hice una rama secundaria de desarrollo para trabajar en el soporte de los menús (MNX) que llamé "Soporte_MNX" (la tarea a realizar) y que luego se convertiría en la versión v1.16.

Mientras estaba trabajando en esta tarea descubrí un error en el soporte OLE de los forms y clases, lo que debía arreglar y promocionar cuanto antes, pero sin incluir nada del nuevo desarrollo. Y es en ese momento que abro una nueva rama desde la v1.15 para hacer el parche v1.15p1
Se puede ver gráficamente que con el arreglo hecho en ese parche (un solo changeset) luego hice un merge en la rama principal, que hizo la versión v1.15p1 pública y también hice un merge en la rama de desarrollo del Soporte_MNX, ya que de otra forma si no lo hiciera así, en la siguiente versión estaría incorporando nuevamente el error que había solucionado.

Al finalizar el trabajo en esta tarea, hice el merge final en la rama principal, que etiqueté como v1.16 pública e hice una nueva rama para comenzar a trabajar en el soporte para Proceso en modo Batch. En este punto Fidel Charny me reportó una incidencia sobre el posicionamiento del menú, pero esta vez en vez de crear una rama aparte para el parche, lo mezclé en la tarea actual, en el segundo changeset de "ProcesoEnModoBatch" y liberé todo junto al día siguiente como versión v1.17. Esto lo hice así porque tanto el desarrollo de la tarea como el parche los hice en un corto período de tiempo (1 día) y no valía la pena separarlos en versiones distintas.

Sobre la conveniencia de crear un parche y versionarla por separado solo con los arreglos o hacer los arreglos dentro de la rama de desarrollo para sacar todo junto en la siguiente versión, todo depende del tipo de desarrollo que se esté haciendo y de los tiempos que se manejen.

Para un programa como FoxBin2Prg, cualquiera de las dos formas de trabajo es válida porque es un conversor y no un aplicativo comercial, y en este caso el baremo que usé es de fechas: Si el desarrollo que estaba haciendo iba para largo y surgía algún reporte de bugs en medio, no podía dejar colgados a todos con el error hasta que termine el desarrolo actual, por lo que lo conveniente era sacar y versionar un parche por separado para luego poder seguir con el desarrollo actual. Pero si el desarrollo iba a ser rápido y surgía algún reporte de fallo, entonces sí hacía el arreglo en la rama de desarrollo actual y versionaba todo junto.

Como ahora el desarrollo de FoxBin2Prg esta terminado, está en etapa de mantenimiento, por lo que las ramas que se hacen son para corregir fallos e incorporar optimizaciones.


Trabajo en ramas cuando se trabaja en equipo


Cuando se trabaja en equipo, el desarrollo es similiar a trabajar en solitario, con la diferencia de que habrá una rama por cada desarrollador, y que en general los desarrolladores harán el merge en una rama de Integración, que en el ejemplo de la imagen de abajo es /main/TESTS, y en esa rama es donde irán integrando funcionalidades terminadas.

En esta rama de Integración no se deben subir cambios incompletos nunca, ya que esta rama debería ser lo bastante estable como para que el resto de desarrolladores puedan actualizar sus propias ramas desde la misma, con bastante seguridad en que no comenzarán a tener errores provocados por una subida inconclusa o errónea.

Convendría que se defina la figura del Integrador Principal, que sería la persona a cargo de hacer la revisión final del código que se integrará y los merge de las ramas de Integración en la rama principal una vez concluida la revisión. Esta figura es muy importante en el ciclo de desarrollo, ya que tiene la responsabilidad de integrar todos los desarrollos en la rama principal.

Durante esta revisión, el Integrador inspecciona las diferencias en el código de la rama de Integración (no en la rama de cada desarrollador!) usando la herramienta de Diff, para buscar posibles problemas o cosas mejorables y detectarlas antes de que se suban a la release definitiva en la rama Principal.


Pantallazo de un proyecto con su rama principal, su rama de Integración y dos desarrolladores Dev_1 y Dev_2:


Sobre esta forma de trabajar, ya había publicado un video.

Como puede verse en la imagen de arriba, cada desarrollador va trabajando en su rama y cuando tiene una funcionalidad terminada puede hacer una de dos opciones:

  • La integra con un merge en la rama de Integración, y acto seguido se actualiza su propia rama desde la de Integración para tener el trabajo de los demás. (Se puede ver que Dev_1 hizo esto en los dos primeros changesets)
  • O se baja primero lo de la rama de Integración en la rama propia con un merge y luego, con todo ya intgrado en su rama, hace otro merge en la rama de Integración desde la propia. (se puede ver que Dev_2 hizo esto en su segundo y tercer changeset)
Como recomendación personal, yo creo que la segunda forma de integrar es la mejor y más segura, ya que cada uno se está Integrando en la rama propia lo que hay en la rama de Integración, con lo cual si surgieran conflictos, se resolverían en la propia rama y no se afectaría a nadie si esto se hiciera mal. Además de que esto permite que una vez realizada esta actualización local se puedan probar los cambios integrados y corregir posibles errores antes de hacer el merge nuevamente en la rama de Integración, y así se tiene cierta seguridad sobre lo que se sube, ya que en el peor caso, si surgen errores en las pruebas locales (rama propia), nadie más estará afectado aunque se actualice desde la rama de Integración.

Si se hiciera al revés (merge a Integración y posterior merge a rama propia), se corre el riesgo de que se haga algo mal durante la Integración dejando esta rama inestable, y el problema es que, aunque se detecte en las pruebas posteriores, como esta rama es pública para el resto de desarrolladores, un error puede provocar que los demás que se actualicen se les propague a sus propias ramas antes de que se pueda corregir el error, lo que puede tomar un buen rato.



Trabajo en ramas con sistemas complejos y varios desarrolladores


Este escenario es similar al anterior, pero en este caso pueden haber varias ramas intermedias para distintas funcionalidades simultáneas, lo que crea un diagrama más complejo, y en el que la figura del Integrador Principal es imprescindible, ya que es quien debe conocer qué desarrollos deben integrarse en la versión actual o cuáles son para la próxima versión.

La siguiente imagen es una simulación de lo que puede ser un sistema complejo, formado por dos proyectos cortos, cada uno con dos desarrolladores, en los que se harán dos funcionalidades distintas que confluirán en la rama de Integración y de ahí a la rama principal en la versión etiquetada como v2.0, y de un proyecto a medio plazo, también con dos desarrolladores, que se va actualizando con la release principal, pero que todavía debe continuar desarrollando y por eso no hace merge en la principal.

(Click en la imagen para agrandar)


Cuando ese proyecto de mediano plazo se deba integrar, se deberá crear primero una nueva rama de Integración que salga de la última release disponible (por ej: de la v4.0), y deberá integrar sus cambios allí para poder realizar pruebas y certificar el funcionamiento, antes de que se integre en la rama Principal.



Recomendaciones finales


Como se ve, dependiendo del tipo de proyecto a realizar, el trabajo en ramas ayuda mucho si se usa adecuadamente. Dejo algunas recomendaciones para tener en cuenta, que están basadas en las buenas prácticas y en la experiencia de varios proyectos durante bastante tiempo:

  • En los componentes usar rutas relativas, nunca rutas absolutas. Esto permitirá que el proyecto sea portable e independiente de la ruta que se use para trabajar
  • Para un proyecto compartido conviene predefinir y usar el mismo directorio entre desarrolladores para evitar diferencias en el pjx, que si no a cada desarrollador le detectará un directorio distinto, el cuál aceptará y esto generará una nueva diferencia innecesaria
  • Hacer uso extensivo de las buenas prácticas de programación (encapsulación, refactorización, etc).
  • Como mínimo se debería respetar una nomenclatura de objetos, como la sugerida por la ayuda de FoxPro. Esto no solo permite que el código se auto-documente, sino que facilita los merge manuales y maximiza los automáticos que no requieren intervención
  • Usar FoxPro desde el directorio raiz del proyecto (workspace) y no cambiar la sesión a otros directorios (set default to <dir> o cd <dir>) ya que esto puede provocar problemas y bloqueos en el SCM cuando se quiera hacer un checkin o cambiar a otro changeset
  • Cerrar siempre los forms, proyectos, clases y programas abiertos, y hacer CLEAR ALL antes de ir al SCM a realizar alguna tarea.
  • Un bloqueo en algún archivo controlado por el SCM puede provocar un error en el checkin o que impida poder regenerar las versiones texto o binario con FoxBin2Prg y que en consecuencia se suban archivos des-sincronizados entre sí, como un binario sin su tx2 o viceversa

Hasta la próxima!