Archive for the ‘SVN’ Category

Ramificando en Mercurial

Lunes, Mayo 31st, 2010

En el artículo anterior prometí volver a hablar de Mercurial y heme aquí cumpliendo la promesa.

En este caso quiero hablar de uno de los cambios más importantes en la filosofía respecto a subversion: la ramificación (o branching).

Ramificando en Subversion

En svn la ramificación se realiza de un modo bastante rudimentario, aunque bonito a su manera. Ya sabéis cómo funciona, así que no me extenderé, y lo contaré todo en plan resumen.

La ramificación se hace con la orden branch. Al ejecutarla, se crea una copia de la estructura del directorio origen, al directorio destino, incluyendo toda la información de historial y revisiones.

Las convenciones nos dicen que en el directorio trunk se encuentra la rama principal (de ahí el nombre, tronco), donde está el desarrollo estable. Las ramas de desarrollo se almacenan todas dentro del directorio branches (ramas), y a veces se ramifican también las versiones estables que salieron a la luz en releases.

Pera esta estrucutura no es más que, como hemos dicho, convenciones. SVN no sabe qué directorio es una rama, o cuál es el principal. Nosotros usamos source/trunk en lugar de trunk, y podríamos usar ramas en lugar de branches como nombre de directorio para las ramas.

De hecho SVN, no sabe qué es rama y qué es tronco, y aquí es donde vienen los quebraderos de cabeza. Cuando fusionamos ramas mediante la orden merge, tenemos que especificar qué revisiones vamos a mezclar. Eso significa muchas veces bucear por los historiales de unas ramas y otras para saber cuándo se creó la rama y cuál fue el último cambio en fusionarse.

Ramificación en Mercurial

En Mercurial no existen ramas en un repositorio. Cuando quieres hacer una rama, te creas otro, clonándolo del padre (orden clone).

Esto puede embrollar un poco el desarrollo con varias ramas, sobre todo si hay distintos desarrolladores trabajando sobre distintas ramas, pero el control de las ramas y los cambios que van de una a otra puede ser más fino, menos rudimentario.

Así, resulta muy cómodo para el programador crearse las ramas de los diferentes aspectos o versiones en las que esté trabajando, y propagar los cambios de una a otra.

Yo recomiendo una estructura absolutamente jerárquica, en la que estén muy claros qué rama empuja los cambios a cuál, y no mezclarlas, ni crear flujos extraños.

Ejemplo

En la entrega anterior hablé de las ramas o repositorios que creé para las modificaciones de OpenTPV. Hoy, aparte de repetirlo, voy a poner un gráfico.

Partimos de la base de Openbravo POS, la aplicación original. Openbravo POS tiene su respositorio en Mercurial, de ahí mis inicios con este SCV. Opensistemas tiene su propio fork de Openbravo POS. Cuando se usaba SVN, mantener OpenTPV actualizado era muy laborioso, puesto que había que ir generando parches e irlos aplicando. Ahora con Mercurial, sólo tenemos que ir haciendo pull del contenido cuando haya alguna actualización.

Por tanto creé OpenTPV como un clon de Openbravo POS, sobre el que hice las modificaciones. Además, consideré oportuno crear un repositorio estable y otro de desarrollo, por lo que cloné el estable.

Ahora, ciertas modificaciones que quería nuestro cliente no las consideraba apropiadas para la versión oficial de OpenTPV, por lo que creé otro repositorio más, clon del de desarrollo. Por último, el cliente quería una versión para resoluciones pequeñas, así que creé otro clon para poder ofrecer ambas.

Una vez tenemos definidos los repositorios que vamos a tener, hay que diseñar la dirección en la que se propagarán los cambios. Si colocamos cada clon debajo de su original, podemos considerar útil propagar los cambios hacia arriba (push) o hacia abajo (pull). En la corta experiencia que tengo con Mercurial no recomiendo mezclar direcciones.

Juntando todo, la estructura más lógica es la siguiente:

Ramas de OpenTPV

Así, cada vez que tenía que añadir una funcionalidad (o corregir un bug), analizaba la parte a la que correspondía aplicar:

  • Si la funcionalidad era apropiada para OpenTPV, la aplicaba a la rama OpenTPV desarrollo. Después propagaba los cambios hacia las versiones de los clientes.
  • Si era una funcionalidad querida por el cliente, pero no apropiada para OpenTPV, lo aplicaba sobre la versión del cliente. Después propagaba los cambios hacia la versión de baja resolución.
  • Si era un cambio de interfaz para baja resolución, lo aplicaba sobre la personalización de baja resolución exclusivamente.

Mercurial, explicado para usuarios de Subversion

Martes, Mayo 4th, 2010

Debido a que los repositorios de Openbravo son de Mercurial, en los últimos meses me he tenido que acostumbrar con ese sistema de control de versiones (SCV).

Para alguien que sólo ha trabajado con Subversion (o anteriores), esto significa un importante cambio de filosofía, puesto que Mercurial se engloba dentro de los más modernos sistemas de control de versiones distribuidos (como Git, Bazaar y otros). Lo que voy a contar es específico de Mercurial, pero estos cambios vienen motivados por su característica de distribuido.

El principal cambio es respecto a la redifinición de los conceptos de cliente y servidor. En SVN, la separación está muy clara: el servidor aloja las versiones y se encarga de su gestión. Por otro lado, los distintos clientes se bajan copias del servidor, realizan cambios, y envían esos cambios al servidor.

SCV tradicional

En toda esta relación está claro quién es quién. En nuestra máquina local tenemos el cliente, y en el servidor el repositorio. Con Mercurial la cosa cambia mucho, porque cada copia del repositorios es a la vez cliente y servidor. En lugar de hacer checkout, para hacerte con un repositorio cliente del servidor, haces clone, con lo que creas un nuevo repositorio cliente-servidor copia del anterior. Las operaciones de commit y update funcionan en local, mientras que se introducen nuevas operaciones (pull y push) para intercambiar cambios entre repositorios. Todo junto quedaría en el siguiente esquema:

SCV distribuido

Esta estructura es bastante más compleja que un SCV tradicional, pero ofrece una serie de ventajas que compensan el aprendizaje inicial. Se suele decir que las principales ventajas son relativas a proyectos grandes, con un montón de colaboradores y varias personas validando grupos de estos colaboradores. Sin embargo, mi experiencia es que incluso cuando hay un único desarrollador, hay beneficios importantes.

Una ventaja que puede parecer secundaria, pero que a mí me encanta, es la capacidad de realizar commits locales. Esto permite trabajar con el control de versiones aún cuando no tienes acceso al servidor princiapl (circunstancia muy frecuente). Esto permite que los desarrolladores incomunicados puedan hacer commits con cambios pequeños y atómicos, en lugar de realizar un envío masivo donde todos los cambios van a tropel y hacen inmanejables logs, control de cambios y vueltas atrás.

Hablando de vueltas atrás, con Mercurial también es posible revertir cualquier fichero a cualquier revisión sin necesidad de conexión con el servidor. Los programadores que se han visto en estas situaciones adversas (como proxies) durante largos periodos pueden valorar estas ventas.

Pero quizá la ventaja más importante está en el prácticamente nulo esfuerzo requerido para clonar repositorios. Por ejemplo, cada vez que un cliente nuevo requiere una personalización de Openbravo POS, se le puede crear un nuevo repositorio simplemente clonándolo. Luego cada desarrollador clonaría de este nuevo repositorio y compartirían los cambios a partir de él.

Si es el caso de OpenTPV, la versión de Opensistemas de Openbravo POS para negocios de restauración, la estructura sería Openbravo POS -> OpenTPV -> versión del cliente . Si hay cambios en el repositorio principal de Openbravo POS, es trivial irla bajando a OpenTPV y a sus modificaciones. Si arreglamos un bug, dependiendo de la raíz del problema, podemos corregir Openbravo POS, OpenTPV o la versión del cliente, y luego difundir esos cambios a los que corresponda.

La única desventaja que le encuentro a Mercurial es que requiere algo más de control y pensar bien cómo organizar estos repositorios. En otras entradas planeo contar un poco más de esto ya que, por si no se ha notado, Mercurial me ha encantado.

Por todo esto, yo recomendaría su uso, o al menos probarlo. Quizá algún día merezca implantarlo a nivel oficial en la empresa, como alternativa al madurito Subversion.

Estructura de SVN para Proyectos de Software

Lunes, Noviembre 5th, 2007
Tener una estructura ordenada de nuestro repositorio es muy importante, pues el proceso de desarrollo en concreto produce artefactos software que deben ser mantenidos, ordenados, revizados y catalogados adecuadamente.

Para quienes no utilicen un control de versiones en sus proyectos, les recomiendo que comiencen a usarlo inmediatamente pues en el software hay que ser simplista, gestionar los cambios, reutilizar lo más posible, y en la medida de lo posible que herramientas hagan nuestro trabajo [Para los estudiosos: Do not repeat yourself, Keep it simple stupid, etc].

Lo primero es entender como trabaja un control de versiones en lineas muy generales: Existe un directorio donde se alamcena una base de datos de archivos, cada desarrollador obtiene una copia de ese directorio y hace los cambios necesarios que luego sube a este directorio; Si hay más de una persona trabajando no importa pues tiene herramientas automáticas que son capaces de juntar los cambios incluso en un archivo y avisar de los conflictos. Para más información sobre control de versiones y en concreto de subversion click aqui.

Ahora que ya se sabe el beneficio de usar un sistema de control de versiones, se debe definir que estructura deberá tener este. Si bien la estructura depende del proceso de desarrollo de software que practiques, la estructura que se presenta la puedes usar como base pues formaliza los archivos y carpetas que se deben incluir.

Nomenclatura:
  • Linea base: Linea base de gestión de configuración - en nuestro caso una carpeta que contien determinados artefactos.
  • ITER: Número de la iteración en la cual fue producido el documento o modelo. No aplica a código fuente. Ejemplo: PLAN_REQ-ERS-00.doc significa el documento de especificación de requisitos de la linea base PLAN_REQ que se produjo en la iteración 0.
Tipos de archivo (de las herramientas que yo uso):
  • .zargo: Modelo UML en ArgoUML
  • .doc: OpenOffice Word Processor
  • .xml: Modelo de base de datos en DBDesigner.
  • .txt: Un editor de texto.
  • .sql: Script sql.

Cabe señalar que se trata de una estructura de directorios para un proceso de desarrollo iterativo, más info aqui

  • trunk (Directorio de desarrollo)
    • PLAN_REQ (Linea base de planificación y requisitos)
      • PLAN_REQ-CALIDAD-ITER.doc (Plan de calidad)
      • PLAN_REQ-CASOS_DE_USO_FORMATO_BREVE-ITER.doc (Casos de uso, formato breve)
      • PLAN_REQ-CONFIGURACION-ITER.doc (Plan de gestión de configuración IEEE 828)
      • PLAN_REQ-DESCRIPCION_DEL_SISTEMA-ITER.doc (Descripción del sistema)
      • PLAN_REQ-DIAGRAMA_CASOS_DE_USO-ITER.zargo (Diagramas de casos de uso)
      • PLAN_REQ-ERS-ITER.doc (Especificación de requisitos de software - IEEE 830)
      • PLAN_REQ-ESTIMACION_PLANIFICACION-ITER.doc (Estimación y Planificación del proyecto - Cocomo II, Puntos de función, cartas gantt)
    • DISEÑO (Linea base de análisis y diseño)
      • DISEÑO-CASOS_DE_USO_FORMATO_EXTENDIDO-ITER.doc (Casos de uso formato extendido - màs conocido como Fichas de casos de uso)
      • DISEÑO-CONTRATOS_DE_OPERACIONES-ITER.doc
      • DISEÑO-DIAGRAMAS_DE_SECUENCIAS_DEL_SISTEMA-ITER.zargo (Pueden obviarlo - no me gustan muchos estos diagramas)
      • DISEÑO-MODELO_CONCEPTUAL-ITER.zargo (Classes de análisis)
      • DISEÑO-DIAGRAMA_DE_CLASES-ITER.zargo (Classes de Diseño)
        DISEÑO-DIAGRAMAS_DE_INTERACCION-
        ITER.zargo (Diagramas de secuencia y comunicacion[colaboración])
      • DISEÑO-MODELO_RELACIONAL_BASE_DE_DATOS-ITER.xml
      • DISEÑO-PLAN_DE_PRUEBAS-ITER.doc
    • IMPL (Linea base de implementación)
      • IMPL-BASE_DE_DATOS-ITER.sql (Dump de la base de datos)
      • SRC (Código fuente)
    • PRUEBAS (Linea base de pruebas)
      • PRUEBAS-PRUEBAS_DEL_SISTEMA-ITER.doc
    • ENTREGA (Linea base de entrega)
      • ENTREGA-LICENCIA-ITER.txt
      • ENTREGA-MANUAL_DE_INSTALACION-ITER.doc
      • ENTREGA-MANUAL_DE_ADMINISTRACION-ITER.doc
      • ENTREGA-MANUAL_DE_USUARIO-ITER.doc
      • ENTREGA-NOTAS_DE_LA_ENTREGA-ITER.txt
  • tags(Directorio de marcas de desarollo)
    • iteraciones (Cada vez que se termina una iteración se hace una copia del trunk aquí, marcada yyyymmdd_iterITER)
    • releases (Cada vez que se lanza una versión del producto se hace una copia del tag de iteración correspondiente aquí yyyymmdd_releaseRELEASE)
  • branches (Directorio de variantes del proyecto)

Puedes descargar la estructura aqui,

Haz checkout de tu repositorio descomprime la carpeta en tu copia de trabajo y haz commit. Yo uso subEclipse, RapidSvn y subversion por terminal.

Espero les sirva.

Si tienes feedback deja comentarios o me escribes a lbarrientos@opensistemas.com.

Suerte!