Repository navigation
padrao codigo
Home > Guia de contribuição do PascalRAL > Padrão de Código
-
Todas as units precisam ser concisas e referenciar um escopo, não existe necessidade de ter uma unit pra cada classe.
-
Os uses são organizados por grupo de escopo, seguindo as condições:
-
Diretivas de compilação: caso a unit dependa de outra baseada em uma condição específica, essas diretivas sempre vêm primeiro na seção uses. Caso a diretiva seja usada, precisa importar a
PascalRAL.incque contém o mapeamento das diretivas mais comuns. Caso a diretiva que você precisa não esteja inclusa lá, defina lá para usar na classe, garantindo que não seja uma redundância de outra diretiva existente. -
Units nativas da IDE: dependências presentes em todas as IDEs, tais como
Classes,SysUtils,System... -
Units da dependência: units necessárias da dependência. Ex:
ZQuery,ZComponent... -
Units do projeto: units presentes nos fontes do projeto RAL. Ex:
RALTools,RALTypes...
-
Diretivas de compilação: caso a unit dependa de outra baseada em uma condição específica, essas diretivas sempre vêm primeiro na seção uses. Caso a diretiva seja usada, precisa importar a
-
Tudo é documentado: unit, classe, record, enum, tipo de evento, constante, rotina e cada membro de classe, privados inclusive. A documentação é em Inglês americano
enUS, veja Documentação no código. -
As seções internas das classes são organizadas em:
-
- Private
-
- Protected
-
- Public
-
- Published
Não informar a seção caso não precise dela
-
-
Dentro de cada seção, os atributos e métodos são classificados em ordem alfabética seguindo a ordem:
-
- Atributos internos: variáveis ou constantes
-
- Método
constructor
- Método
-
- Método
destructor
- Método
-
- Métodos:
procedureoufunction, a palavra reservada não influencia na ordem alfabética
- Métodos:
-
- Eventos: métodos que começam com “On”
-
- Atributos publicados,
property
- Atributos publicados,
Diretiva de compilação (
{$IFDEF},{$ENDIF}...) não se move: a ordem vale dentro de cada trecho entre duas diretivas, e nenhum membro entra ou sai de um{$IFDEF}. Enumerados, sets, constantes inicializadas e records não são reordenados. -
-
A Identação padrão é a mesma definida pela IDE Delphi ou Lazarus com as seguintes alterações:
- Margem direita 90
- Diretivas seguem identação
-
As units devem ser salvas seguindo o padrão de nomenclatura do projeto: RAL + escopo da unit, por exemplo:
RALClient.Dentro da pasta relativa ao escopo de projeto, como base, utils, database… -
Os escopos de projeto atuais são:
- Base = pasta que contém as units referentes ao funcionamento mínimo do pacote e são obrigatórias na compilação para o pacote-base funcionar.
- Utils = pasta que contém funções diversas, mapeadores e demais métodos que são utilizados por várias outras units.
- Database = pasta que contém todas as units referentes ao tráfego de informações DBWare.
-
Caso o código seja para um pacote diferente, precisa ficar contido no escopo de projeto relacionado a ele, por exemplo um motor de dados possui os arquivos de projeto
.dpkdentro de\pkg\<IDE>e as units ficam em\src\engine\<motor>. Basta seguir esse modelo ou entrar em contato seja abrindo uma issue de dúvida, ou uma discussão no GitHub, ou acessando o grupo de suporte do componente. -
Na 2.0 🚧 as regras de pasta e de pacote são estas (a troca de cada nome está em Migrar para a 2.0):
-
Uma pasta pertence a um pacote só.
src\core,common,compress,cryptoepluginssão doPascalRAL;src\designé doPascalRALDsgn; cada pacote opcional tem a sua (src\plugins\auth,src\storage,src\modules\web,src\engine\indy...). A exceção ésrc\others, que guarda só os submódulos (ZSTD, pascal_brotli, kxBSON) e nenhuma unit do RAL. -
As units de design ficam numa subpasta
designdo recurso (src\database\design,src\modules\soap\design). Não é enfeite: olazbuild -Bcompila de novo, dentro do pacote de design, toda unit de runtime que achar na mesma pasta. -
Nomes de pacote:
PascalRALePascalRALDsgn(os obrigatórios, na raiz depkg\<IDE>); motores<Motor>RAL(IndyRAL), de propósito, para lembrar que é preciso um motor; o restoRAL<Categoria><Item>PackageeRAL<Categoria><Item>Dsgn(RALPluginAuthPackage,RALDBFireDACPackage+RALDBFireDACDsgn). No Lazarus, os mesmos nomes em minúsculas. -
Nenhuma unit termina em
Package,DsgnouRAL, para um pacote nunca ter o nome de uma unit. A unit que registra componentes éRAL<item>Reg(a do núcleo éRALRegister). -
Runtime e design separados: os
...Dsgnsão{$DESIGNONLY}(DesignTimeno Lazarus); um pacote que só registra componentes é de runtime e design e exige oPascalRAL, nunca oPascalRALDsgn. - O
PascalRAL.incentra por caminho relativo ({$I ..\core\PascalRAL.inc}, na profundidade da unit), sem include path.
-
Uma pasta pertence a um pacote só.
/// Unit that represents the code that complies with documentation for contributors.
unit RALExample;
{$I PascalRAL.inc} // necessary since there's a conditional directive below
interface
uses
{$IFDEF RALWindows} Windows, {$ENDIF}
Classes, SysUtils;
type
/// Example that follows the documentation as a guideline for contributors.
TMyExample = class
private
FSomething: sometype;
public
constructor Create;
destructor Destroy; override;
/// Returns something.
function GetSomething: sometype;
{ Defines something. A description that does not fit in one line
goes in braces. }
procedure SetSomething(AParam: sometype);
/// Event to be called during something.
procedure OnSomething(AParam: sometype);
/// Something the example keeps.
property Something: sometype read GetSomething write SetSomething;
end;
implementation
[...]
end.A descrição é o que aparece no autocomplete e no hint do Delphi e do Lazarus, e é dela que o pasdoc gera a documentação da API. Por isso ela é curta.
-
Uma linha (cabe em 90 colunas com a indentação):
/// Texto. -
Mais de uma linha: chaves. O texto começa depois de
{, as linhas seguintes ficam alinhadas com ele e o}fecha na última linha. Duas ou três linhas no máximo. - O comentário fica colado na declaração, sem linha em branco no meio.
- Inglês americano, tempo presente. A primeira frase é o resumo e fecha com ponto.
- Diz o que a coisa é ou faz e o que quem usa precisa saber: unidade e valor padrão
("milliseconds; 0 = no limit"), o que
nilou vazio significa, quando levanta exceção, em que thread um evento roda, restrição de plataforma ou de motor. - Não diz: histórico ("used to", "antes era", datas), referência a plano ou etapa, números de medição, alternativa descartada, comparação com outro motor. O git guarda a história.
- Explicação longa vai para a wiki: o "porquê" de uma decisão e as armadilhas de cada motor ficam nas páginas de internos, não no código.
- Cada membro tem a sua descrição; comentário de grupo sobre vários campos não vale.
- Ficam sem descrição só:
Create/Destroysem parâmetro que precise de explicação,overrideque não muda o contrato do ancestral, e o campo, o getter e o setter de uma propriedade documentada. - Enumerados, sets e constantes inicializadas ganham a descrição antes da declaração, que não muda de forma.
- Diretiva de compilação não é comentário:
{$IFDEF}é código. - Sem crase e sem lista "- item" dentro do comentário (o pasdoc mostra literal).
Identificador escrito puro (
TRALServer.SSL) vira link sozinho. Um@literal é@@, porque@abre as tags do pasdoc (@code(...),@param,@raises,@deprecated...). - Dentro de
{ }nunca entra}nem{, e o texto nunca começa com$(viraria diretiva). - Comentário dentro de método (
//ou{ }) só quando o código não se explica: um invariante, uma ordem obrigatória, uma referência de protocolo. Uma ou duas linhas, no presente. Código comentado não fica.
{ Accepted server certificates (SHA-256), one per line: "fp" for any host,
"host=fp" or "host:port=fp" for one server. }
property Pins: TStrings read GetPins write SetPins;
/// Refuses to send anything over plain http, whatever the URL says.
property Required: boolean read FRequired write FRequired default False;O CHANGELOG.md é gerado sozinho a partir das mensagens de commit, então o
assunto do commit é a nota de versão que o usuário vai ler. Escreva em
inglês, dizendo o que muda para quem usa.
A seção do changelog é escolhida pela primeira palavra-chave encontrada no assunto e no corpo, nesta ordem:
| Ordem | Palavras (em qualquer lugar da mensagem) | Seção |
|---|---|---|
| 1 |
security, vulnerability, cve, exploit
|
Security |
| 2 |
breaking change, breaking:, break:
|
Breaking Changes |
| 3 |
deprecat, obsolete, phase out
|
Deprecated |
| 4 |
remove, delete, drop, eliminate
|
Removed |
| 5 |
add, new, create, implement, feat
|
Added |
| 6 |
fix, resolve, correct, patch, bug, issue
|
Fixed |
| 7 |
chore, chr
|
(fora das notas) |
| — | nenhuma | Changed |
Duas pegadinhas:
-
removevem antes deadd: um commit de recurso novo cujo corpo diz "removes the old check" cai em Removed. Escolha a seção e evite no texto as palavras das seções anteriores. - As palavras são em inglês: "Adicionado..." não tem
adde cai em Changed.
Commits com [skip ci] ou docs: update changelog ficam de fora.
Exemplos:
Add PBKDF2 key derivation for the AES body cipher
Fix the fpHTTP client writing requests into closed connections
Breaking change: CORS lets no origin in by default
Começar
Servidor
- Rotas e parâmetros
- Ler o pedido e responder
- Resposta em fluxo 🚧
- Plugins 🚧
- Autenticação
- Banco de dados (DBWare)
- Servir site e arquivos
- Swagger e Postman
- Servidor SOAP 🚧
- HTTPS
- Criptografia ponto a ponto
- Segurança para produção
- Colocar no ar
- Desempenho
MQTT 🚧
- O que é e quando usar 🚧
- Cliente MQTT 🚧
- Broker MQTT 🚧
- MQTT-SN 🚧
- Ponte REST 🚧
- Segurança 🚧
- Rede ruim 🚧
Cliente
Motores
Avançado
Ajuda
- Problemas comuns
- Atualizar o Indy
- Várias versões do Delphi
- Vídeos e guias
- Módulos de terceiros
- Licenças
- Contribuir
- Roadmap e changelog
🚧 = em desenvolvimento, pode mudar