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
esalario_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;
ouchar *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)
ouint 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 arquivogit 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.
- Referência: A Note About Git Commit Messages
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
- Linux, Mac ou Unix:
- 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
- Veja detalhes de como atualizar o repositório após alterar estas configurações na página de help do GitHub
- Veja também configurando o Git
Obrigado!
Agora é com você! Divirta-se programando!
Atenciosamente,
Prof. Dr. Ruben Carlo Benante <<rcb@beco.cc>>
Autor do brainforce