Hay un refrán que dice "en casa del herrero cuchillo de palo", lo cuál es bastante cierto si hablamos de informática. Parece que los ingenierillos disfrutan haciendo trabajo de monos espaciales. Se enciende una luz y tiras de una palanca. Repítelo un millón de veces y tendrás a un especialista en ingeniería del software.
Con la ingeniería del software me pasa lo mismo que con el comunismo. Las dos cosas me gustan, pero no puedo decir lo mismo de los ingenieros del software y los comunistas, que suelen ser gilipollas.
Vayamos al meollo de la cuestión. En las asignaturas de "injenierida del chofgüer" y derivadas parece que son asignaturas en las que enseñan a manejar el "Guord", a poner bien de colorines el documento, a hacerte unos encabezados muy chulos, a hacer un montón de fichas en tablitas para requisitos y componentes... y los alumnos, en cuanto tienen que pensar un poco, se quedan pasmados con el dedo en la nariz (ver diagrama:
)
y repiten como buenos simios amaestrados que son. Los más afortunados recibirán su plátano, trabajarán de consultores ganando una pasta y se sentirán dichosos de haber triunfado en la vida. Los menos, acabarán con estos jefes.
Siempre he pensado que la informática se creó con los siguientes objetivos:
- Automatizar tareas.
- Asistir en la resolución de problemas.
- Almacenar datos.
Luego vino el ocio, la multimierda y tal, pero eso ya es harina de otro costal y se me escapa un poco del tema... hmmmm... no, ya me he escapado, voy a intentar volver a lo que tenía en la cabeza desde un principio.
Estaba intentando describir cómo para la última práctica de la carrera (Sistemas Informáticos) nos hemos desviado un poco de las típicas chapuzas artesanales y hemos automatizado los procesos de documentación todo lo que hemos podido (se podría haber hecho más, pero hay que encontrar un equilibrio entre el tiempo que empleas en mejorar los procesos y el tiempo que te ahorras con los procesos mejorados); con el fin de poder recurrir aquí cuando quiera repetir y de paso que cualquier otro se pueda subir al carro de los elegidos.
Empecemos enumerando los requisitos necesarios para montar el sistema:
- Servidor unix (o windows con cygwin) conectado a la red.
- cvs
- ssh
- make
- openjade (y todas las utilidades para docbook)
- ghostscript
- xmllint
- python
- Clientes
- edición xml (posibles alternativas)
- jedit + plugin xml (recomendada)
- vex (algo wysiwyg, pero todavía incompleto... como ventaja se puede incluir como workspace en eclipse).
- kxml (no está mal para ver la estructura, pero pesado para editar)
- emacs + sgml mode (un clásico que nunca falla)
- cliente cvs (posibles alternativas)
- cvs a pelo (algo coñazo, pero efectivo y disponible en casi todas partes)
- tortoise cvs (cómodo y divertido, para windows)
- eclipse (es lo más cómodo si ya lo usas para desarrollar y editar xml)
- hoja de cálculo
- oocalc (recomendada, porque exporta como queremos)
- gnumeric (copy & paste a un vi o emacs para exportar)
- excel (copy & paste a un notepad para exportar)
- Montar las cuentas de usuarios
- Montar un repositorio CVS:
- entrar en el directorio que queramos tener como repositorio y ejecutar el comando "cvs init" (un sitio típico es "/var/cvs", aunque puede estar en el home de una cuenta especial para el proyecto, a la que tienen permiso de acceso, lectura y escritura los miembros del grupo)
- crear un módulo para la documentación (la manera más fácil es hacerlo con el asistente del eclipse, en el menú contextual sobre un proyecto "team > share project", o en la línea de comandos con "cvs import nombre-modulo grupo version")
- Crear uno directorio para cada grupo de:
- Documentos
- Imágenes compartidas (logotipos, etc.)
- Plantillas comunes
- Crear un directorio para el primer documento (bajo el de documentos):
- Crear un Makefile (que luego explicaremos qué tiene).
- Subdirectorio para las imágenes propias del documento.
- Subdirectorio para los requisitos, con sus scripts y más cosas (luego lo explicamos).
- Documentos xml para cada capítulo ó sección (con el grano todo lo fino que queramos) y un documento maestro (también explicamos cómo funciona ahora).
Ahora vamos a hablar un poco más detalladamente de cada tipo de archivo.
workspace/ssii_docs/
|-- CVS #esto es información del cvs, los siguientes están abrevidados
| |-- Entries
| |-- Repository
| |-- Root
| `-- Template
|-- diagramas #diagramas del rational y otros dibujitos
| |-- Bender.emx
| |-- CVS
| |-- Disenyo.mdx
| |-- Disenyo.wdx
| |-- Disenyo5EC87526B7F54B30B9A09AFCE8E3EBA7.idx
| |-- Mermelada.mdx
| |-- Mermelada.wdx
| |-- build.xml
| |-- disenyo1037AB48F0554ECA9D513EDDDE78C57A.idx
| |-- instalacion.svg
| `-- sensor_tapon.svg
|-- documentos
| |-- CVS
| |-- anteproyecto #el anteproyecto, abarcará URD y SRD
| | |-- CVS
| | |-- Makefile #fantástico makefile
| | |-- anteproyecto.xml #documento maestro
| | |-- anteproyecto_final.pdf #el resultado final
| | |-- anteproyecto_final.ps #un resultado intermedio
| | |-- anteproyecto_final.xml #un resultado intermedio
| | |-- chap_descripcion_modelo_logico.xml #los siguientes chap*.xml son capítulos
| | |-- chap_disenno_arquitectonico.xml
| | |-- chap_estimacion.xml
| | |-- chap_introduccion.xml
| | |-- chap_maquinas_estados.xml
| | |-- chap_planificacion.xml
| | |-- chap_plano_instalacion.xml
| | |-- chap_presupuesto.xml
| | |-- chap_pruebas.xml
| | |-- chap_requisitos_software.xml
| | |-- chap_requisitos_usuario.xml
| | |-- chap_resumen.xml
| | |-- cocomo #informes del cocomo
| | | |-- CVS
| | | |-- cocomo-report.rpt
| | | `-- cocomo.est
| | |-- images #gráficos para incrustar (*.ps y *.eps)
| | | |-- CVS
| | | |-- Mermelada__Arrancar__Actividad__Arrancar.ps
| | | |-- Mermelada__Arrancar__Secuencia__InteractionInstance1__Arrancar.ps
| | | |-- Mermelada__Casos_uso.ps
| | | |-- Mermelada__Clases_analisis.ps
| | | |-- Mermelada__Configurar__Actividad__Configurar.ps
| | | |-- Mermelada__Configurar__Secuencia__InteractionInstance1__Configurar.ps
| | | |-- Mermelada__Despliegue.ps
| | | |-- Mermelada__Emergencia__Actividad__Emergencia.ps
| | | |-- Mermelada__Emergencia__Secuencia__InteractionInstance1__Emergencia.ps
| | | |-- Mermelada__Generar_informes__Actividad__Generar_informes.ps
| | | |-- Mermelada__Generar_informes__Secuencia__InteractionInstance1__Generar_informes.ps
| | | |-- Mermelada__Parar__Actividad__Parar.ps
| | | |-- Mermelada__Parar__Secuencia__InteractionInstance1__Parar.ps
| | | |-- Mermelada__esclavo 1__estados.ps
| | | |-- Mermelada__esclavo2__estados.ps
| | | |-- Mermelada__maestro__estados.ps
| | | |-- bender.eps
| | | |-- cocomo.eps
| | | |-- costes-proyecto.eps
| | | |-- costos-proyecto.pdf
| | | |-- esclavo1.eps
| | | |-- esclavo2.eps
| | | |-- instalacion.ps
| | | |-- maestro.eps
| | | |-- planificacion.ps
| | | |-- sensor_tapon.ps
| | | `-- vaf.eps
| | |-- presupuesto #una simple hoja de cálculo para trabajar con ella
| | | |-- CVS
| | | `-- hardware.ods
| | |-- pruebas_aceptacion #cositas para las pruebas
| | | |-- CVS
| | | |-- hoja_pruebas_aceptacion.csv #el fichero que se procesa, derivado del excel
| | | |-- hoja_pruebas_aceptacion.excel.xml #fichero de excel para trabajar
| | | |-- procesar_pruebas.py #script que procesa el csv y lo transforma en xml docbook
| | | `-- pruebas_aceptacion.docbook.xml #fragmento de docbook
| | `-- requisitos #los requisitos de usuario y del software
| | |-- CVS
| | |-- README.TXT #instrucciones para usarlos
| | |-- hoja_requisitos.csv #fichero para procesar, derivado del xls
| | |-- hoja_requisitos.xls #fichero de excel, para trabajar
| | |-- matriz-d-sr-ur.docbook.xml #matriz de trazabilidad, derivada del script
| | |-- matriz-i-sr-ur.docbook.xml #matriz de trazabilidad, derivada del script
| | |-- matriz.py #módulo genérico para las matrices de trazabilidad
| | |-- matriz.pyc #bytecode de python
| | |-- procesar_lista_requisitos.py #script que genera listas de requisitos
| | |-- procesar_matriz_directa.py #script que genera una matriz de trazabilidad directa
| | |-- procesar_matriz_inversa.py #script que genera una matriz de trazabilidad inversa
| | |-- requisitos-sr.docbook.xml #fragmento docbook, derivado
| | |-- requisitos-ur.docbook.xml #fragmento docbook, derivado
| | |-- requisitos.py #modulo generico para los requisitos
| | |-- requisitos.pyc #bytecode de python
| | `-- urd.xml #fragmento de docbook, que incrusta los *.docbook.xml
| |-- disenyo #otro documento, más de lo mismo
| | |-- CVS
| | |-- Makefile
| | |-- chap_contexto.xml
| | |-- chap_descripcion.xml
| | |-- chap_descripcion_completo.xml
| | |-- chap_disenyo.xml
| | |-- chap_estandares.xml
| | |-- chap_introduccion.xml
| | |-- chap_viabilidad.xml
| | |-- chap_vision_sistema.xml
| | |-- componentes #descripción detallada de los componentes software
| | | |-- CVS
| | | |-- matriz-trazabilidad.docbook.xml #derivado
| | | |-- modelo_componentes.xls
| | | |-- modulo_automatas #una carpetita para modulito
| | | | |-- CVS
| | | | |-- especificacion-componentes.docbook.xml #fichero derivado del csv
| | | | |-- modelo_componentes.csv #csv exportado del xls
| | | | |-- modelo_componentes.xls #descripción de los componentes
| | | | `-- pseudocodigo #pseudocódigo de los componentes
| | | | |-- CVS
| | | | |-- TODO
| | | | |-- comp_AUT-003.txt
| | | | |-- comp_AUT-004.txt
| | | | |-- comp_AUT-005.txt
| | | | |-- ... #muchos más
| | | | `-- comp_AUT-059.txt
| | | |-- modulo_comunicaciones #otro modulito, igual que el anterior
| | | | |-- CVS
| | | | |-- especificacion-componentes.docbook.xml
| | | | |-- modelo_componentes.csv
| | | | |-- modelo_componentes.xls
| | | | `-- pseudocodigo
| | | | |-- CVS
| | | | |-- comp_COM-003.txt
| | | | |-- comp_COM-004.txt
| | | | |-- ... #muuuuuuchos más
| | | | `-- comp_COM-100.txt
| | | |-- ... #un par de módulos más
| | | `-- scripts
| | | |-- CVS
| | | |-- modulos.py #modulo genérico para los módulos... vaya juego de palabras
| | | |-- modulos.pyc #bytecode de python
| | | |-- procesar_lista_modulos.py #genera la lista de los módulos de un componente
| | | `-- procesar_matriz_trazabilidad.py #genera las matrices de trazabilidad
| | |-- disenyo.xml #documento maestro
| | |-- disenyo_final.pdf #resultado final
| | |-- disenyo_final.ps #resultado intermedio
| | |-- disenyo_final.xml #resultado intermedio
| | `-- images #graficos para incrustar
| | |-- CVS
| | |-- Disenyo__Automatas__Main.eps
| | |-- Disenyo__Comunicaciones__Buzon__Main.eps
| | |-- Disenyo__Comunicaciones__Main.eps
| | |-- Disenyo__Comunicaciones__Mensajes__Main.eps
| | |-- Disenyo__GestorInformes__Main.eps
| | |-- Disenyo__Main.eps
| | |-- Disenyo__SCADA__Main.eps
| | |-- Mermelada__Automatas__Main.ps
| | |-- Mermelada__Comunicaciones__Buzon__Main.ps
| | |-- Mermelada__Comunicaciones__Main.ps
| | |-- Mermelada__Comunicaciones__Mensajes__Main.ps
| | |-- Mermelada__GestorInformes__Main.ps
| | |-- Mermelada__Main.ps
| | |-- Mermelada__SCADA__Main.ps
| | |-- bender.eps
| | `-- diagrama_contexto.ps
| |-- manual_usuario #el manual. estamos trabajando en él ahora mismo
| | |-- CVS
| | |-- Makefile
| | |-- images
| | | |-- CVS
| | | `-- bender.eps
| | `-- sum.xml
| `-- stylesheets #plantillas comunes (sólo se usa custom.dsl, las otras son de referencia)
| |-- CVS
| |-- cogent-both.dsl
| |-- custom.dsl
| |-- freebsd_tuned.dsl
| |-- gdp-both.dsl
| `-- guide.dsl
`-- plantillas_docbook #ejemplos de archivos docbook
|-- CVS
|-- Makefile #ejemplo de makefile
|-- articulo.xml #ejemplo de articulo, para los manuales
|-- chap1src.xml #ejemplo de capitulo, para incluir en documentos
|-- images #varios logos, para guarrear
| |-- CVS
| |-- logo.wmf
| |-- logotipo1.gif
|-- libro.xml #ejemplo de libro
|-- prueba.xml #no sé qué tenía este, creo que era un ejemplo de xinclude
`-- stylesheets
|-- CVS
|-- cogent-both.dsl
|-- custom.dsl
|-- gdp-both.dsl
`-- ldp.dsl
57 directories, 468 files
Los XML de DocBook
Para el que no conozca DocBook, habría que decir que es un lenguaje de marcas XML diseñado para escribir documentos estructurados. Los documentos estructurados son aquellos que tienen partes, capítulos, secciones, subsecciones, etc.La edición de estos documentos puede ser un tanto tediosa si se hace a mano sin ningún editor especializado (que nos ayude con las marcas), pero tiene la ventaja de que al ser texto plano (bueno, al ser XML no es plano, es un árbol :-P), lo cuál tiene algunas recompensas:
- Se puede gestionar directamente con un SCV, como CVS ó SVN, con lo cuál se mantiene un histórico de las revisiones, se puede volver a una versión anterior en el caso de fallo, se puede ver quién ha escrito cada cosa...
- Se pueden hacer fácilmente programas que escriban este tipo de documentos (lo cuál lo explotaremos bastante).
- Se puede editar en (casi) cualquier parte.
Nosotros también queremos tener documentos modulares, lo cuál lo conseguiremos con dos tecnologías: XInclude y las System Entities de XML.
XInclude
XInclude tiene una ventaja y un inconveniente principales. La ventaja es que permite hacer un pre-procesado de los documentos a incluir, como puede ser seleccionar una rama del XML concreta para incluir ó escapar los caracteres no válidos en un documento XML al incluir texto plano (como los > y los <, por ejemplo).El inconveniente es que el motor de render que usamos (Jade) no lo procesa correctamente (para los que usen XSL-FO no creo que tengan este problema, pero yo ya había apostado por Jade, ¡y uno no aprende DSSSL para luego cambiarse!).
Para solucionar el problema de procesamiento, optamos por hacer un pre-procesado de los documentos con una herramienta externa, en este caso xmllint.
System Entities
Es un mecanismo bastante más sencillo que el XInclude, ya que simplemente vuelva el contenido del fichero incluido en el maestro, lo cuál tiene el problema de que por lo general, los documentos que incluyamos no serán de por sí documentos DocBook válidos (por las cabeceras y tal) y no serán reconocidos como tal por los editores XML.Esta característica nos viene muy bien para incluir los cachos de DocBook generados por nuestros programas, ya que en ellos no querremos perder tiempo declarando cabeceras, ni puede que sepamos de antemano en qué rama estarán metidos.
Gráficos
Como habréis podido observar, los gráficos están en formato PS ó EPS, que son formatos de gráficos vectoriales, lo cuál nos vendrá bien para que los diagramas no pierdan calidad en los documentos.El problema que tienen estos gráficos es que están definidos en un lenguaje de programación de impresoras (que por cierto, es muy divertido aprenderlo, yo lo estoy haciendo) y no hay programas para editarlos directamente... pero por suerte, desde (casi) cualquier programa se puede exportar a PostScript, si bien no directamente, sí mediante la opción de imprimir a un archivo (habiendo instalado los drivers de una impresora PostScript, como los de casi cualquier impresora Láser).
Un pequeño escollo con el que nos encontramos aquí es que al generar los PDF's a partir de DocBook con Jade, nos dice que no le gustan los ficheros PS ni EPS. La solución es crear un PS con Jade y luego convertirlo a PDF con ps2pdf.
Las hojas de cálculo XLS y los CSV
Las hojas de cálculo son para editar registros de formato fijo, como son las típicas plantillas de requisitos y módulos de sofware. Con un poco de arte, se pueden automatizar varias cosillas, como la numeración automática, la selección de enumerados, etc.Aquí os pongo un par de pantallazos para que veáis de qué hablo:
El problema de usar los XLS es que son ficheros binarios y no se llevan muy bien con el CVS, así que si usáis Excel (a partir del 2003, creo), podéis guardarlos en el XML ese guarruzo de Microsoft. Si usáis OpenOffice, podéis seguir el tutorial de Pesso para guardar los documentos ODF en texto plano que enlazaré en cuanto esté listo. Si usáis Gnumeric, sólo tenéis que ir a preferencias, y especificar que el nivel de compresión de los archivos es 0.
Los CSV tienen algunas consideraciones especiales, para que puedan ser procesados más fácilmente:
- Usar el tabulador como separador.
- No usar delimitadores para el texto.
- Estar codificados en UTF-8
Los scripts en Python
Para los que no lo conozcan, Python es un lenguaje dinámico interpretado, que te permite hacer muchas guarrerías de forma elegante y rápida, por lo que resulta ideal para lo que queremos hacer aquí.Estos scripts también deberían estar codificados en UTF-8.
Estos scripts leeran los CSV y generarán cachos de DocBook a porrillo... como no hay mucho más que decir, aquí los pongo tal cual:
anteproyecto/requisitos/requisitos.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
"""Encapsula un requisito"""
class Requirement:
def __init__(self):
self.id = ""
self.type = ""
self.nid = -1
self.priority = ""
self.need = ""
self.stability = ""
self.source = ""
self.description = ""
self.verification = ""
self.dependencies = []
def __init__(self, line):
self.parse(line)
def parse(self, line):
tokens = line.strip().split("\t")
self.type = tokens[0]
self.nid = int(tokens[1])
self.id = tokens[2]
self.priority = tokens[3]
self.need = tokens[4]
self.stability = tokens[5]
self.source = tokens[6]
self.description = tokens[7]
self.verification = tokens[8]
self.dependencies = tokens[9:]
def printDocBookSheet(self):
print "<table id =\""+self.id+"\">"
print "<title>"+self.id+"</title>"
print "<tgroup cols=\"4\"><tbody>"
print "<row>"
print "<entry><emphasis role=\"strong\">Prioridad</emphasis></entry>"
print "<entry>", self.priority,"</entry>"
print "<entry><emphasis role=\"strong\">Necesidad</emphasis></entry>"
print "<entry>", self.need,"</entry>"
print "</row>"
print "<row>"
print "<entry><emphasis role=\"strong\">Estabilidad</emphasis></entry>"
print "<entry>", self.stability, "</entry>"
print "<entry><emphasis role=\"strong\">Fuente</emphasis></entry>"
print "<entry>", self.source, "</entry>"
print "</row>"
print "</tbody></tgroup>"
print "<tgroup cols=\"1\"><tbody>"
print "<row>"
print "<entry><emphasis role=\"strong\">Descripción</emphasis></entry>"
print "</row>"
print "<row>"
print "<entry>", self.description, "</entry>"
print "</row>"
print "<row><entry><emphasis role=\"strong\">Dependencias</emphasis></entry></row>"
print "<row><entry>"
for i in self.dependencies:
print "<link linkend=\"" +i+"\">", i, "</link>"
print "</entry></row>"
print "</tbody></tgroup>"
print "</table>"
def createRequirementsList():
reqs = []
headings = True
for line in sys.stdin.readlines():
if headings:
if line.startswith("\t"):
headings = False
else:
if not line.startswith("\t"):
r = Requirement(line)
reqs.append(r)
return reqs
anteproyecto/procesar_lista_requisitos.py
from requisitos import *
import sys
def main():
type = sys.argv[1]
reqs = createRequirementsList()
for r in reqs:
if r.type == type:
r.printDocBookSheet()
main()
anteproyecto/requisitos/matriz.py
from requisitos import *
def directTraceabilityMatrix(reqs, fromType, toType):
matrix = []
types = {}
for i in reqs:
types[i.id] = i.type
for i in reqs:
#si tenemos un requisito del tipo de partida
if i.type == fromType:
#cogemos las dependencias del tipo de destino
d = [j for j in i.dependencies if types[j] == toType]
matrix.append((i.id, d))
return matrix
def inverseTraceabilityMatrix(reqs, fromType, toType):
matrix = []
table = {}
types = {}
#inicializamos la tabla
for i in reqs:
if i.type == toType:
table[i.id] = []
for i in reqs:
types[i.id] = i.type
for i in reqs:
#si tenemos un requisito del tipo de destino
if i.type == fromType:
#miramos las dependencias del tipo de partida
for j in i.dependencies:
if types[j] == toType:
table[j].append(i.id)
#pasamos de la tabla a la lista
for i in table:
matrix.append((i, table[i]))
matrix.sort()
return matrix
def printTraceabilityMatrix(matrix, title):
print "<table>"
print "<title>", title, "</title>"
print "<tgroup cols = \"2\">"
print "<colspec colwidth=\"1*\"/>"
print "<colspec colwidth=\"4*\"/>"
print "<tbody>"
for i,j in matrix:
print "<row>"
print "<entry>", link(i), "</entry>"
print "<entry>"
for k in j:
print link(k)
print "</entry>"
print "</row>"
print "</tbody>"
print "</tgroup>"
print "</table>"
return
def link(r):
return "<link linkend=\""+r+"\">"+r+"</link>"
anteproyecto/requisitos/procesar_matriz_directa.py
from matriz import *
def main():
fromType = sys.argv[1]
toType = sys.argv[2]
title = sys.argv[3]
reqs = createRequirementsList()
matrix = directTraceabilityMatrix(reqs, fromType, toType)
printTraceabilityMatrix(matrix, title)
main()
anteproyecto/requisitos/procesar_matriz_inversa.py
from matriz import *
def main():
fromType = sys.argv[1]
toType = sys.argv[2]
title = sys.argv[3]
reqs = createRequirementsList()
matrix = inverseTraceabilityMatrix(reqs, fromType, toType)
printTraceabilityMatrix(matrix, title)
main()
Makefile (juntándolo todo)
Si alguna vez has utilizado "make", seguramente ya tendrás una idea de cómo funcionan los Makefiles, pero por si acaso, primero haré una breve introducción.La herramienta make sirve para gestionar dependencias en proyectos, por lo que normalmente se asocia con programas en C (para no tener que compilar módulos que no han sido modificados), pero se puede usar para automatizar casi cualquier proceso de flujo de datos.
Los ficheros Makefile están formados por una lista de reglas, que están separadas entre sí por una o más líneas en blanco. Las reglas tienen 3 partes:
- Objetivo (nombre del fichero a actualizar o de la regla)
- Dependencias (otras reglas o nombres de ficheros de los que dependa el objetivo)
- Acciones (comandos que se ejecutan para crear o actualizar el objetivo)
objetivo : dep1 dep2 dep3 #y más... a partir de la almohadilla va comentado
accion1
accion2
#y más...
Ahora aquí van los Makefiles que hemos usado:
anteproyecto/Makefile
NAME = anteproyecto
FLAGS = --dcl `if test -e /usr/share/sgml/xml.dcl ;then echo /usr/share/sgml/xml.dcl; else locate xml.dcl | tail -n1; fi`
STYLESHEET = ../stylesheets/custom.dsl
MOD_REQ = requisitos/requisitos.py
MOD_MAT = requisitos/matriz.py
PROC_LIST_REQ = requisitos/procesar_lista_requisitos.py
PROC_MAT_D_REQ = requisitos/procesar_matriz_directa.py
PROC_MAT_I_REQ = requisitos/procesar_matriz_inversa.py
HOJA_REQUISITOS = requisitos/hoja_requisitos.csv
MATRIZ_D_SR_UR = requisitos/matriz-d-sr-ur.docbook.xml
MATRIZ_I_SR_UR = requisitos/matriz-i-sr-ur.docbook.xml
all: pdf view
view:
xpdf $(NAME)_final.pdf || evince $(NAME)_final.pdf || acroread $(NAME)_final.pdf
pdf: $(NAME)_final.pdf
html: $(NAME)_final.xml $(STYLESHEET)
db2html $(FLAGS) $(NAME)_final.xml
cp -r images $(NAME)_final
$(NAME)_final.pdf: $(NAME)_final.ps
ps2pdf $<
$(NAME)_final.ps: $(STYLESHEET) $(NAME)_final.xml ../images/* images/*
db2ps $(FLAGS) -d $(STYLESHEET) $(NAME)_final.xml
$(NAME)_final.xml: $(NAME).xml chap*.xml requisitos matrices pruebas cocomo/*
xmllint --noent --encode "iso-8859-1" --xinclude $(NAME).xml > $@
#REQUISITOS
requisitos: requisitos/requisitos-ur.docbook.xml requisitos/requisitos-sr.docbook.xml
requisitos/hoja_requisitos.csv: requisitos/hoja_requisitos.xls
echo $@ : HAY QUE ACTUALIZAR EL CSV A MANO!!!
false
requisitos/requisitos-ur.docbook.xml: requisitos/hoja_requisitos.csv $(PROC_LIST_REQ)
cat $< | python $(PROC_LIST_REQ) UR > $@
requisitos/requisitos-sr.docbook.xml: requisitos/hoja_requisitos.csv $(PROC_LIST_REQ)
cat $< | python $(PROC_LIST_REQ) SR > $@
#MATRICES REQUISITOS
matrices: $(MATRIZ_D_SR_UR) $(MATRIZ_I_SR_UR)
$(MATRIZ_D_SR_UR): $(HOJA_REQUISITOS) $(PROC_MAT_D_REQ) $(MOD_REQ) $(MOD_MAT)
cat $< | python $(PROC_MAT_D_REQ) SR UR "Matriz de dependencias directas SR-UR" > $@
$(MATRIZ_I_SR_UR): $(HOJA_REQUISITOS) $(PROC_MAT_I_REQ) $(MOD_REQ) $(MOD_MAT)
cat $< | python $(PROC_MAT_I_REQ) SR UR "Matriz de dependencias inversas SR-UR" > $@
#PRUEBAS ACEPTACION
pruebas: pruebas_aceptacion/pruebas_aceptacion.docbook.xml
pruebas_aceptacion/hoja_pruebas_aceptacion.csv: pruebas_aceptacion/hoja_pruebas_aceptacion.excel.xml
echo $@ : HAY QUE ACTUALIZAR EL CSV A MANO!!!
false
pruebas_aceptacion/pruebas_aceptacion.docbook.xml: pruebas_aceptacion/hoja_pruebas_aceptacion.csv pruebas_aceptacion/procesar_pruebas.py
cat $< | python pruebas_aceptacion/procesar_pruebas.py PA > $@
#PRESUPUESTO
#CLEAN
clean:
rm -rf $(NAME)_final || true
rm -rf $(NAME)_final.junk || true
rm $(NAME)_final.xml || true
rm *.tex *.aux *.dvi *.log *.out *.ps *.pdf || true
rm requisitos/requisitos-??.docbook.xml || true
rm requisitos/matriz-?-??-??.docbook.xml || true
rm pruebas_aceptacion/pruebas_aceptacion.docbook.xml || true
disenyo/Makefile
NAME = disenyo
FLAGS = --dcl `if test -e /usr/share/sgml/xml.dcl ;then echo /usr/share/sgml/xml.dcl; else locate xml.dcl | tail -n1; fi`
STYLESHEET = ../stylesheets/custom.dsl
HOJA_AUT = componentes/modulo_automatas
HOJA_GEI = componentes/modulo_gestor_informes
HOJA_GUI = componentes/modulo_gui
HOJA_COM = componentes/modulo_comunicaciones
SCRIPT_COMPONTENTES = componentes/scripts/procesar_lista_modulos.py
SCRIPT_MATRIZ = componentes/scripts/procesar_matriz_trazabilidad.py
all: pdf view componentes
view:
xpdf $(NAME)_final.pdf || evince $(NAME)_final.pdf || acroread $(NAME)_final.pdf
pdf: $(NAME)_final.pdf
html: $(NAME)_final.xml $(STYLESHEET)
db2html $(FLAGS) $(NAME)_final.xml
cp -r images $(NAME)_final
$(NAME)_final.pdf: $(NAME)_final.ps
ps2pdf $<
$(NAME)_final.ps: $(STYLESHEET) $(NAME)_final.xml ../images/* images/*
db2ps $(FLAGS) -d $(STYLESHEET) $(NAME)_final.xml
preprocesado_xinclude_nivel2: chap_descripcion.xml
xmllint --noent --encode "iso-8859-1" --xinclude chap_descripcion.xml > chap_descripcion_completo.xml
$(NAME)_final.xml: $(NAME).xml chap*.xml matriz componentes preprocesado_xinclude_nivel2
xmllint --noent --encode "iso-8859-1" --xinclude $(NAME).xml > $@
#COMPONENTES
matriz:
python ${SCRIPT_MATRIZ} ${HOJA_AUT}/modelo_componentes.csv ${HOJA_COM}/modelo_componentes.csv ${HOJA_GEI}/modelo_componentes.csv ${HOJA_GUI}/modelo_componentes.csv > componentes/matriz-trazabilidad.docbook.xml
componentes: ${HOJA_AUT}/especificacion-componentes.docbook.xml ${HOJA_COM}/especificacion-componentes.docbook.xml ${HOJA_GEI}/especificacion-componentes.docbook.xml ${HOJA_GUI}/especificacion-componentes.docbook.xml
${HOJA_AUT}/modelo_componentes.csv: ${HOJA_AUT}/modelo_componentes.xls
echo $@ : HAY QUE ACTUALIZAR EL CSV ${HOJA_AUT} A MANO!!!
false
${HOJA_COM}/modelo_componentes.csv: ${HOJA_COM}/modelo_componentes.xls
echo $@ : HAY QUE ACTUALIZAR EL CSV ${HOJA_COM} A MANO!!!
false
${HOJA_GEI}/modelo_componentes.csv: ${HOJA_GEI}/modelo_componentes.xls
echo $@ : HAY QUE ACTUALIZAR EL CSV ${HOJA_GEI} A MANO!!!
false
${HOJA_GUI}/modelo_componentes.csv: ${HOJA_GUI}/modelo_componentes.xls
echo $@ : HAY QUE ACTUALIZAR EL CSV ${HOJA_GUI} A MANO!!!
false
${HOJA_AUT}/especificacion-componentes.docbook.xml: ${HOJA_AUT}/modelo_componentes.csv $(SCRIPT_COMPONTENTES)
cat $< | python $(SCRIPT_COMPONTENTES) ${HOJA_AUT}/pseudocodigo < ${HOJA_AUT}/modelo_componentes.csv > $@
${HOJA_COM}/especificacion-componentes.docbook.xml: ${HOJA_COM}/modelo_componentes.csv $(SCRIPT_COMPONTENTES)
cat $< | python $(SCRIPT_COMPONTENTES) ${HOJA_COM}/pseudocodigo < ${HOJA_COM}/modelo_componentes.csv > $@
${HOJA_GEI}/especificacion-componentes.docbook.xml: ${HOJA_GEI}/modelo_componentes.csv $(SCRIPT_COMPONTENTES)
cat $< | python $(SCRIPT_COMPONTENTES) ${HOJA_GEI}/pseudocodigo < ${HOJA_GEI}/modelo_componentes.csv > $@
${HOJA_GUI}/especificacion-componentes.docbook.xml: ${HOJA_GUI}/modelo_componentes.csv $(SCRIPT_COMPONTENTES)
cat $< | python $(SCRIPT_COMPONTENTES) ${HOJA_GUI}/pseudocodigo < ${HOJA_GUI}/modelo_componentes.csv > $@
#CLEAN
clean:
rm `find componentes -name "*.docbook.xml"` || true
rm -rf $(NAME)_final || true
rm -rf $(NAME)_final.junk || true
rm $(NAME)_final.xml || true
rm *.tex *.aux *.dvi *.log *.out *.ps *.pdf || true
Bueno, pues hasta aquí hemos llegado, que ya estoy hasta los cojones de escribir... si encuentro algún josting de archivos chulo, cuelgo un tbz con todo (o si alguien lo quiere, que me mande un mail a fortranito arroba gmail punto com).
Y recordad: ¡make es vuestro amigo!