Uma lista aberta e colaborativa de itens que você deve verificar antes de enviar seu pacote ao CRAN.
Este repo nasceu após trocas no Twitter sobre o processo de envio do CRAN, especialmente este tópico.
A idéia aqui é coletar regras básicas que ajudariam o CRAN a trabalhar com mais facilidade, listando coisas comuns (ou incomuns) que eles pedem aos mantenedores para alterar para serem à prova de CRAN.
O envio do CRAN é rigoroso, a equipe do CRAN está fazendo seu trabalho voluntariamente e há mais de 15 mil pacotes para manter.
Acreditamos que podemos ajudá-los fornecendo algumas boas práticas sobre desenvolvimento de pacotes e submissão de CRAN, para que os autores de pacotes possam trabalhar nessas questões antes que a equipe CRAN lhes peça para fazê-lo. Assim, poderíamos economizar o tempo de todos, evitando que a equipe CRAN lhe envie um e-mail porque existe "com R" no título da sua DESCRIÇÃO. Porque, como disse Peter Dalgaard:
muitas pessoas não percebem que o grupo mantenedor do CRAN pode ser contado em uma mão, às vezes até mesmo em um dedo.
Ainda há etapas a serem adicionadas à lista de testes automatizados, conforme detalhado nas seções a seguir, mas você pode adicioná-los a um arquivo "dev/dev_history.R" para executá-los sempre que enviar algo ao CRAN.
# Prepare for CRAN ----
# Update dependencies in DESCRIPTION
# install.packages('attachment', repos = 'https://thinkr-open.r-universe.dev')
attachment :: att_amend_desc()
# Check package coverage
covr :: package_coverage()
covr :: report()
# Run tests
devtools :: test()
testthat :: test_dir( " tests/testthat/ " )
# Run examples
devtools :: run_examples()
# autotest::autotest_package(test = TRUE)
# Check package as CRAN using the correct CRAN repo
withr :: with_options( list ( repos = c( CRAN = " https://cloud.r-project.org/ " )),
{ callr :: default_repos()
rcmdcheck :: rcmdcheck( args = c( " --no-manual " , " --as-cran " )) })
# devtools::check(args = c("--no-manual", "--as-cran"))
# Check content
# install.packages('checkhelper', repos = 'https://thinkr-open.r-universe.dev')
# All functions must have either `@noRd` or an `@export`.
checkhelper :: find_missing_tags()
# Check that you let the house clean after the check, examples and tests
# If you used parallel testing, you may need to avoid it for the next check with `Config/testthat/parallel: false` in DESCRIPTION
all_files_remaining <- checkhelper :: check_clean_userspace()
all_files_remaining
# If needed, set back parallel testing with `Config/testthat/parallel: true` in DESCRIPTION
# Check spelling - No typo
# usethis::use_spell_check()
spelling :: spell_check_package()
# Check URL are correct
# install.packages('urlchecker', repos = 'https://r-lib.r-universe.dev')
urlchecker :: url_check()
urlchecker :: url_update()
# check on other distributions
# _rhub v2
rhub :: rhub_setup() # Commit, push, merge
rhub :: rhub_doctor()
rhub :: rhub_platforms()
rhub :: rhub_check() # launch manually
# _win devel CRAN
devtools :: check_win_devel()
# _win release CRAN
devtools :: check_win_release()
# _macos CRAN
# Need to follow the URL proposed to see the results
devtools :: check_mac_release()
# Check reverse dependencies
# remotes::install_github("r-lib/revdepcheck")
usethis :: use_git_ignore( " revdep/ " )
usethis :: use_build_ignore( " revdep/ " )
devtools :: revdep()
library( revdepcheck )
# In another session because Rstudio interactive change your config:
id <- rstudioapi :: terminalExecute( " Rscript -e 'revdepcheck::revdep_check(num_workers = 4)' " )
rstudioapi :: terminalKill( id )
# if [Exit Code] is not 0, there is a problem !
# to see the problem: execute the command in a new terminal manually.
# See outputs now available in revdep/
revdep_details( revdep = " pkg " )
revdep_summary() # table of results by package
revdep_report()
# Clean up when on CRAN
revdep_reset()
# Update NEWS
# Bump version manually and add list of changes
# Add comments for CRAN
usethis :: use_cran_comments( open = rlang :: is_interactive())
# Upgrade version number
usethis :: use_version( which = c( " patch " , " minor " , " major " , " dev " )[ 1 ])
# Verify you're ready for release, and release
devtools :: release()
devtools::check()
retorne 0 0 0 A primeira coisa a fazer é executar devtools::check()
e ter certeza de que não há nenhum erro, nenhum aviso, nenhuma nota.
Se você estiver no RStudio, também pode clicar em Build > Check.
Se alguma vez você achar que esses avisos ou notas não são justificados, deixe um comentário ao enviar, especificando por que você acha que isso não é justificado.
Você pode chamar usethis::use_spell_check()
dentro do seu pacote para adicionar um teste de ortografia. Chame spelling::spell_check_package()
a qualquer momento se precisar executar a verificação ortográfica.
{rhub}
O pacote {rhub}
permite verificar seu pacote em diversas plataformas com a configuração padrão CRAN, usando GitHub Actions.
Execute rhub::rhub_setup()
e siga as instruções.
Mais sobre {rhub}
: https://github.com/r-hub/rhub
Teste se seu pacote é compilado usando a ferramenta win-builder ou com devtools::check_win_devel()
.
Crie e envie manualmente seu arquivo aqui: https://mac.r-project.org/macbuilder/submit.html
Consulte https://github.com/DavisVaughan/extrachecks
Essas verificações podem não capturar tudo o que a equipe CRAN irá capturar, então aqui está uma lista de boas práticas:
Observe que se este for seu primeiro envio, você terá automaticamente uma NOTA, para New submission
.
O envio de uma nova versão pelo CRAN não deve ser feito com muita frequência. Uma vez a cada 30 dias parece ser a regra geral (a menos que você esteja reenviando após o feedback de um membro da equipe CRAN).
Ao reenviar após um feedback do CRAN, certifique-se de incluir que se trata de um reenvio após um feedback e descreva o que você fez.
Se você reenviar após um feedback do CRAN, adicione 1 ao componente patch do número da sua versão (por exemplo, se o seu primeiro envio for 0.3.1, seu reenvio deverá ser 0.3.2).
O CRAN pode rejeitar pacotes que contenham erros gramaticais no DESCRIPTION
. Alguns erros ortográficos comuns:
'
(exemplo: Lorem-Ipsum Helper Function for 'shiny' Prototyping
)API
, não Api
) O arquivo DESCRIPTION
deve ter um cph
(detentor dos direitos autorais). Pode ser o primeiro autor ou a empresa onde o(s) autor(es) trabalha(m).
Isso pode não ser detectado pelo CRAN, mas certifique-se de ter preenchido tudo neste arquivo.
É tentador escrever algo como 'Um manipulador de condições mais amigável para R' ou 'Criação fácil de Dockerfile para R' no título do seu repositório no GitHub (e parece apropriado). A equipe CRAN solicitará que você remova isso, pois é redundante (você está lidando apenas com pacotes R no CRAN).
Escreva um campo de descrição elaborado.
O título deve estar em caixa de título
Letras maiúsculas e minúsculas nos títulos (maiúsculas e minúsculas)
Nota: isso deve ser capturado pelo r-hub.
Um pacote à prova de CRAN deve ter uma longa descrição que explique o que o pacote faz, quais são os benefícios, o que há de novo e como ele difere do que já está no CRAN.
Nem o título nem a descrição devem começar com "Um pacote..." ou com o nome do pacote.
Se você citar outro pacote, um artigo/livro ou um site/API, coloque seu nome entre aspas simples '
. Além disso, os nomes dos pacotes diferenciam maiúsculas de minúsculas. por exemplo, 'brilhante' -> 'Brilhante'.
Se um nome de função for usado em sua DESCRIÇÃO, certifique-se de colocá-lo entre parênteses. por exemplo, "fornece um substituto imediato para cat() do pacote 'base'."
Se você escrever uma interface R para uma API ou implementar um algoritmo de um artigo/livro publicado, adicione uma referência à publicação como DOI, ISBN ou link canônico semelhante, ou URL para a API ou artigo no campo 'Descrição' do seu arquivo DESCRIPTION.
Ao vincular a um artigo ou site na DESCRIÇÃO, use colchetes angulares para vincular automaticamente.
API name or
authors (year) (see )
authors (year)
authors (year, ISBN:...)
sem espaço após https:
, doi:
, arXiv:
e colchetes angulares para vinculação automática.
Todas as funções exportadas no seu pacote devem ter um valor @return
. Se uma função não retornar um valor, documente isso também.
Caso exista uma função interna (não exportada) com documentação parcial (título, and.ou @param
), utilize a tag #' @noRd
para evitar a geração de documentação.
Você pode usar checkhelper::find_missing_tags()
para ajudá-lo a encontrar as tags ausentes em sua documentação. Instale {checkhelper} do GitHub: https://github.com/ThinkR-open/checkhelper
dontrun{}
Os elementos dontrun{}
nos exemplos podem de fato ser executados pelo CRAN. Se você não deseja que um exemplo seja executado, coloque-o entre if (interactive()) {}
. Não coloque o exemplo entre if (FALSE) {}
.
dontrun{}
só deve ser usado se o exemplo realmente não puder ser executado (por exemplo, devido à falta de software adicional, falta de chaves de API, ...) pelo usuário. É por isso que agrupar exemplos em dontrun{}
adiciona o comentário ("# Not run:") como um aviso para o usuário.
Desembrulhe os exemplos se eles forem executáveis em < 5 segundos ou substitua dontrun{}
por donttest{}
.
Observe que donttest{}
será executado por check()
e poderá ser executado por CRAN...
Se houver alguns URLs em sua documentação, certifique-se de:
Você pode usar {urlchecker} para ajudar: https://github.com/r-lib/urlchecker
README.md
, NEWS.md
, LICENSE.md
) Se você tiver URIs relativos apontando para arquivos como NEWS.md
ou CODE_OF_CONDUCT.md
de dentro do README.md
por exemplo:
Code is distributed under the [GPL-3.0-License](LICENSE.md).
Eles gerarão o seguinte erro CRAN:
Found the following (possibly) invalid file URIs:
URI: LICENSE.md
From: README.md
Alterar os links relativos para links absolutos apontando para o site {pkgdown} resolve (consulte o Código de conduta em {dplyr}
README)
Code is distributed under the [GPL-3.0-License](https://USERNAME.github.io/MY_PACKAGE/LICENSE.html).
Apontar para um recurso externo, para uma licença, também funciona (veja o README {golem}
):
Code is distributed under the [GPL-3.0-License](https://www.gnu.org/licenses/gpl-3.0.en.html).
Se você tiver exemplos que levam mais de alguns segundos para serem executados, envolva-os em donttest{}
, não use dontrun{}
.
#' @example
#' donttest{x <- foo(y)}
Não deve haver tags vazias na documentação (para aquela que exige um valor). devtools::check()
detecta saídas @param
e @return
vazias.
Novamente, você pode usar checkhelper::find_missing_tags()
para ajudá-lo a encontrar as tags ausentes em sua documentação. Instale {checkhelper} do GitHub: https://github.com/ThinkR-open/checkhelper
Se você tiver esse problema no CRAN
Warning: attribute "align" not allowed for HTML5
Você pode seguir estas etapas:
https://github.com/DavisVaughan/extrachecks-html5
Estado da política do repositório CRAN:
Os pacotes não devem ser gravados no espaço de arquivos inicial do usuário (incluindo áreas de transferência), nem em qualquer outro lugar do sistema de arquivos além do diretório temporário da sessão R (ou durante a instalação no local apontado pelo TMPDIR: e tal uso deve ser limpo). A instalação na instalação R do sistema (por exemplo, scripts para seu diretório bin) não é permitida.
Talvez você não saiba o que são diretórios/arquivos temporários ou como usá-los. Esses arquivos temporários são criados para a sessão R atual e são excluídos quando a sessão é fechada.
Você pode criá-los com:
file <- tempfile()
Adicione uma extensão com
tmp <- tempfile(fileext = ".csv")
tmp
[1] "/var/folders/lz/thnnmbpd1rz0h1tmyzgg0mh00000gn/T//Rtmpnh8kAc/fileae1e28878432.csv"
Então você pode:
write.csv(iris, file = tmp)
Consulte: Criar nomes para arquivos temporários
Se os pacotes dependem do seu pacote, você deve executar um teste de dependências reversas nos pacotes listados com devtools::revdep()
.
Use {revdepcheck}: https://github.com/r-lib/revdepcheck
# Check reverse dependencies
# remotes::install_github("r-lib/revdepcheck")
usethis :: use_git_ignore( " revdep/ " )
usethis :: use_build_ignore( " revdep/ " )
devtools :: revdep()
library( revdepcheck )
# In another session
id <- rstudioapi :: terminalExecute( " Rscript -e 'revdepcheck::revdep_check(num_workers = 4)' " )
rstudioapi :: terminalKill( id )
# See outputs
revdep_details( revdep = " pkg " )
revdep_summary() # table of results by package
revdep_report() # in revdep/
# Clean up when on CRAN
revdep_reset()
Cria cran-comments.md, um modelo para suas comunicações com o CRAN ao enviar um pacote. O objetivo é comunicar claramente as etapas que você executou para verificar seu pacote em uma ampla variedade de sistemas operacionais. Se você estiver enviando uma atualização para um pacote usado por outros pacotes, também precisará resumir os resultados de suas verificações de dependência reversa.
usethis::use_cran_comments(open = rlang::is_interactive())
Você pode executar devtools::release()
para enviar automaticamente para CRAN de R.
Você receberá um link em sua caixa de correio. Clique neste link para confirmar o upload.
Dependendo da embalagem, pode demorar entre uma hora e várias semanas; se necessitar de inspeção manual, pode demorar algum tempo.
Você pode acompanhar o status do seu pacote com {cransays}
: https://lockedata.github.io/cransays/articles/dashboard.html
Lista de verificação para envios de CRAN
Política de Repositório CRAN
Pacotes R - por Hadley Wickham e Jennifer Bryan
Escrevendo extensões R - documentação oficial
Dominando o desenvolvimento de software em R - por Roger D. Peng, Sean Kross e Brooke Anderson.
Como desenvolver bons pacotes R (para ciência aberta) - por Maëlle Salmon (incluindo lista de tutoriais)
Sinew: Documentação do pacote R simples - por Jonathan Sidi
Pacotes rOpenSci: desenvolvimento, manutenção e revisão por pares - por editores de integração do rOpenSci