viernes, 28 de julio de 2017

Herencia de proyectos en ZinjaI

Tengo casi lista una nueva funcionalidad en ZinjaI que viene a aliviarme dos problemas en la gestión de proyectos, problemas que algunos de ustedes podrían compartir. Por un lado el problema de incluir el .zpr en un repositorio git (o cualquier VCS). El otro, el de compartir muchos archivos entre diferentes proyectos.

Nota: si quieren saltarse la justificación e ir derecho a la solución, comiencen justo después de la primera imagen.


En el caso de git, el problema es que el zpr tiene la info necesaria para compilar/construir el proyecto, o al menos el ejecutable. Además de que si usamos ZinjaI para desarrollar es necesario para trabajar. Entonces, por eso, es bueno que esté en el repositiorio. Pero por otro lado, tenerlo en git hace que se generen cambios innecesarios e insignificantes cada 5 minutos. Con solo abrir un proyecto en ZinjaI y cerrarlo, el zpr ya cambia. Porque guarda cosas como la versión de ZinjaI, las pestañas abiertas, la posición del cursor en cada una, cuál de ellas tenía el foco, etc. Muchas cosas que son cómodas, pero que no son verdaderos cambios que valga la pena registrar en el historial del repo.

Para esto, hasta ahora había dos opciones. Una es permitir que todos esos pequeños y olvidables cambios se registren igual en el historial. Esto hago en PSeInt, ZinjaI y MotoGT. Verán entonces que el 99% de los commits modifican algún zpr. Aunque el 90% no cambia ni la lista de archivos, ni las opciones de compilación, ni nada que sea importante registrar. La otra opción es tener dos .zpr, uno registrado en el repo, y otra copia ignorada. Así trabajamos con algunos otros proyectos en la universidad. Pero eso obliga a replicar la información en ambos y eso requiere cierta disciplina. Y casi siempre nos ocurre que cuando agregamos o movemos un archivo lo hacemos en el zpr de trabajo (la copia) y nos olvidamos del otro (el que sí va al repo).


El segundo escenario, que también se da en estos proyectos en la facultad, surge cuando varios programas clientes deben tener a una biblioteca común como parte propia (no como dependencia externa o de terceros). Entonces, si se agrega, quita o mueve un archivo de la biblioteca, hay que hacerlo en todos los zprs de todos los programas clientes. Y nuevamente, requiere disiciplina, es muy molesto, y conduce a olvidos varios.

Para las opciones de compilación hay una salida fácil: si queremos que varios zprs usen un mismo set de opciones básicas las ponemos en un script (algo tipo pkg-config) e invocamos al script como sub-comando en los campos de opciones de compilación y de enlazado adicionales. Así, cambiando la salida del script, cambian las opciones de todos los proyectos a la vez, automáticamente.  Pero para la lista de archivos compartidos, hasta ahora no había opción.

Si en los campos de argumentos adicionales coloco algo entre acentos (los graves, los que no usamos en español;
esta sintaxis viene de los Makefiles), ZinjaI ejecuta el comando y lo reemplaza por su salida estándar.


La nueva funcionalidad se llama, por el momento, "herencia de proyectos". La idea es la siguiente: en un proyecto A.zpr, se puede definir una referencia a otro B.zpr y decirle a ZinjaI que "herede" de A todos sus archivos, fuentes y cabeceras. Entonces, agregando, quitando o moviendo un archivo en A, automáticamente cambia en B. Así puedo tener un zpr base con la parte compartida de la biblioteca, y que "hereden" de él todos los zprs de los programas clientes. O puedo reducir el trabajo duplicado si tengo un zpr para registrar en el repo y otro para trabajar habitualmente.

Derecha:El nuevo campo para definir el proyecto "padre" en las opciones generales del proyecto.
Izquierda: el árbol de proyecto con los archivos heredados señalados con un color diferente.

Quedan algunas cosas por resolver. Como por ejemplo, qué pasa si quiero heredar todos los archivos menos una o dos excepciones. Por ahora (con lo que ya está hoy en el git) lo que puedo hacer es mover esos dos a la categoría "otros" para que ZinjaI no intente compilarlos ni parsearlos (ya puedo cambiar de categoría un heredado y que el proyecto hijo recuerde el cambio). Pero siguen ahí, y salen en las búsquedas. Una mejor alternativa que estoy probando es establecer una "lista negra", que aparecerá bajo demanda como cuarta categoría en el árbol del proyecto, pero cuyos archivos serán totalmente ignorados para cualquier operación de cualquier tipo.

Entonces, por ahora dejo lo de los subcomandos para compartir/heredar opciones de compilación, y ofrezco un primer mecanismo para compartir/heredar la lista de archivos. Esta opción va estar accesible desde las configuraciones generales del proyecto (buscar en el menú archivo, justo arriba de las preferencias). Tal vez más adelante evolucione y se puedan heredar más cosas, o tener un control más fino... ya veremos.

1 comentario: