Série: Contribuindo

Importância, peculiaridades e diferenças

Sua contribuição aos códigos disponíveis no github é essencial para tornar estes programas cada vez melhores. Além disso, é difícil para apenas um desenvolvedor testar a imensa quantidade de plataformas e a miríade de configurações existentes. Este guia está aqui para tornar mais simples sua contribuição e aumentar as chances dela ser aceita. Há apenas algumas regras que precisamos para que consigamos manter a organização e o controle do código, então basta seguir este pequeno guia de ‘Como contribuir’.

Cada código, claro, terá suas peculiaridades. Confira no repositório escolhido para entender os detalhes e para você se adaptar ao padrão estabelecido. Deste modo, este texto é mais um guia para que você possa adaptá-lo e inserir no seu próprio repositório.

O local ideal para colocar este texto é numa pasta escondida chamada .github, com nome de arquivo CONTRIBUTING.md. Desta forma, este texto terá um link automático na página de criação de novos issues como por exemplo em:

Please review the guidelines for contributing to this repository.

Iniciando

Tenha certeza de que sua conta está devidamente configurada. Cheque os seguintes itens:

  • Cadastre-se no GitHub 🙂
  • Nas configurações do git em sua máquina local confira se seu nome e email são os mesmos que cadastrou no GitHub.
  • Siga o código de conduta do bom programador BecoSystems
  • Faça um fork, implemente e teste o programa.
  • Para um pull request (PR) ser aceito é essencial que as alterações sejam em doses bem pequenas (homeopáticas), mudando apenas um bloco lógico consistente em cada requisição.
  • Organize a seu PR em ramos. Se preferir fazer pequenas alterações, crie novos ramos a partir do master.
  • Faça testes à vontade no ramo develop ou outro qualquer. Mas se possível tente manter o ramo master fiel ao upstream, e evite conflitos no PR fazendo antes um git pull e merge das últimas modificações.

Arquivos no repositório

  • AUTHORS: lista os autores do programa (em grupo ou individual)
  • LICENSE: TODO a licença do programa (prefira GNU GPL v2, MIT ou BSD-3)
  • VERSION: contém o número da versão atual (modificado automaticamente pelo make)
  • makefile: o script rodado pelo comando make
  • README.md: em sintaxe de Markdown, contém a "capa" que aparece no GitHub.
  • Índice ctags
  • .gitignore : faz o git ignorar certos arquivos
  • .gitattributes : permite configurar atributos por arquivo (veja abaixo)

Formatação

O estilo de indentação

Linguagem C

  • A indentação é feita de acordo com o estilo A1 descrito pelo astyle, também conhecido por –style=allman, –style=bsd ou –style=break.

O estilo Allman é um entre mais de 15 estilos e variantes disponíveis e encontradas em vários tipos de código. Não misture os estilos. Este estilo utiliza a seguinte sintaxe, chamada de broken brackets (ou chaves quebradas). Atente para os espaços entre operadores e mudanças de linhas no exemplo abaixo:

/**
 * @ingroup Modulo
 * @brief Breve descricao
 * @details Descricao detalhada
 * que pode estar em multiplas linhas
 *
 * @param[in] is_bar indice de entrada
 * @param[out] x indice recalculado de saida 
 * @param[in,out] z Entra com um valor blablabla e devolve blebleble
 *
 * @return Descricao do que a funcao retorna
 * @author Ruben Carlo Benante
 * @date 2016-06-05
 */
int foonc(int is_bar[MAX], int x, char *z)
{
    int p; /* a really though condition */

    p = !(is_bar[0] || isBar[1]);

    /* check if it's beer number 2 and not in some thugh condition */
    if(is_bar[x] == 2 && !p)
    {
        z[bar(p + 1)] = 'b';
        return 1;
    }
    else
        return 0;
}

Conheça todos os estilos na página de documentação do astyle.

  • Para aplicar o estilo no seu código, pode-se rodar o programa $astyle -A1 ex11.c

Dicas para um bom código fonte:

Comentários

  • Use comentários / estilo C /
  • Coloque um espaço após o / e um antes do /
  • Faça comentários em linha nas declarações de variável. int i; /* indice geral */
  • Evite comentários em linha em outros locais
  • Na medida do possível e do seu conhecimento, escreva tudo em inglês, desde nomes de variáveis até comentários. Se for importante usar português, então escreva as variáveis em inglês e os comentários nas duas línguas. Caso não seja possível, tudo bem usar apenas português.
  • Coloque os comentários na linha anterior ao bloco ou comando a comentar
  • Não use acentos (nem c-cedilhas) no código ou comentários
  • Use as palavras nos comentários:
    • / TODO: alguma tarefa / : para indicar algo que falta fazer
    • / BUG: esta errado assim e assado / : para indicar um bug conhecido que precisa ser corrigido no futuro.

Comentários DOXYGEN

Antes de cada função, coloque comentários na sintaxe DOXYGEN. O mínimo necessário para bem explicar uma função é detalhar:

  • Grupo do módulo: @ingroup
  • Resumo: @brief
  • Detalhes: @details
  • Opcional, pré-condições: @pre
  • Parâmetros de entrada: @param[in]
  • Parâmetros de saída: @param[out]
  • Parâmetros de entrada e saída: @param[in, out]
  • Valor de retorno: @return ou @retval (ou ambos)
  • Opcional, um aviso: @warning
  • Opcional, se a função está depreciada: @deprecated
  • Opcional, indicar funções semelhantes: @see
  • Opcional, indicar bugs: @bug
  • Opcional, indicar to do: @todo
  • Opcional, escrever uma nota: @note
  • Autor: @author
  • Opcional, colocar versão: @version
  • Data que foi escrita/modificada: @date (formato YYYY-MM-DD, ano, mes, dia)
  • Opcional, caso diferente do resto do código, colocar a licença de copyright: @copyright

O exemplo acima mostra somente os campos obrigatórios, e descreve hipotéticas variáveis como parâmetros.

No meio do código

  • Apague espaços sobrando ao final da linha (trailing spaces)
  • Não inclua espaços após (, [, { ou antes de }, ] e )
  • Use espaços após vírgulas e ponto-e-vírgulas
  • Use espaços em volta de operadores (exceto os unários como !)
  • Não cometa erros de grafia (não use acentos!)
  • Não alinhe tokens verticalmente em linhas consecutivas
  • Use indentação de 4 espaços (não use TABS)
  • Se quebrar uma linha, indente-a 4 espaços
  • Use uma linha em branco entre métodos, funções ou blocos lógicos importantes
  • Use final de linha de um byte (n) estilo Unix (*)
  • Deixe uma linha em branco ao final do arquivo conforme padrão POSIX

Variáveis

  • Variáveis com letras maiúsculas somente se:
    • São PROLOG, claro 😉
    • São MACROS (logo não são variáveis) em C (exemplo: #define CINCO 1)
    • São MUIIIITO importantes e precisam de algum destaque. Não tente usar assim, pois você provavelmente não vai convencer ninguém. 😉
  • Use nomes claros para as variáveis
  • O nome da variável deve indicar sua intenção, i.é., o dado que ela carrega.
  • Prefira nomes que demonstrem o conceito geral do domínio, ao invés dos padrões que eles implementam.
  • Não faça nomes gigantes. Um tamanho máximo que já não fica tão bom é até 15 caracteres. Tente nomes menores, até 10 no pior caso.
  • Use sublinhados para sufixos apenas se for criar variáveis que tenham alguma característica em comum. Exemplo: salario_antes e salario_depois. Se existirem muitas características em comum em um tipo de dados, considere agrupar com struct
  • Não coloque o tipo no nome da variável. Exemplo: vetor_de_alunos.
  • Coloque t_ no início de typedef. Exemplo: typedef int t_meuint;
  • Coloque st_ no início de structs. Exemplo: struct st_concreto { ... };
  • Coloque s no início de variáveis string. Exemplo: char snome[MAX];
  • Coloque p no início de ponteiros. Exemplo: t_carro *pcarro; ou char *pnome;.
  • Nomeie uma enum (enumeração) pelo substantivo comum do objeto que ela enumera.

Organização

A ordem que o esqueleto do programa deve ter é como segue:

Em linguagem C

  • Comentário com copyright, descrição do programa, autor, contato e data
  • Comentários com uma introdução à leitura do código, explicações gerais, compilação, etc.
  • O(s) #include <...>
  • O(s) #include "..."
  • Se o programa não tem uma biblioteca própria, seguem:
    • Os defines
    • Os TAD’s (tipos abstratos de dados): struct, enum, typedef, etc.
    • Os tipos globais
    • Os protótipos das funções
  • Se o programa tem biblioteca própria, estes ficam no .h
  • A função int main(void) ou int main(int argc, char *argv[])
  • As outras funções, de preferência em uma ordem que faça um mínimo de sentido com o próprio fluxo do programa

Ciclo de trabalho

  • Ligou o computador, primeira vez neste repositório
    • Tudo configurado no GitHub e na sua máquina local?
    • Repositório criado no GitHub com fork
    • Faça o clone na sua máquina
    • Crie seu ramo feature-nome ou vá para develop
    • Siga a partir do passo (1)
  • Ligou o computador para trabalhar do segundo dia em diante
    • Atualize todos os ramos remotos (master e develop)
    • Resolva conflitos se houver
    • Vá para seu ramo de trabalho feature-nome ou develop
    • (1) Edite o arquivo fonte no vi
    • (2) Compile (gcc ou make, ou teste no swipl)
    • (3) Erros: volte para passo (1)
    • (4) Compilou sem erros: faça commit
    • (5) Vai trabalhar mais, volte para o passo (1)
    • (6) Fim do dia de trabalho:
      • Vá para o develop e atualize-o
      • Faça merge do feature-nome com o develop
      • Resolva conflitos se houver
      • Teste o programa muitas vezes e corrija se necessário
      • Faça o push do develop para o GitHub
      • Ou, se usou apenas o develop, faça o push
    • (7) Dia de finalizar o master e pedir um pull request
      • Vá para o master e atualize-o
      • Faça merge do develop com o master
      • Resolva conflitos se houver
      • Teste o programa muitas vezes e corrija se necessário
      • Faça o push do master para o GitHub
      • Tudo pronto, faça o pull request e torça para ser aceito

Teste

  • Não tenha pressa de fazer push! O push é irreversível, manda para o GitHub. Enquanto estiver só na sua máquina você pode corrigir quaisquer bugs
  • Compile. Use todas as chaves de aviso que o gcc pode oferecer. O gcc é seu amigo!
  • Crie páginas com mensagens de erro com o comando sprunge para discutir nos issues se necessário
  • Use makefile para compilar seus testes
    • Não deixe de conhecer as opções do gcc para compilação. Este é um comando fundamental em vários sistemas operacionais, inclusive embarcados (arduino, pic, raspberry pi, etc.)
  • Teste! Rode o programa, faça entrada de dados, veja se o que acabou de programar realmente faz o que você deseja, e se não quebrou nada em outra função do programa.
  • Tudo ok? Então faça o push!
  • Faça suas modificações chegarem até o master e então faça o pull request do seu master (origin) para o master do upstream.
  • No pull request coloque um título descritivo.

Faça uma boa mensagem de commit

  • Se é um pequeno commit tudo bem abreviar a mensagem com apenas um título com o comando git commit -am "uma descricao do que este commit faz em ate 50 caracteres"
  • Mas se é um commit que vai influenciar muito o código de outros ramos ou que vai ser usado para pull request então é importante escrever uma boa mensagem. Neste caso, não use o comando abreviado. Use os comandos:
    • git add arquivo : se necessário adicionar algum arquivo
    • git commit : sem abreviação e sem mensagem. Este comando vai abrir o vi (ou seu editor preferido) para você digitar uma mensagem de commit maior.
      • Na primeira linha, escreva um título do commit com até 50 caracteres, como você já está acostumado.
      • Pule uma linha.
      • Da terceira linha para baixo, descreva com mais detalhes tudo o que você fez, o que este commit inclui, o que muda, qual funcionalidade é acrescentada ou bug é resolvido.
      • Saia com :x (no vi) para salvar e fazer o commit
      • Saia com :q! (no vi) para abortar a edição e não fazer o commit
      • Linhas iniciadas com # são ignoradas pelo git como sendo comentários e não são escritas no commit.
  • Exemplo de uma boa mensagem de commit:
Faz um exemplo para demonstrar a clareza do commit

Sem este commit a explicação sobre mensagens de commit ficaria 
falha, sem um exemplo concreto. Este é um problema, porque assim 
fica apenas na imaginação o que seria um bom commit.Este commit 
corrige este problema ao fazer aqui um exemplo concreto e imperativo.

A primeira linha é um título imperativo descritivo do essencial. 
Os dois parágrafos seguintes, o de cima e este, são explicações mais 
aprofundadas. É importante descrever:

(1) _o que ocorria_ antes do commit, 
(2) _qual_ é o problema que este commit resolve, 
(3) _porque_ este comportamento é problemático, e 
(4) _como_ este commit corrige este problema.

Também é possível usar enumerações para clarificar algumas mudanças 
em pontos específicos, como:

* mudafunc() : agora não retorna mais void e sim o código do cliente
* funcoutra() : criada para cumprir outra finalidade que faltava
* divideaqui() : criada para cumprir uma finalidade tal e tal que 
antes estava sendo feita na função mudafunc() de modo a ficar mais 
clara a divisão do que cada função faz.

Lembre que a primeira linha é importante para ver o log e acompanhar a evolução do programa.

Dicas de configuração

Final de linha estilo Unix (n)

  • Para o final de linha n, use em suas configurações
    • Linux, Mac ou Unix: git configure --global core.autocrlf input
    • Windows: git configure --global core.autocrlf true
  • Outra opção para configurar n é por repositório. Inclua um novo arquivo .gitattributes com os comandos:
# Arquivo .gitattributes

* text=auto
*.c text
*.h text
*.txt text
*.ini text
*.eng text
*.x binary
*.jpg binary
*.png binary

Obrigado!

Agora é com você! Divirta-se programando!

Atenciosamente,

Prof. Dr. Ruben Carlo Benante <rcb@beco.cc>

Autor do brainforce

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>