Criando Documentação no Jmine

Visão Geral

Toda camada do Jmine Framework possui um módulo chamado ‘docs‘, que basicamente serve como ponto central para criação de documentação técnica usando um conjunto de ferramentas já estabelecidas no mundo open-source e que permitem transformar arquivos de texto em praticamente qualquer outro formato (como html, pdf etc...).

  • ReStructured Text: linguagem de markdown que usa o próprio texto para definir relacionamentos e comportamentos. Lembra bastante a linguagem que usamos em uma wiki, mas possui uma sintaxe própria, que permite extensões por parte dos usuários
  • Sphinx: um sistema de documentação técnica para python, bastante usado em projetos open-source e base para o site http://readthedocs.org. O Sphinx expande o comportamento do ReStructured Text adicionando blocos e marcações específicas para documentação de código-fonte
  • JavaSphinx: apesar do Sphinx ter sido criado, originalmente, para python, ele permite expansão e uso por outras linguagens, como ruby, php e java. O suporte à linguagem Java ocorre através do JavaSphinx. Usamos uma versão alterada deste plugin para que seja possível adaptar melhor a nossa documentação técnica ao modo de desenvolvimento do Jmine.
  • Sphinx Maven: o sphinx é completamente criado usando a linguagem Python, mas este plugin envelopa todos os requisitos usando Jython, isto evita que os desenvolvedores Java precisem se preocupar em criar e manter um ambiente específico para lidar com a documentação, tornando sua criação tão simples quanto executar um comando maven, comum a todos neste meio.

É importante notar que existem dois tipos bem distintos de documentação, e o uso combinado de ambos é essencial para que possamos criar artigos claros e suficientes, tanto para quem deseja entender como o negócio funciona, quanto para quem deseja saber como o código conversa com a lógica de negócio:

  • Documentação automática: é a documentação extraída diretamente do código, ou seja, dos JavaDocs que criamos. Este tipo de informação é muito relevante, e pode ser muito aprofundada, mas geralmente é muito específica, por exemplo, o javadoc de um método dirá o que o método faz, e não dará uma visão geral do que aquilo significa no negócio
  • Documentação manual: informação gerada, em sua grande maioria, por pessoas. É a documentação que descreve o negócio e geralmente é muito mais alto nível, descrevendo como as coisas se relacionam e não apenas o que elas fazem.

Na estrutura do Jmine você cria a documentação usando o maven em conjunto com perfis que vão processar os tipos de documentação citados acima, para processar a documentação manual e transformá-la em HTML é necessário rodar o comando abaixo:

cd docs
mvn clean site -Pdocs

Já para a documentação completa (documentação criada por pessoas e a documentação extraída do código fonte) existe um outro perfil:

cd docs
mvn clean site -Pdocs-full

Vale a pena notar que o ‘clean‘ não é obrigatório, caso você queira utilizar caches e tornar a geração de documentação mais rápida, você pode não usá-lo e assim reaproveitar o processamento realizado em comando anterior.

Quando o target ‘site‘ for executado com o devido perfil, basta olhar na pasta ‘target/site‘ do componente docs e os arquivos gerados estarão lá.

Criando um documento

O sistema de documentação vai processar todos os arquivos com extensão rst que estejam dentro do pasta “src/sphinx” do módulo “docs”. Por isto, para criar um novo documento basta criar um arquivo vazio, editá-lo e pronto. Não se esqueça de linkar a página recém criada com alguma outra, provavelmente no próprio arquivo index.rst do módulo.

Existe uma documentação extensiva sobre o ReStructured Text (reST daqui para frente) na internet, vamos tentar consolidar aqui os blocos de criação mais comuns, mas fique à vontade para pesquisar no google e obter mais informação.

reStructured Text Básico

Antes de mais nada é necessário entender que reST é ‘white space sensitive’, ou seja, não colocar um espaço em branco corretamente afeta o resultado final, por tanto, fique atento. Além disto é possível executar comandos que vão transformar texto em um bloco específico. Isto é feito usando a notação ‘..’, como abaixo:

.. note:: esta é uma nota simples
     e espaços em branco importam

Note que :: indicam uma separação da chamada do bloco de seus parâmetros. No exemplo acima o texto logo após os :: representa o título da nota, o texto abaixo é a continuação dele, mas para ser reconhecido como tal é necessário que exista a indentação.

A seguir apresento exemplos de usos básicos, caso você queira saber o que é possível fazer com o Sphinx e o reST, por favor visite o site http://sphinx-doc.org/rest.html

Seções

A hierarquia de cabeçalhos (e as seções que eles representam) funciona usando uma sequência de caracteres que sublinham o título desejado, como abaixo:

===============
Seção principal
===============

Seção 1
=======

Seção 1.1
---------

Seção 1.1.1
^^^^^^^^^^^

Seção 1.2
---------

Seção 1.2.1
^^^^^^^^^^^

Seção 2
=======

Seção 2.1
---------

Seção 2.1.1
^^^^^^^^

Formatação

  • Itálico: *texto em itálico*
  • Negrito: **texto em negrito**
  • Monospace: ``monospace``

Listas

Listas com bullets:

* Item 1
* Item 2
* Item 3

Listas numeradas:

#. Item 1
#. Item 2
#. Item 3

Listas compostas:

* Item
  #. SubItem
  #. SubItem
* Item

Notas e Avisos

Note

Nota exemplo

Warning

Aviso exemplo

Imagens

Para adicionar uma imagem basta usar o bloco abaixo:

.. image:: minha_imagem.png

Notas de Rodapé

Caso queira colocar referências no texto você pode usar a seguinte sintaxe:

Alguém [#f1]_ falou que código limpo é código lindo!

E em algum outro canto do seu documento, colocar a referência:

.. _[#f1] Referência a alguém

Referenciando documentos

É possível referenciar outros documentos no próprio componente usando a notação abaixo:

:doc:`Minha Documentação <caminho/relativo/docs>`

Você também pode linkar sites externos usando a marcação já discutida acima. Caso o objetivo seja fazer as documentações criadas se relacionarem, ou referênciarem entidades, é possível fazê-lo através de blocos específicos do java:

:java:ref:`jmine.tec.persist.impl.hibernate.impl.Entidade`
:java:meth:`jmine.tec.persist.impl.hibernate.impl.Entidade.toString`

Os exemplos acima colocarão o nome completo da classe, incluindo seu pacote, no link. É possível simplificar e usar somente o nome básico da classe usando a estrutura abaixo:

:java:ref:`~jmine.tec.persist.impl.hibernate.impl.Entidade`

O uso ou não do ~ vai fazer com que ‘Entidade‘ seja exibido na documentação e não ‘jmine.tec.Entidade‘.

O sistema tentará resolver as referência criadas, e o html gerado após a geração da documentação completa terá links para a página gerada automaticamente. Caso você faça referência a uma entidade que não está na camada, é possível indicar para o sphinx a localização externa das respectivas documentações usando o arquivo conf.py

Exemplos de Código

Esta estrutura foi proposta pensando, principalmente, na sua manutenibilidade. Nós podemos usar qualquer sistema para criar e armazenar informações, só que quando relacionamos isto com código, estas informações podem ficar desatualizadas muito rapidamente.

Como usamos java, a melhor forma de garantir que os exemplos de código continuem atuais é manter o código usado na documentação diretamente no projeto. Para isto criamos o bloco abaixo, que permite inserir trechos de classes ou métodos diretamente do projeto:

.. java:code:: jmine.tec.aom.example.OnlineCarBuilderExampleTest

Este exemplo vai adicionar na documentação todo o corpo da classe OnlineCarBuilderTest, um teste criado com o único objetivo de auxiliar a transmissão de conhecimento técnico. Ainda é possível adicionar somente métodos específicos:

.. java:code:: jmine.tec.aom.example.OnlineCarBuilderExampleTest
    :method: testSimpleCreatePropertizedAvailableCars

Neste exemplo, o método testSimpleCreatePropertizedAvailableCars da classe OnlineCarBuilderExampleTest será adicionado, incluindo sua assinatura. Quando a assinatura do método não for necessária, é possível usar o modo abaixo:

.. java:code:: jmine.tec.aom.example.OnlineCarBuilderExampleTest
    :method: testSimpleCreatePropertizedAvailableCars
    :body-only:

Esta é a melhor forma de adicionar pedaços de código que serão executados e evoluirão com o projeto original.

Validações em tempo de build

Com a preocupação em evoulir a documentação junto com o código, criamos um conjunto de testes que validam em tempo de build as referências feitas ao código. Caso as classes referenciadas não existam, o build quebrará, avisando ao desenvolvedor de que é necessário editar a documentação.

Isto é feito usando a estrutura de ComponentStructureTest do próprio Jmine, por enquanto simplesmente verificando a existência das classes e dos métodos no classpath da aplicação, mas é possível evoluir estas validações de acordo com nossa necessidade.

Caso você queira dar uma olhada em como isto ocorre, verifique a classe jmine.tec.docs.ComponentStructureTest.

Visualizando alterações

Você pode executar os comandos maven para gerar a documentação e visualizá-la no seu navegador. Esta é uma abordagem muito boa, e não demora muito, mas, caso você esteja confortável com o vim, existe um plugin que permite a visualização em tempo real da documentação que você está criando, é o InstantRst.

Indicação do Guilherme Costa, este é um plugin que integra seu editor com o navegador, permitindo que você tenha uma ideia muito aproximada de qual será o resultado final do seu documento. O Guilherme também criou um fork que permite que esta pre-visualização ocorra com o tema do Jmine.

Para usá-lo é necessário seguir instruções disponíveis no repositório http://srv-mercurial.maps.com.br:5000/Jmine/docs-template

E pronto, você pode abrir o vim para editar um arquivo reST, digitar :InstantRst e começar a visualizar o que está fazendo. Isto agiliza muito a criação da documentação.

Referências

Caso queira mais informações, aconselhamos os seguintes sites: