INDICE 1. Introducción 2. Módulos 3. Comentarios 3.1. Principio de Módulo 3.2. Principio de funciones, estructuras, ... 3.3. De línea 4. Código 4.1. Ficheros .hh 4.2. Ficheros .cc 4.3. Declaraciones 5. Control de versiones 5.1. Implementación 1. Introducción El objetivo de este documento es mostrar a los desarrolladores el sistema que hay que utilizar en la elaboración de cualquier módulo. ¿Porqué se deben tener unas reglas y unos estándares para todos?. Principalmente para un mayor entendimiento de los módulos por los desarrolladores. Imaginemos por un momento que una persona hace el módulo mouse, y entre las funciones que este módulo hace se encuentran: mostrar puntero ratón, obtener coordenadas, ... Pero de repente, 5 meses después otro desarrollador, el cuál está creando el módulo ventanas, necesita que se cree una clase que devuelva un evento al gestor de ventanas. ¿Qué hacer?. Podríamos comunicarselo al creador del módulo mouse, pero realmente ése ahora ya no es su problema, sino que su problema es programar un modulo que gestione el joystick (o a lo mejor dicho desarrollador tuvo que dejar el proyecto por problemas personales). Lo mejor es que sea el propio desarrollador que necesite dicha función quién modifique el módulo del ratón y que cree la clase que necesita, ¿no?. Ahora bien, cuando obtiene el módulo que hizo el anterior desarrollador, ¿qué ocurriría si estuviese hecho en C o en Pascal?, y encima, ¿qué pasaría si no estuviese documentado?, se tardaría mucho tiempo en modificar la rutina (ver lo que hacen las diferentes variables y funciones ... no se podrían crear clases, ni nada relaccionado con objetos, lo que significaría una perdida de la capacidad de actualización global del proyecto). Aquí observamos el problema, no siempre una misma persona va a trabajar con un mismo módulo (sería lo ideal, pero no es así ya que la gente se va, otra viene, además de que una persona no puede dedicarse exclusivamente a un módulo). Por estas razones creo conveniente que leáis este documento, el cual debería ser el modelo a seguir por TODOS los desarrolladores de Tai-Kai. Incluso para los que programen en Windows (al fin y al cabo todos acabaremos haciendolo en breve). 2. Módulos Lo primero que tenemos que tener claro es cómo realizar los distintos módulos, teniendo en cuenta que vamos a utilizar un lenguaje C++ (aparte que se Borland C++, Watcom C++, ...). Los módulos se van a dividir en dos partes, .hh y .cc. Donde, .hh contendrá variables, definiciones, cabeceras de funciones, ... pero no contendrá nada de código. Para eso está .cc, éste contiene el código de las funciones que hayamos definido en el .hh y será el que se añadirá en el fichero de proyecto, para que sea compilado e introducido en el linkaje. Ejemplo: mouse.hh #if ¡defined(_MOUSE_HH) #define _MOUSE_HH // Los #include, #define y estructuras de datos públicas, deberán definirse aquí. class cCoordXY { int X; int Y; public: void GetCoordXY(int X, int Y); void PutCoordXY(int X, int Y); }; #endif // _MOUSE_HH mouse.cc // Los #include, #define y estructuras de datos privadas, deberán definirse aquí. void cCoordXY::GetCoordXY(int PosX, int PosY) { X=PosX; Y=PosY; } Este es un sencillo ejemplo, que permite al desarrollador que simplemente quiere utilizar el módulo mouse acceder de forma fácil a la clase allí definida (cCoordXY), sin necesidad de ver como está hecha (código que realmente no le interesa ver). Y de la misma forma, permite a un desarrollador modificar la clase, accediendo a mouse.cc. Hay que tener en cuenta que esto es un ejemplo y no está comentado. 3. Comentarios Una herramienta muy útil en los grandes proyectos (y al realizar cualquier programa) consiste en la documentación en línea del código. Normalmente un buen proyecto tiene entre el 40% y el 60% de las líneas que se crean de comentarios. Ahora bien, tampoco hay que crear 3 líneas de comentario para un simple printf(), hay que saber qué comentar y dónde comentarlo. Existen 3 tipos de comentarios que pueden incluirse: de principio de módulo, de principio de estructura o de función, y de línea. 3.1. Principio de Módulo Todos los módulos, al principio, deben contener una serie de datos que permitan identificarlo de entre otros. Deberá tener una línea con el nombre del módulo y otra con la versión de dicho módulo, que luego no se repetirán más a lo largo del fichero. La versión se modificará de acuerdo con los deseos del grupo de programación, así como el de los coordinadores. Luego deberá tener tantos bloques como retoques haya sufrido el módulo, me explicaré, primeramente cuando se cree el fichero, éste tendrá un número de revisión igual a 0. La fecha, contendrá el día en que dicho fichero fue modificado por el desarrollador. La descripción en la primera cabecera pertenecerá a la descripción del módulo, mientras que en posteriores bloques de revisión pertenecerá a la modificación realizada sobre la primera descripción. Las revisiones siempre harán referencia a la versión que aparezca en la segunda línea. Cuando se creen nuevas versiones, todos los bloques de datos desaparecerán y se comenzará con un bloque de revisión 0, conteniendo el nombre del desarrollador que ha modificado el fichero para adecuarlo a la nueva. Posteriormente, si alguien desea cambiar alguna parte de dicho módulo se introducirá a continuación, otro bloque con los datos de éste, aunque con el número de revisión incrementado (y los datos propios del desarrollador, claro). La cabecera de los distintos ficheros deberá seguir un estándar, tal como se muestra: /* Módulo: */ /* Versión: */ /************************************************************* Revisión: Fecha: Desarrollador: Descripción: ************************************************************/ Un ejemplo de un fichero sería: /* Módulo: mouse */ /* Versión: 1 */ /********************************************************************** Revisión: 0 Fecha: 1/06/98 Desarrollador: Moro Descripción: Módulo encargado de gestionar todo el proceso del ratón. **********************************************************************/ /********************************************************************** Revisión: 1 Fecha: 10/09/98 Desarrollador: Enrique David Descripción: Se ha modificado la función GetCoordXY() para que se le pase un puntero a la nueva estructura sMouseDat, de tal forma que actualice los datos que contiene. **********************************************************************/ 3.2. Principio de funciones, estructuras, ... Cada una de las funciones, estructuras y grupo de variables o constantes con las mismas características deberán ir precedidas de una serie de comentarios que podrá variar según el tipo al que pertenezca. Hay que tener en cuenta que este tipo de comentarios comenzará a la misma altura que el código y estará representado por //. Los grupos de variables, directivas de preprocesador, constantes, etc, deberán tener una explicación de la característica que les une, estará compuesto unicamente de una o dos lineas, aunque puede variar según las necesidades del desarrollador. Por ejemplo: // Modos de vídeo disponibles #define _ALFANUMERICO 3 #define _GR320x200 19 #define _GR640x480x256 0x0101 Como podeis ver, es muy simple y a la vez útil. De esta manera, conjunto de datos con los mismos objetivos (por ejemplo, utilizados como parámetro en una función), son localizados de una forma más eficaz y rápida. Las estructuras deberán tener, al igual que los conjuntos de datos, una explicación de cuál es su función en la aplicación, es decir, para qué se creó. Normalmente tendrá un par de líneas, aunque esto puede variar a gusto del desarrollador, o según la necesidad de dicha estructura. Por ejemplo: // Estructura que representa un punto 2D en el espacio struct sPoint2D { int PointX; int PointY; int Attrib; }; De esta forma, cuando veamos definida una estructura que no sabemos lo que hace, con leer el comentario valdrá. Para conseguir esto, este tipo de comentarios deben ser escuetos, concisos y que describan perfectamene a la estructura. Otros tipos que llevará neste comentario serán las clases, uniones, etc ... Por último, se encuentran las funciones y procedimientos. Realmente éstos son los que más lo necesitan, ya que el comentario inicial que les acompañe describirá la función a la perfección. Es muy importante que se comenten bien las funciones y procedimientos, por si necesitan ser modificadas o utilizadas por desarrolladores ajenos a su creador. Será un formato estándar, lejos de los descritos para estructuras, clases, conjuntos de datos, etc ... y no podrán cambiarse sus títulos. El formato de dicho comentario es: /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Descripción: // Entrada: // Salida: // Notas: /////////////////////////////////////////////////////////////////////////////////////////////////////////////// Un ejemplo de cómo se debe hacer, sería: /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Descripción: Función encargada de mostrar un sprite por pantalla desde // una zona de memoria. // Entrada: sDS ---> Estructura con los datos del sprite a copiar // lpDirDest ---> Dirección destino, o donde se copiará el sprite // cMask ---> Color de máscara // Salida: Devolverá 0 si no se pudo copiar o hubo algún error y 1 si fue bien. // Notas: Sirve además para mover sprites a zonas de memoria normales. /////////////////////////////////////////////////////////////////////////////////////////////////////////////// int cSprite::CopyMask( sDatSprite *DS, char *lpDirDest, char cMask) { } 3.3. Comentarios de línea Estos comentarios son los más típicos y simples. Únicamente se pondrán cuando el desarrollador crea conveniente. Su objetivo es el de "guiar" por el código tanto a posteriores desarrolladores que estudien una función ya creada, como al mismo desarrollador que la creó. Deben utilizar //, en vez de /*...*/. Esto tiene una explicación, si utilizasemos los comentarios de múltiples líneas, cuando el desarrollador desease "eliminar" un trozo de código para su depuración tendría muchos problemas, que no surgen si se utiliza el comentario //. Un ejemplo de este tipo de comentarios sería: #define _ALFANUMERICO 3 // Modo texto 80x25 #define _GR320x200 19 // Modo gráfico VGA #define _GR640x480x256 0x0101 // Modo gráf. SVGA Aunque en el ejemplo esté en líneas de precompilador, deberán utilizarse a lo largo de todo el módulo. Son muy importantes en los ficheros de cabecera .hh, ya que serán utilizados como interfaces entre distintos módulos, generados por distintos desarrolladores. Por éste motivo, debería ser obligatorio el uso de comentarios de línea en dichos ficheros. 4. Código El código no podrá hacerse de cualquier manera, ya que se debe conservar un estándar que tendrán todos los desarrolladores, para de esta manera entender módulos desarrollados por otros. Sería un auténtico caos y totalmente perjudicial para el proyecto que estamos emprendiendo el que cada persona crease sus módulos, con su metodología y a su manera. Luego si esta persona se da de baja sería casi imposible meterle mano a su código, por lo menos llevaría muchisimo más tiempo. Ni decir tiene que todo tiene que estar hecho con lenguajes aprobados por el conjunto de programadores (que en este momento se compone únicamente de Watcom C++). 4.1. Ficheros .hh Contendrán únicamente la cabecera del fichero correspondiente (con el mismo nombre) .cc. Hay que tener en cuenta que éste tipo de ficheros será el interface entre el módulo y nuestra aplicación, por lo que se podrá hacer, ya ha este nivel, una distinción entre funciones, variables, constantes, etc... locales y globales. Todo lo que se defina en estos ficheros tendrá carácter global, mientras que si queremos ocultar algo al desarrollador, que no necesite conocer o que no queramos mostrar cómo se ha hecho, lo que se hará es no añadir su definición en el .hh, pero sí en el .cc. Deberán estar perfectamente documentados, a través de comentarios (y no vendría mal algún fichero .txt en ASCII, con el mismo nombre que el .hh y el .cc). Debido a que, como hemos dicho, será el interface entre el módulo y otros módulos, y alguien que necesite introducir, por ejemplo, una clase ya creada en su módulo, deberá conocer perfectamente el funcionamiento de ésta, ya que si no puede tener problemas al trabajar con ella. Más adelante se puede ver un ejemplo de éste tipo de ficheros y su relacción con los .cc. 4.2. Ficheros .cc Contendrán código C++, orientado a objeto. Tendrá, obligatoriamente (a no ser que sea el principal), un fichero de cabecera, con el mismo nombre asociado a él. Todo lo que se defina o programe en dicho módulo permanecerá oculto a otros desarrolladores (aunque siempre se podrá abrir para ver su contenido, muchas veces no es necesario). El objetivo principal de éste tipo de módulos será aislar el código de lo que realmente se utiliza. Además de conseguir un cierto grado de privacidad entre módulos. Es muy importante comprender, que el código aquí introducido será privado a éste. Mientras que las cabeceras, variables, estructuras, y demás, definidos en el fichero .hh serán públicas al proyecto, aunque también serán codificadas en el fichero .cc asociado. Un posible ejemplo de la relación existente entre ficheros .cc y .hh, siguiendo con la programación del ratón, sería el siguiente: mouse.hh #include "../hdrs/evento.hh" #define _MAXROW 640 #define _MAXCOLUMN 320 class cMouse { int iPosX, iPosY; char cBotD, cBotI; void MsjEvento(cEvento *EvTipo); public: void PutCoord(int iPosX, int iPosY); }; mouse.cc #include "../hdrs/mouse.hh" #define _POSXINI _MAXROW >> 1 #define _POSYINI _MAXCOLUMN >> 1 // Funciones privadas a la clase cMouse void cMouse::MsjEvento(cEvento *EvTipo) { } // Funciones públicas a la clase cMouse void cMouse::PutCoord(int iPosX, int iPosY) { } Todo esto es un sencillo ejemplo, aunque faltan muchas cosas, y la más importante es comentar, según el modelo seguido en el apartado anterior. Aquí se pueden ver declaraciones globales (_MAXROW y _MAXCOLUMN), clases globales (cMouse) y obtención de datos de otras librerías o módulos (eventos.hh). Aquí se ve la verdadera utilidad de los ficheros .hh y .cc, obtenemos el fichero de cabecera de eventos.hh, pero no se vuelven a definir las funciones, si introdujesemos en los .hh todo, al llamarlo desde otro módulo se volvería a generar todo el código dentro de este, así, como hemos explicado antes solamente se compilaría el código en una zona de memoria y se iría a él cada vez que hubiese una llamada a una función de dicho módulo. Además también pueden verse declaraciones privadas (_POSYINI, _MAXCOLUMN). Dentro de la clase, aunque esté definida en .hh, también existirán partes privadas (iPosX, iPosY, ..., MsjEvento()), y partes públicas (PutCoord()), o accesibles. 4.3. Declaraciones Las declaraciones de variables constantes, creadas con #define, para diferenciarlas de otros tipos de estructuras y de variables deberán ser en mayúsculas, pudiendo ser precedidas del signo de subrayado. Las declaraciones de variables normales, creadas con int, char, ..., deberán tener en el nombre de la variable la primera letra del tipo de dato que representan, es decir, como vimos en el ejemplo anterior, int iPosX y char cBotD. De esta forma sabremos en todo momento que tipo de dato estamos tratando, sin necesidad de ir donde se encuentra su declaración. Las funciones deberán tener la primera letra de cada palabra de que esté formado con mayusculas y el resto con minúsculas. Por ejemplo, PutCoord(). Así, por ejemplo, una referencia a esta función desde el exterior se haría: cMouse.PutCoord(iNewPosX,_MAXCOLUMN). Por lo que sabemos que cMouse es una clase, GetCoord es una función, iNewPosX es una variable definida como entera con signo y _MAXCOLUMN es una constante definida con #define. Aquí se ha podido ver de una forma práctica el poder de utilización de éste tipo de gramática, ¿qué ocurriría si nos encontrásemos al revisar un módulo de otra persona? ... RAT.ponercordenada(dato,posmaxcol); Podría entenderse en un contexto reducido, pero ¿qué ocurrirá cuando tengamos más de 100.000 líneas de código y el módulo a revisar se haya hecho en 1994?. Espero que comprendáis la potencia de estas herramientas ... además a nadie le cuesta seguir estas indicaciones. 5. Control de versiones Pero no sólo es importante mantener un estándar en la creación de código, también es muy importante gestionar un poco todo el proceso de cambios de módulos ya creados. Podría darse el caso, que dos personas necesitasen modificar el mismo módulo, ambos lo cogen, modifican y entregan, pero si no existe un control, la entrega del segundo desarrollador pisará o borrará la entrega que ya hizo en su día el primero. ¿Cómo solucinar esto?. Normalmente, en los grandes proyectos, existen herramientas encargadas para ello e integradores encargados también para controlarlo, pero nuestro caso es muy diferente. El control de todos los ficheros lo deberá llevar el coordinardor de programación correspondiente, y si existiese algún módulo que se necesitase en varios departamentos, el control sobre dichos módulos o ficheros lo tendría que llevar el coordinador de proyectos. Su función o labor es muy simple, ellos mantendrán siempre los módulos o fuentes originales, cuando una persona necesite modificar algo se la pedirá al coordinador, el cuál a su vez deberá comprobar que dicho módulo no se encuentra en manos de otro desarrollador, de ser así tendría que denegar la entrega hasta que el desarrollador que posee el módulo lo entregue. Fácil, ¿no?. Ahora bien, ¿cómo realizar este control?. Se insertará en un fichero una asociación del módulo solicitado con la persona que lo solicitó. Así, solamente dicha persona podrá entregar el módulo modificado. Existe otra situación no contemplada hasta ahora. Consiste en que se debe garantizar el correcto funcionamiento de un módulo, para lo que se tienen que haber hecho unas pruebas unitarias previas. Normalmente, para poder realizar dichas pruebas, se van a necesitar muchos de los módulos creados, pero ¿qué ocurre si éste está ocupado?, pues muy fácil. Habrá dos tipos de solicitudes de módulos a los coordinadores, uno que ya hemos visto y que conlleva una modificación de éste, y otro que pasaremos a explicar ahora. Cuando alguien quiere un módulo símplemente para su consulta, visionado, prueba unitaria, etc, y éste no requiera una modificación se podrá solicitar también al coordinador, aunque éste no insertará su nombre en el fichero de control comentado anteriormente, por lo que dicho fichero sigue siendo accesible a modificaciones. Si por un casual, el fichero obtenido para consulta se necesitase modificar, se solicitaría una petición de bloqueo de éste, siempre y cuando no lo esté ya. Lo que tiene que quedar claro son dos cosas; un módulo o fichero fuente podrá ser consultado siempre por un desarrollador, pero para poder modificarlo se necesitará tener permiso del coordinador, el cuál pasará a estado de bloqueado (insertando los datos de quien lo hizo en un fichero) todos los fuentes solicitados. Algo muy importante es que el coordinador deberá revisar el código entregado, para de esta forma controlar (a fin de cuentas este es el objetivo) las modificaciones que se han hecho y si cumplen todas las condiciones expuestas en éste documento. Cuando se realiza una modificación se debe tener cuidado además de qué es lo que se borra o modifica (añadir no es ningún problema). Puede suceder que el desarrollador A utilice en uno de sus módulos una función, por ejemplo, del ratón, que luego el desarrollador B modifica o elimina. Para esto, siempre que un desarrollador modifique (esto no suele dar problemas) o elimine (auténtico problema) una función de una clase se deberá avisar a los desarrolladores. Pero, ¿Cómo?. Pues muy fácil, cuando el coordinador reciba la entrega y la haya comprobado, mandará un e-mail con un copy-paste de la zona de comentario de principio de fichero con la nueva revisión y la modificación o eliminación realizada, no aprobando dicha entrega (tenerla pero no hacerla oficial), hasta que todos los desarrolladores den su aprobación (modificando funciones o fuentes donde apareciesen llamadas a dicha función). Realizar una modificación no suele dar problemas, ya que si tenemos una función que devuelve el pixel situado en unas coordenadas, aunque se modifique el código, se seguirá haciendo lo mismo. El problema viene a la hora de eliminar funciones, para ésto se debe informar a todos los desarrolladores antes incluso de su entrega, aunque el coordinador siempre solicitará una confirmación de todos éstos. Aunque parezca tedioso, es muy importante y no da mucho trabajo, porque realmente sólo es en situaciones de grandes cambios o extremas, cuando se borran funciones, estructuras, etc ... (Por ejemplo, un cambio de la versión 1.0 a la 2.0, donde se cambie todo un sistema de tratamiento de ventanas, eventos, etc ...). El coordinador tendrá el deber de controlar todo el proyecto, así como guardarlo bajo una estructura completamente jerárquica y coerente que facilite la búsqueda de ficheros. Además de realizar una copia de seguridad cada día, semana o mes, dependiendo de lo que se decida en las reuniones de coordinadores. 5.1. Implementación Devido al principal inconveniente que se nos presenta a la hora de desarrollar una aplicación sin equipos preparados, la distancia, nos vemos obligados a establecer un control de revisiones y versiones de fuentes apoyado en las direcciones ftp, con ayuda del e-mail para establecer controles. Empezaremos comentando el trabajo de las diferentes personas, primero nos encontramos con los desarrolladores. Su principal comentido es el de programar el video-juego, dirigidos todos ellos por un coordinador del que hablaremos más adelante. Los desarrolladores deben disponer en todo momento de los fuentes, ya que realmente es su trabajo; ver, modificar, compilar, realizar pruebas unitarias, etc ... Todo esto necesita de los fuentes, por lo que no se puede negar a un programador un módulo que solicite, aunque éste se encuentre bloqueado por otro programador. El coordinardor será a la vez administrador e integrador de la aplicación que se está creando. Como el principal objetivo del coordinador es eso, coordinar y no programar (aunque no quita que lo haga), deberá encargarse de supervisar como se está llevando a cabo todo el proceso; compilando la aplicación en general, probandola, revisando el código en caso de error o de que se encontrase algo fuera de lo común, realizar backups de su departamento, controlando la petición de bloqueos y de módulos, etc ... Como se ve su importancia es mucho mayor para lo que la aplicación se refiere de lo que parece en un principio. Por último, se encuentra el coordinador del proyecto (que en este caso es igual que el coordinador general). Su función será la de dirigir todos los grupos y coordinar a los diferentes responsables de los distintos departamentos. Así entre las obligaciones del coordinador de proyecto se encontraría; realizar backup de toda la aplicación, hacer pruebas globales (junto con gráficos y sonido), ofrecer ficheros entre los distintos departamentos (puede ocurrir que un desarrollador solicite un fichero de gráficos para realizar su prueba unitaria), establecer tiempos de presentación, etc ... (al igual que en el caso del coordinador de programación no quita que éste coordinador participe en el proyecto con sus conocimientos en cualquier departamento que controla). Lo único que no haría con respecto a un coordinador de departamento, sería el control de ficheros, ya que el paso de ficheros de un departamento a otro no es para modificación, sino para consulta, lo que no da lugar a conflictos entre revisiones y versiones. El paso de ficheros interdepartamental puede llevarse a cabo, saliendose de lo planteado, unicamente a través de los coordinadores de departamentos, saltandose el paso burocrático del coordinador general y liberandole de dicha responsabilidad. Aunque para poder hacer esto deberá autorizarlo expresamente el coordinador del proyecto. Debido a las características de cada una de las personas involucradas en el proyecto se ha optado por: * Se creará un directorio que podrá subdividirse en más según lo necesite el módulo. Su estructura será de forma jerárquica, en la que el directorio raiz será un fichero denominado prTaiKai (para el caso de ésta aplicación), seguido de una serie de subdirectorios correspondientes a cada uno de los módulos (mouse, sonido, etc ...), los cuales a su vez pueden estar subdivididos en más directorios (por ejemplo, del directorio sonido podría salir; sblaster, gravis, ...). * Este directorio conservará su estructura tanto en el backup, como en el directorio del coordinador de proyecto, como en el de coordinador de departamento y, por supuesto, en la dirección ftp. * Para ayudar a los desarrolladores, se debería conservar esta estructura en todos los demás departamentos; por ejemplo, grTaiKai, sdTaiKai, etc ... * Cuando se vaya a realizar la prueba global se deberá reorganizar todos los ficheros necesarios, ya que no se conservarán (nunca se hace) los mismos directorios durante la creación del video-juego, que durante la venta del producto. * En la dirección ftp se guardará siempre una copia correcta y actualizada, es decir, no se establecerán entregas directamente sobre dicha zona, sino que cada cierto tiempo el coordinador de departamento, una vez comprobado que todo está bien y que la compilación se realizó sin ningún tipo de error, realizará un volcado con los nuevos ficheros a dicha zona. Permaneciendo intacta hasta la siguiente compilació correcta. Se recomienda realizar el volcado, como mínimo una vez cada semana. * Lo ideal sería que sólo los responsables situados por encima del coordinador del departamento tuviesen permiso de escritura y de lectura sobre la zona del ftp, restringiendo únicamente a la lectura de éstos a los desarrolladores. Así evitariamos males entedidos, errores, etc ... * Los desarrolladores para poder realizar una entrega deben tener el fichero bloqueado. Para saber si un fichero se encuentra bloqueado éstos deberán consultar el fichero bloqueos.doc, que se encuentra tanto en el ftp como en el directorio del coordinador del departamento de desarrollo. El cuál deberá ser actualizado cada vez que se produzca un cambio (como mínimo una vez al día, siempre que se vaya a modificar claro). * El coordinador de programación deberá enviar un mail a todos los desarrolladores y al coordinador de proyecto justo antes de realizar el volcado a ftp y una vez se termine de hacer. De esta forma se intenta prevenir cualquier problema que pueda surgir durante el volcado. * Cuando el coordinador de proyecto reciba el mail del de programación, éste deberá copiarse en su directorio toda la nueva estructura, modificando la antigua. Para de esta forma tener más seguro y protegido el código que se realiza, ante cualquier problema que puediese surgir. * Cuando un desarrollador quiera bajarse un fichero de ftp, simplemente se tendrá que conectar y cogerlo, no necesita del permiso de nadie. Sólo necesita el permiso del coordinador de programación para entregar los fichero y que éstos sean aceptados (si los bloqueos se hicieron bien, el código enviado parece seguro, etc ...). * Al entregar un fichero el coordinador de programación, siempre que lo apruebe, lo copiará en el directorio correspondiente, esperando más entregas. Cuando sea preciso (normalmente se establece un día de la semana o cuando ocurre un cambio importante que puede afectar a muchos desarrolladores) se realizará la compilación y el volcado, con los consiguientes avisos a los desarrolladores y coordinador de proyecto. Además deberá actualizar el fichero bloqueos.doc, el cuál se copiará o sustituirá en el ftp sin previo aviso, de esta forma se garantiza el control de los ficheros. * Si un desarrollador quiere entregar un fichero se deberá bloquear primero, como dijimos antes, pero además, antes de esto, deberá ver si en el fichero bloqueos.doc del ftp no se encuentra bloqueado. Este paso permite liberar de carga de correo a los diferentes componentes del departamento. * Bueno, y si no está bloqueado, ¿cómo se bloquea?. Muy fácil, el bloqueo se solicitará a través de un e-mail codificado, el cual se explica más adelante junto con todas las variantes posibles. El código de este mail será: [bloq:] * Una vez bloqueado, puede suceder, que el desarrollador no quiera modificarlo, por lo que no necesita entregarlo, para eso existe otro mail, cuyo código es [ublq:] * Al igual que para bloquear y desbloquear ficheros, se dispone de [entr:] y de [rech:]. Estos se envían por el desarrollador (para entregar) y por el coordinador de programación (para rechazar) respectivamente. * El desarrollador NO deberá borrar los ficheros entregados hasta que no confirme su existencia en el ftp, y aunque lo confirme puede no hacerlo. Existen, de momento, cuatro tipos de mails, que son los siguientes: Mail para bloqueos: TO: prCoord_TK SUBJ: [bloq:TaiKai] CONT: Una línea con el código [bloq] al comienzo, por cada fichero a bloquear. Mail para desbloqueos: TO: prCoord_TK SUBJ: [ublq:TaiKai] CONT: Una línea con el código [ublq] al comienzo, por cada desbloqueo. Mail para entregas: TO: prCoord_TK SUBJ: [entr:TaiKai] CONT: Una línea con el código [entr] al comienzo, por cada fichero a entregar. ATTACH: Ficheros fuente a entregar. Mail para rechazos: TO: DesarrolladorX SUB: [rech:TaiKai] CONT: Explicación de porqué se rechazó (no bloqueada, errores, no compila, ...) FORWARD: Del mail [entr:TaiKai] entregado. El formato del fichero bloqueos.doc, estará formado por líneas en código ASCII, terminadas por un retorno de carro y fin de línea. Se compondrá de 3 campos, de la siguiente manera: ::<\ruta\fichero_bloq>[CRLF]