-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathmaintenance_evolution.pt.Rmd
231 lines (162 loc) · 10.1 KB
/
maintenance_evolution.pt.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
---
aliases:
- evolution.html
---
# Evolução do pacote - alteração de itens em seu pacote {#evolution}
```{block, type="summaryblock"}
Este capítulo apresenta nossa orientação para alterar coisas em seu pacote: alterar nomes de parâmetros, alterar nomes de funções, descontinuar funções e até mesmo retirar e arquivar pacotes.
_Este capítulo foi inicialmente contribuído como uma nota técnica no site da rOpenSci por [Scott Chamberlain](https://github.com/sckott); você pode ler a versão original [aqui](https://ropensci.org/technotes/2017/01/05/package-evolution/)._
```
## Filosofia das alterações {#philosophy-of-changes}
Todos são livres para ter sua própria opinião sobre a liberdade com que parâmetros/funções/etc. são alterados em uma biblioteca - as regras sobre alterações de pacotes não são impostas pelo CRAN ou de outra forma. Em geral, à medida que uma biblioteca se torna mais madura, as alterações nos métodos voltados para o usuário (ou seja, funções exportadas em um pacote R) devem se tornar muito raras. As bibliotecas que são dependências de muitas outras bibliotecas provavelmente serão mais cuidadosas com as alterações, e devem ser.
## O pacote lifecycle {#the-lifecycle-package}
Este capítulo apresenta soluções que não requerem o pacote lifecycle, mas que você ainda pode considerar úteis.
Recomendamos que você [leia a documentação do lifecycle](https://lifecycle.r-lib.org/articles/stages.html).
## Parâmetros: alteração dos nomes dos parâmetros {#parameters-changing-parameter-names}
Às vezes, os nomes dos parâmetros precisam ser alterados para maior clareza ou por algum outro motivo.
Uma abordagem possível é verificar se os argumentos descontinuados não estão faltando e parar de fornecer uma mensagem significativa.
```r
foo_bar <- function(x, y) {
if (!missing(x)) {
stop("use 'y' instead of 'x'")
}
y^2
}
foo_bar(x = 5)
#> Error in foo_bar(x = 5) : use 'y' instead of 'x'
```
Se quiser que a função seja mais útil, você pode fazê-la emitir um aviso e tomar automaticamente a ação necessária:
```r
foo_bar <- function(x, y) {
if (!missing(x)) {
warning("use 'y' instead of 'x'")
y <- x
}
y^2
}
foo_bar(x = 5)
#> 25
```
Esteja ciente do parâmetro `...`. Se sua função tiver `...` e você já tiver removido um parâmetro (vamos chamá-lo de `z`), um usuário pode ter um código mais antigo que usa `z`. Quando você passa o parâmetro `z` ele não é um parâmetro na definição da função e provavelmente será ignorado silenciosamente -- não é o que você deseja. Em vez disso, deixe o argumento presente, lançando um erro se ele for usado.
## Funções: alteração de nomes de funções {#functions-changing-function-names}
Se você precisar alterar o nome de uma função, faça-o gradualmente, como em qualquer outra alteração em seu pacote.
Digamos que você tenha uma função `foo`.
```r
foo <- function(x) x + 1
```
No entanto, você deseja alterar o nome da função para `bar`.
Em vez de simplesmente alterar o nome da função e `foo` deixar de existir imediatamente, na primeira versão do pacote em que o `bar` aparecer, crie um alias como:
```r
#' foo - add 1 to an input
#' @export
foo <- function(x) x + 1
#' @export
#' @rdname foo
bar <- foo
```
Com a solução acima, o usuário pode usar `foo()` ou `bar()` -- ambos farão a mesma coisa, pois são a mesma função.
Também é útil ter uma mensagem, mas você só vai querer lançar essa mensagem quando eles usarem a função antiga, por exemplo,
```r
#' foo - add 1 to an input
#' @export
foo <- function(x) {
warning("please use bar() instead of foo()", call. = FALSE)
bar(x)
}
#' @export
#' @rdname foo
bar <- function(x) x + 1
```
Depois que os usuários tiverem usado a versão do pacote por algum tempo (com ambos os `foo` e `bar`), na próxima versão você poderá remover o nome da função antiga (`foo`), e você terá apenas `bar`.
```r
#' bar - add 1 to an input
#' @export
bar <- function(x) x + 1
```
## Funções: descontinuadas e removidas {#functions-deprecate-defunct}
Para remover uma função de um pacote (digamos que o nome do seu pacote seja `helloworld`), você pode usar o seguinte protocolo:
- Marque a função como descontinuada na versão do pacote `x` (por exemplo, `v0.2.0`)
Na própria função, use `.Deprecated()` para apontar para a função de substituição:
```r
foo <- function() {
.Deprecated("bar")
}
```
Há opções em `.Deprecated` para especificar um novo nome de função, bem como um novo nome de pacote, o que faz sentido quando você move funções para pacotes diferentes.
A mensagem que é dada por `.Deprecated` é um aviso, portanto, pode ser suprimida por usuários com `suppressWarnings()` se você desejar.
Crie uma página de manual para funções descontinuadas, como:
```r
#' Deprecated functions in helloworld
#'
#' These functions still work but will be removed (defunct) in the next version.
#'
#' \itemize{
#' \item \code{\link{foo}}: This function is deprecated, and will
#' be removed in the next version of this package.
#' }
#'
#' @name helloworld-deprecated
NULL
```
Isso cria uma página de manual que os usuários podem acessar como ``?`helloworld-deprecated` `` e que você verá no índice da documentação. Adicione quaisquer funções a essa página conforme necessário e remova-as quando uma função se tornar "defunct" (veja abaixo).
- Na próxima versão (`v0.3.0`), você pode tornar a função "defunct" (ou seja, completamente removida do pacote, exceto por uma página de manual com uma nota sobre ela).
Na própria função, use `.Defunct()` como:
```r
foo <- function() {
.Defunct("bar")
}
```
Observe que a mensagem em `.Defunct` é um erro para que a função pare, enquanto `.Deprecated` usa um aviso que permite que a função continue.
Além disso, é bom adicionar `...` a todas as funções removidas para que, se os usuários passarem algum parâmetro, recebam a mesma mensagem de "defunct" em vez de um `unused argument` assim, por exemplo:
```r
foo <- function(...) {
.Defunct("bar")
}
```
Sem `...` o resultado é:
```r
foo(x = 5)
#> Error in foo(x = 5) : unused argument (x = 5)
```
E com `...` o resultado é:
```r
foo(x = 5)
#> Error: 'foo' has been removed from this package
```
Faça uma página de manual para funções "defunct", como:
```r
#' Defunct functions in helloworld
#'
#' These functions are gone, no longer available.
#'
#' \itemize{
#' \item \code{\link{foo}}: This function is defunct.
#' }
#'
#' @name helloworld-defunct
NULL
```
Isso cria uma página de manual que os usuários podem acessar como ``?`helloworld-defunct` `` e que você verá no índice da documentação. Você pode adicionar quaisquer funções a essa página, conforme necessário. Você provavelmente desejará manter essa página de manual indefinidamente.
### Testando funções descontinuadas {#testing-deprecated-functions}
Você não precisa alterar os testes de funções descontinuadas até que elas se tornem "defunct".
- Considere todas as alterações feitas em uma função descontinuada. Além de usar `.Deprecated` dentro da função, você alterou os parâmetros na função descontinuada ou criou uma nova função que substitui a função descontinuada, etc.? Essas alterações devem ser testadas, caso você as tenha feito.
- Em relação ao que foi dito acima, se a função descontinuada estiver apenas recebendo uma alteração de nome, talvez você possa testar se as funções antiga e nova retornam resultados idênticos.
- [`suppressWarnings()` poderia ser usado](https://community.rstudio.com/t/unit-testing-of-a-deprecated-function/42837/2) para suprimir o aviso lançado pelo `.Deprecated`, mas os testes não são voltados para o usuário e, portanto, não é tão ruim se o aviso for lançado nos testes, e o aviso pode até ser usado como um lembrete para o mantenedor.
Quando uma função se torna "defunct", seus testes são simplesmente removidos.
## Arquivamento de pacotes {#archivalguidance}
Software geralmente tem uma vida útil finita, e os pacotes podem precisar ser arquivados. Os pacotes arquivados são [arquivados](https://docs.github.com/en/repositories/archiving-a-github-repository/archiving-repositories) e movidos para uma organização dedicada no GitHub, [ropensci-archive](https://github.com/ropensci-archive). Antes do arquivamento, o conteúdo do arquivo README deve ser movido para um local alternativo (como "README-OLD.md") e substituído por um conteúdo mínimo, incluindo algo como o seguinte:
```md
# <package name>
[](https://www.repostatus.org/#unsupported)
[](https://github.com/ropensci/software-review/issues/<issue_number>)
This package has been archived. The former README is now in [README-old](<link-to-README-old>).
```
O *badge* de status do repositório deve estar como "unsupported" (sem suporte) para pacotes lançados anteriormente ou como "abandoned" (abandonado) para pacotes de conceito anterior ou WIP (trabalho em progresso), caso em que o código do *badge* acima deve ser substituído por:
```md
[](https://www.repostatus.org/#abandoned)
```
Um exemplo de um README mínimo em um pacote arquivado está em [ropensci-archive/monkeylearn](https://github.com/ropensci-archive/monkeylearn/blob/master/README.md). Depois que o README tiver sido copiado em outro lugar e reduzido à forma mínima, você deverá seguir as etapas a seguir:
- [ ] Encerre os *issues* com uma frase que explique a situação e faça um link para este guia.
- [ ] Arquive o repositório no GitHub (também nas configurações do repositório).
- [ ] Transfira o repositório para [ropensci-archive](https://github.com/ropensci-archive) ou solicite um [membro da equipe do rOpenSci](https://ropensci.org/about/#team) para transferi-lo (você pode enviar um e-mail para `[email protected]`).
Os pacotes arquivados podem ser desarquivados se os autores ou uma nova pessoa optarem por retomar a manutenção. Para isso, entre em contato com a rOpenSci.