Selectores en Plastic SCM: Bienvenidos al lado oscuro III

17:20 0 Comments

Después de posts previos describiendo los selectores al detalle, ahora es el momento de pasar la última frontera de los selectores: selectores con múltiples repositorios.

Como ya sabéis plastic puede gestionar múltiples repositorios. Se puede mapear cada uno de los proyectos en un repositorio de plastic o utilizar prácticas más avanzadas como desarrollo orientado a componentes.

Los repositorios pueden ser totalmente independientes unos de otros, pero tambien hay situaciones en las que se pueden relacionar. Por ejemplo, podemos tener librerías compartidas que se han desarrollado y reutilizado entre diversos proyectos. Si este fuera el caso podría ser muy útil el tener un repositorios para cada proyecto y otro repositorio para las librerías.

Pero entonces, ¿cómo pueden utilizar los desarrolladores el código de las librerías y del proyecto a la vez?


Veamos un repositorio muy simple como el de la imagen. Tiene un par de ficheros y un directorio vacío. Probablemente ninguno de los proyectos que utilize sea tan simple. Supongamos que este es el repositorio denominado “proj00”.




Entonces tendremos otro repositorio que contenga la librería de código. Tiene la apariencia de la siguiente figura. Este repositorio se llama “lib_repos”.



Ahora necesitamos que el repositorio lib_repos esté disponible para los desarrolladores “proj00”.
Por favor tenga en cuenta que hemos creado un directorio vacío “lib” que se utilizará como punto de montaje en “proj00” para unir “lib_repos”.

Veamos el siguiente selector:

repository "lib_repos" mount "/lib"

path "/"

branch "/main"

checkout "/main"

repository "proj00"

path "/"

branch "/main"

checkout "/main"


Recordemos cómo funcionan las reglas del selector:
de arriba hacia abajo verá como le decimos a plastic: coge todo de lib_repos en la rama principal, pero móntalo en /lib. Después necesitará resolver la ruta /lib que se utilizará utilizando la siguiente regla del repositorio (proj00).

Si ejecuta el siguiente ls (con un modificador de formato para mostrar la información del repositorio), verá lo siguiente.

>cm ls

br:/main#1@rep:proj00@local:8084 .

br:/main#0@rep:proj00@local:8084 file00.txt

br:/main#0@rep:proj00@local:8084 file01.txt

br:/main#1@rep:lib_repos@local:8084 lib



Nota:
Utilizamos la siguiente variable de entorno PLASTIC_LS_FORMAT:
LS_FORMAT="{3}@{8,-26} {4,-5} {5}"

Bien, el directorio de la librería se está cargando desde el repositorio lib_repos.
Claro que si nos movemos dentro del directorio comprobaremos que todo lo que hay dentro está en el mismo repositorio. Mire la siguiente captura de plastic que muestra los detalles de los ficheros y directorios del repositorio.

Implementar un entorno de trabajo real
El selector de arriba mostraba cómo ir desde el desarrollo en la rama principal a un escenario de múltiples repositorios. Pero probablemente necesitará implementar toda una estrategia de ramas. Si es así debería de considerar el siguiente selector:

repository "lib_repos" mount "/lib"

path "/"

label “lib_00”

repository "proj00"

path "/"

branch "/main/task001" label “BL010”

checkout "/main/task001"



Este patrón se parece al patrón de rama por tarea en un escenario de múltiples repositorios.

Por favor tenga en cuenta que ahora estamos montando “lib_repos” como sólo lectura ya que estamos especificando una etiqueta y no una regla de desprotección.

El modo de utilizar el repositorio montado variará dependiendo de las necesidades de su proyecto. Puede ocurrir que un grupo diferente de desarrollo gestione completamente “lib_repos”, entonces se podría montar cómo de sólo lectura ya que los desarrolladores del proyecto “proj00” sólo lo utilizarán como “librería”. Lib_repos irá a través de su propio ciclo de versionado y el equipo de proj00 solo tendrá que ocuparse de cambiar la etiqueta del repositorio montado cada vez que haya una nueva versión disponible y aprobada para su proyecto.

También puede ocurrir que su equipo sea responsable de ambos repositorios. Ha decidido separarlos por estar trabajando claramente con diferentes componenetes pero sólo tienen un ciclo de versionado.

Entonces tendría sentido seguir un "ciclo de ramificación y merge" combinado para ambos repositorios. Si está trabajando en la tarea task001 entonces puede ocurrir que necesite cambiar código tanto en both lib_repos como en proj00. Estará probablemente utilizando un selector como el siguiente:


repository "lib_repos" mount "/lib"

path "/"

branch "/main/task001" label “BL010”

checkout "/main/task001"

repository "proj00"

path "/"

branch "/main/task001" label “BL010”

checkout "/main/task001"



Por favor tenga en cuenta que:
Hay dos ramas /main/task001, una en cada uno de los repositorios, y lo mismo ocurre con las etiquetas, pero se puede utilizar un sistema de nombre (utilizando el mismo nombre que yo estoy usando aquí) para reforzar su relación.

Avanzando aún más, configuracion del sistema montado
Hasta ahora hemos visto escenarios típicos. Pero, ¿qué pasa si necesitaramos montar dentro del directorio “/lib” en “proj00” algo que no está en la raíz de “lib_repos”?

Entonces utilizaremos la potencia de herencia de ramas de plastic para conseguir el resultado deseados.

Supongamos que queremos montar dentro de “lib” el contenido del directorio “/bin”. Así que queremos utilizar “/bin” como la raíz del repositorio lib_repos repository. Para facilitar las cosas asumimos que hay un subdirectorio versionado dentro de “bin”. Mire la siguiente figura.



Vamos al repositorio lib_repos y creamos una rama denominada “/main/mount-point”.
Entonces utilizamos los comandos rm y mv para configurar correctamente la rama "mount-point" como necesitamos.


>cm co .
Checking out . ... Done

>cm rm doc src
Item doc has been removed.
Item src has been removed.

>cm co bin
Checking out bin ... Done

>cm mv bin\release .
bin\release has been moved to .

>cm ls
0 07/04/08 dir br:/main/mount-point#CO CO .
0 07/04/08 dir br:/main/mount-point#CO CO bin
0 07/04/08 dir br:/main#0 release

>cm ci bin
Checking in bin ... Done
Created changeset
cs:3@rep:lib_repos@repserver:CONRAD:8084

>cm rm bin
Item bin has been removed.

>cm ls
0 07/04/08 dir br:/main/mount-point#CO CO .
0 07/04/08 dir br:/main#0 release

>cm ci .
Checking in . ... Done
Created changeset
cs:4@rep:lib_repos@repserver:CONRAD:8084

Entonces podemos configurar el siguiente selector:

repository "lib_repos" mount "/lib"
path "/?"
branch "/main"
checkout "/main"
path "/" norecursive
branch "/main/mount-point"
repository "proj00"
path "/"

branch "/main"
checkout "/main"

Por favor, tenga en cuenta lo siguiente:
Estamos utilizando la rama /main/mount-point sólo como “refactor”, pero el contenido se cargará en la rama principal del repositorio “lib_repos”. Claro que en vez de la rama principal podríamos estar utilizando otra rama.
El propósito de la rama /main/mount-point no es el de volver a integrarla en “/main” sino realizar una reorganización del proyecto. De hecho podemos incluso evitar que se integre denegando el permiso de integración.


Configuremos el siguiente selector:

repository "lib_repos" mount "/lib"

path "/?"

branch "/main/task001" label “BL010”

checkout "/main/task001"

path "/" norecursive

branch "/main/mount-point"

repository "proj00"

path "/"

branch "/main/task001" label “BL010”

checkout "/main/task001"



Y una pequeña explicación:

Cuando haga cambios en el código dentro del directorio “lib” estará colocando los cambios directamente en “/main/task001”, pero utilizando la reorganización del directorio de “/main/mount-point”.

Al volver a integrar /main/task001 en lib_repos, sólo obtendrá los cambios realizados en la tarea, y no toda la reorganización realizada dentro de “mount-point”.
Esto es por lo que la herencia de ramas de plastic es tan potente y permite implementar diversos escenarios.

Trabajo futuro
Actualmente estamos trabajando en el diseño de nuevas reglas del selector para permitir montar diversos repositorios directamente en diferentes localizaciones. Hay quien considerará la solución de la rama “mount-point” útil pero otros preferirán poder hacer algo equivalente utilizando las reglas del selector.

Estamos incluyendo nuevas reglas del selector para poder especificar cuál es el ítem raíz que se utilizará . De este modo se podría especificar que /bin es ahora raíz de lib_repos.

Además estamos trabajando en crear “directorios de selector del espacio de trabajo”, que son directorios locales que no están bajo el control de código fuente sino gestionados por la herramienta (creados en el proceso de update) y pueden contener código controlado…

Así que estamos abiertos a nuevas sugerencias… podéis contactarnos si tenéis ideas sobre la posible evolución del selector.

0 comentarios: