Manter uma biblioteca
Depreciar sem quebrar, o que fazer numa mudança incompatível, e como não abandonar quem depende de você.
A parte difícil de uma biblioteca começa depois do 1.0.0. Tudo o que você publicou está rodando na máquina de alguém, e cada mudança tem de escolher entre melhorar e não quebrar.
Acrescentar é quase sempre seguro#
// antes
action formatar(valor: Float) -> String:
yield $"R$ {round(valor, 2)}"
// depois — menor, não maior: quem chamava com um argumento continua igual
action formatar(valor: Float, moeda: String := "R$") -> String:
yield $"{moeda} {round(valor, 2)}"Parâmetro novo com padrão, campo novo com padrão, ação nova no relay: tudo isso é versão menor. A armadilha é o parâmetro novo sem padrão — e a linguagem recusa declará-lo depois de um com padrão, o que evita metade dos casos.
Depreciar: avise antes de remover#
Remover na hora quebra; remover depois de um ciclo de aviso não. A sequência tem três etapas e leva uma versão maior:
// 1.5.0 — o novo nasce, o velho continua e avisa
action validar_cpf(texto: String) -> Boolean:
yield len(texto) is 11
action cpf(texto: String) -> Boolean:
// descontinuada em 1.5.0, sai na 2.0.0
out "aviso: V.cpf virou V.validar_cpf; ela sai na 2.0.0"
yield validar_cpf(texto)
relay validar_cpf, cpf- 1.5.0 — o nome novo aparece; o antigo continua funcionando e avisa.
- 1.x seguintes — o CHANGELOG repete o aviso.
- 2.0.0 — o antigo sai, e a nota de versão diz exatamente o que fazer.
O aviso precisa dizer o que usar no lugar. Um "descontinuado" sem substituto só transfere o problema.
Quando a quebra é inevitável#
| Faça | Porque |
|---|---|
| suba o maior | é a única sinalização que o resolvedor entende |
| escreva o caminho de migração | "o que mudou" sem "o que fazer" custa uma tarde a cada usuário |
| mantenha a linha antiga viva por um tempo | correção de segurança em 1.x enquanto a 2.x amadurece |
| quebre uma vez, e não aos poucos | três versões maiores em seis meses é pior que uma com três quebras |
O CHANGELOG é para quem atualiza#
## 2.0.0
### Quebrado
- `V.cpf` saiu. Use `V.validar_cpf`, que tem a mesma assinatura.
- `V.email` devolve um record em vez de Boolean:
antes: given V.email(x):
agora: given V.email(x).valido:
### Adicionado
- `V.cep`, com os dois formatos.A seção Quebrado vem primeiro e mostra as duas linhas — a de antes e a de agora. É o que transforma uma atualização numa busca-e-substitui em vez de uma investigação.
Segurança#
- Uma correção de segurança sai como correção em todas as linhas ainda vivas, e não só na mais nova.
- A nota diz o que estava exposto e desde quando — sem isso ninguém sabe se foi afetado.
- Se um segredo vazou dentro de um tarball publicado, ele está comprometido: rotacione, e publique uma versão nova. Despublicar não desfaz o download de ninguém.
Abandonar com honestidade#
Uma biblioteca sem manutenção é comum e legítimo. O que faz diferença é dizer: uma linha no README — "não tenho mantido isto; outra-lib faz o mesmo" — economiza horas de quem estava prestes a adotá-la, e é mais útil que qualquer último commit.