De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Francisco José Alonso Ares
Data de Publicação: 07 de August de 2008
O subversion tem uma opção que permite a execução de qualquer programa em algumas etapas de seu trabalho de versionamento. São chamados "hooks", tem nomes padronizados para cada função disponível e devem ser instalados no diretório de mesmo nome dentro do repositório usado, ou seja:
/caminho/para/seu/repositório/hooks
Apesar de seu poder, o subversion sozinho não faz o gerenciamento de configuração de um software, apenas o gerenciamento de versão - que já não é pouca coisa!
Para manter registro não apenas das versões de um software mas também das versões de suas dependências que estejam no mesmo repositório e ainda gerando automaticamente a documentação para cada nova versão atualizada, peguei umas idéias no manual do próprio subversion e do doxygen e bolei os scripts abaixo.
O primeiro é só um "wrapper" para o segundo, que pode ser colocado em outro diretório.
Este segundo script cria um diretório temporário no próprio servidor em que o seu repositório está rodando e faz um "checkout" do projeto que acabou de ter sua versão atualizada.
Como opção, ele verifica se existe um arquivo "geradoc*" (pode ser "geradoc.c", "geradoc.txt", qualquer coisa, até com comprimento nulo, basta ter a entrada); caso não exista, ele não faz mais nada, apenas limpa esse diretório temporário.
Caso o "geradoc*" exista, ele faz uma varredura nos arquivos *.c, *.h, *.cpp e *.hpp (outros podem ser adicionados livremente) em busca da diretiva "#include" que contenha uma referência a algum arquivo que esteja no formato abaixo:
#include "../projeto/arquivo"
onde o "projeto" deve estar sob versionamento do subversion.
Após a extração dessas informações, ele gera um arquivo "depend.c" com umas poucas linhas que serão aproveitadas pelo doxygen. Estas linhas contém o número de versão de cada linha "#include" encontrada que aponte para um projeto externo ao projeto atual.
A seguir, ele remove qualquer prévia existência de um arquivo de configuração do doxygen e o substitui por um padrão, editando apenas o nome do projeto para que o documento final receba o nome do projeto de forma adequada.
O segmento seguinte executa o doxygen, move a documentação em HTML para um diretório onde um apache está rodando, também faz as mesmas tarefas que o "make pdf" faria, ou seja, finaliza a geração da documentação em PDF, que é uma das configurações usadas neste arquivo de configuração padrão do doxygen, copia este PDF para um diretório determinado e o envia por e-mail para o usuário que fez a atualização da versão. Só faltou encriptar via GPG, mas isto fica para outra oportunidade ;)
De quebra, ainda tem mais dois scripts: um encontra a versão do arquivo sendo documentado pelo doxygen dentro do repositório para que esta apareça na documentação gerada e outro que faz este mesmo arquivo passar pelo "astyle" antes de ser documentado, portanto garantindo uma formatação padronizada.
Seguem os arquivos:
#!/bin/bash /bin/echo _ _ _ _ `/bin/date` $1 $2 >> /var/log/svn/commit.log r=`/usr/bin/svnlook dirs-changed /desenv/svnroot | /bin/sed -n 2p` if [ "a" == "a"$r ] then r=`/usr/bin/svnlook dirs-changed /desenv/svnroot | /bin/sed -n 1p` fi /caminho/para/o/segundo/script/postco $r $2 & exit 0
#!/bin/bash # evita que traduções afetem comandos de "strings" como o sed , o cut e o grep export LC_ALL="C" R="$1" #REV="$2" u=`/usr/bin/svn info file:///caminho/do/repositório/$R | /bin/grep Author | /bin/cut -d" " -f4` n=`/bin/cat /etc/postfix/aliases | /bin/grep $u | /bin/cut -f2` g=`/bin/cat /etc/hosts | grep $u | cut -d" " -f1` f="refman.pdf" t=`/bin/echo $R | /bin/cut -d"/" -f2` #cd /tmp/ #if [ -s post_commit ] #then # /bin/rm -fR post_commit #fi d=`/bin/tempfile -d /tmp/ -p postcommit` /bin/rm -f $d /bin/mkdir $d cd $d /bin/echo = = = = `/bin/date` $R $u $n $g $t $d>> /var/log/svn/commit.log /usr/bin/svn co file:///caminho/do/repositório/$R ./ > /dev/null if [ -f geradoc* ] then #código de verificação e documentação de dependências LC_ALL="C" touch depend.c echo "/*! " > depend.c echo " * \\file depend.c " >> depend.c echo " * \\author "$u >> depend.c echo " * \\brief Lista de dependências para controle de configuração." >> depend.c echo " *" >> depend.c for h in "*.c" "*.h" "*.cpp" "*.hpp" do for i in $h do if [ "$h" != "$i" ] then m=`/bin/tempfile -d /tmp/ -p postcommit` fgrep "#include \"" $i | grep [\/\\] | sed s#\\\\#\/#g > $m a=`cat $m` rm -f $m if [ "$a" != "" ] then for j in $a do if [ "$j" != "#include" ] then d=`echo $j | cut -d "\"" -f2` b=`basename $d` d=`echo $d | sed s/$b//` l=`echo $d | cut -d "/" -f2` k=`svn info file:///caminho/do/repositório/trunk/$l 2>/dev/null | grep "Changed Rev:" | cut -d " " -f4` if [ "$k" != "" ] then echo " * \""$i"\"" depende do projeto "\""`echo $j | cut -d "/" -f2`"\", que está na versão " $k >> depend.c else echo " * \""$i"\"" depende do projeto "\""`echo $j | cut -d "/" -f2`"\", <b>que não está no repositório! </b>" >> depend.c fi echo " *" >> depend.c fi done fi fi done done echo -e " */\n">> depend.c #fim do código de verificação e documentação de dependências if [ -f Doxyfile ] then /bin/rm -f Doxyfile fi /bin/cat /caminho/do/arquivo/padrão/Doxyfile.post_commit | /bin/sed -e s/ProjectName/$t/ -e "s%/post_commit_dir/%"`/bin/pwd`/"%" > ./Doxyfile /usr/bin/doxygen > /dev/null 2> /dev/null cd doc if [ -d html ] then if [ -d /var/www/localhost/htdocs/docs/$t ] then /bin/rm -fR /var/www/localhost/htdocs/docs/$t fi /bin/mkdir /var/www/localhost/htdocs/docs/$t cd html /bin/mv * /var/www/localhost/htdocs/docs/$t/ cd .. fi cd latex /usr/bin/pdflatex refman.tex > /dev/null 2> /dev/null /usr/bin/makeindex refman.idx > /dev/null 2> /dev/null /usr/bin/pdflatex refman.tex > /dev/null 2> /dev/null latex_count=5 E=0 while [ $E == 0 ] do /usr/bin/pdflatex refman.tex > /dev/null 2> /dev/null /bin/egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log E=$? if [ $E == 0 ] then latex_count=`expr $$latex_count - 1` if [ $latex_count == 0 ] then E=1 fi fi done /bin/cp refman.pdf ../.. /bin/mv refman.pdf /caminho/da/pasta/de/documentação/"$t"_"$2"_refman.pdf cd ../.. /usr/sbin/sendmail -f admin@srv.com.br -r admin@srv.com.br $n << EOF Bcc: Administrador <admin@srv.com.br> Subject: Projeto $1 na v$2 . From: "root @ desenv" <admin@srv.com.br> To: $u <$n> Reply-to: "root @ serv" <admin@srv.com.br> X-Mailer: postfix in $HOSTNAME Seu projeto $1 foi efetivado no repositorio na v$2 . Os documentos podem ser encontrados em: http://desenv/docs/$t O PDF se encontra na pasta "caminho da pasta de documentação" deste servidor e anexo a esta mensagem. -- servidor "desenv" `uuencode $f $f` EOF cd .. fi /bin/rm -fR $d
PROJECT_NAME = ProjectName PROJECT_NUMBER = OUTPUT_DIRECTORY = ./doc CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = Brazilian USE_WINDOWS_ENCODING = YES BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = YES INLINE_INHERITED_MEMB = YES FULL_PATH_NAMES = YES STRIP_FROM_PATH = /post_commit_dir/ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = YES INHERIT_DOCS = YES DISTRIBUTE_GROUP_DOC = NO SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = YES HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = YES CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = YES SORT_BY_SCOPE_NAME = YES GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = YES FILE_VERSION_FILTER = "/caminho/auxiliares/versionfilter.sh" QUIET = YES WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = INPUT = FILE_PATTERNS = *.c \ RECURSIVE = YES EXCLUDE = .* */teste/* EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = *.c="/caminho/auxiliares/beautyfier.sh" \ *.h="/caminho/auxiliares/beautyfier.sh" \ *.cpp="/caminho/auxiliares/beautyfier.sh" \ *.hpp="/caminho/auxiliares/beautyfier.sh" \ *.c++="/caminho/auxiliares/beautyfier.sh" \ *.h++="/caminho/auxiliares/beautyfier.sh" FILTER_SOURCE_FILES = NO SOURCE_BROWSER = YES INLINE_SOURCES = YES STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = YES TREEVIEW_WIDTH = 250 GENERATE_LATEX = YES LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = YES PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = YES LATEX_HIDE_INDICES = NO GENERATE_RTF = NO RTF_OUTPUT = COMPACT_RTF = YES RTF_HYPERLINKS = YES RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = YES TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = YES GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = MAX_DOT_GRAPH_WIDTH = 1024 MAX_DOT_GRAPH_HEIGHT = 1024 MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = YES GENERATE_LEGEND = YES DOT_CLEANUP = YES SEARCHENGINE = YES
#!/bin/sh PTH=`pwd` if [ -d CVS ] ; then cvs status `echo $1 | sed s%$PTH\/%%` | sed -n 's/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p' elif [ -d .svn ] ; then svn stat -v `echo $1 | sed s%$PTH\/%%` | sed -n 's/^[ A-Z?\*|!]\{1,15\}/r/;s/ \{1,15\}/\/r/;s/ .*//p' #F=`echo $1 | sed s%$PTH\/%%` #E=`svn stat -v $F | sed -n 's/^[ A-Z?\*|!]\{1,15\}/r/;s/ \{1,15\}/\/r/;s/ .*//p'` fi
#!/bin/sh /usr/bin/astyle --break-blocks --min-conditional-indent=0 --style=linux -CSKNPT4 $1 rm $1.orig cat $1
Agora chega ;)
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Comentários