Introduction
This vignette contains code and annotations to develop a package, to
prepare for package release, and to set up for a new version. It assumes
the package has been set up as described in the vignette Package
setup:
vignette("pkg_setup", package = "develcoder").
Adding functions
Set up
usethis::use_r("<func>")
devtools::document() # also runs devtools::load_all()
?<func>() # view help-page of the functionDo:
- Manually update the
NEWSfile:### Added functions- `<func>()` to ... - If the added function relies on other packages, you have to update
the dependencies given in the
DESCRIPTIONfile: see section Update dependencies. - When adding new function arguments to an existing function, it is best practice to place the new argument after existing arguments and use a default value that matches the old behaviour: then code written for the old version will work the same as before the change, even if it relies on positional matching, such that it is a non-breaking change.
- When renaming functions, remember to also change their names in the
_pkgdown.ymlfile if that file is used to create a custom index for the website (pkgdown::build_reference()warns about it if you forget).
Documentation
#' Title
#'
#' Description
#'
#' @param x Vector of names to test.
#' @param allow_NA `TRUE` or `FALSE`: allow [NA]s of the correct type in `x`?
#' @param x,y Separate arguments by a comma without a space to create a single
#' description for multiple arguments.
#'
#' @details
#'
#' @returns
#' `TRUE` or `FALSE`, returned [invisibly][invisible].
#'
#' @section Side effects:
#' The directory indicated by the returned path is
#' [created][progutils::create_dir()] if it does not yet exist.
#'
#' @section Notes:
#' Some notes.
#'
#' @section Programming notes:
#' Some programming notes. Create a GitHub issue instead of To do / Wishlist
#' sections.
#'
#' @seealso
#' Section `Details` of [make.names()] and the [\R FAQ about valid names](
#' https://CRAN.R-project.org/doc/manuals/R-FAQ.html#What-are-valid-names_003f)
#' on the syntactical validity of names.
#'
#' @family collections of checks on type and length
#'
#' @examples
#' all_names(x = c("a", "b2a")) # TRUE
#'
#' @export
func_name <- function(x, allow_NA = TRUE) {
stopifnot(checkinput::is_logical(allow_NA))
<...>
}Inherit documentation
It is possible to inherit sections of the documentation from other functions. Inherited sections are silently ignored if that section is also defined in the file itself.
#' @inherit is_number return
#' @inherit is_number details
#' @inheritSection is_logical Programming notes
#' @inheritSection is_logical @noteInherit parameters
It is possible to inherit the description of parameters from other
functions. Since roxygen2 8.0.0, it is possible to specify
which arguments to inherit.
# inherit from a function in the current package
#' @inheritParams is_logical allow_NA
# inherit from a function in another package
#' @inheritParams utils::installed.packages fieldsAdd examples
Examples that create output files should write them to a temporary
directory that is cleaned up afterwards. See the section
Usage in practice in
help("create_tempdir", package = "progutils") and section
Add tests below.
Although examples rendered on a website created with pkgdown will display
the output underneath the code, help-files accessed through
help(<func>) will not, such that it might be useful
to include a short comment regarding what feature of the output is
notable.
To run all examples in a package:
devtools::run_examples()To not run or not display code in examples, you can use the
dontrun and dontshow tags, see the section Examples
from the Writing R Extensions manual
and the section about Examples
in the book R packages.
Styling
Newlines can be forced using \cr.
For an overview of mathematical notation see https://rpruim.github.io/s341/S19/from-class/MathinRmd.html
Add tests
Background
For background on testing:
Unit tests-
Testing basicsand subsequent chapters. -
Code Testingand subsequent chapters. - This curated overview of packages that also includes packages that test non-code aspects (e.g., examples or documentation) and packages that help with generating test suites.
To attach a package during testing, use
devtools::load_all(<pkg>). Alternatively, use
attach(loadNamespace("<pkg>"), name = "<some_name>")
which can be undone by detach("<some_name>").
Cleaning up
Tests that create output files should write them to a temporary
directory that is cleaned up afterwards. See the section
Usage in practice in
help("create_tempdir", package = "progutils") and the
vignette test fixtures
from package testthat for more details. In addition,
changed options and graphical parameters should be restored to their
original state to prevent influencing subsequent code (see the entry
in the CRAN cookbook for details). The following pattern shows how
to do so for a single option or parameter:
orig_opt <- options(<option> = <value>)
orig_par <- par(<parameter> = <value>)
<do stuff>
par(orig_par)
options(<option> = orig_opt)To reset all parameters at once, use
orig_par <- par(no.readonly = TRUE). To restore options
that are changed inside a function, add
on.exit(par(orig_par)) immediately after changing the
option.
Note that expect_silent(...) tests that no errors or
warnings are emitted, not that no messages are
emitted.
tinytest::expect_silent(expect_true(func_name(x = x, arg = arg)))
tinytest::expect_warning(
expect_equal(func_name(x = "a", arg = arg), 3),
pattern = "...", strict = TRUE, fixed = TRUE)
tinytest::expect_error(func_name(x = "a", arg = arg),
pattern = "is_number(x) is not TRUE", fixed = TRUE)The code below shows how to run tests.
# Run all tests of a package. Use 'devtools::test()' instead of
# 'tinytest::test_all()' if you used package 'testthat' to create tests.
tinytest::test_all()
# Run a specific test file, selecting the file by name
tinytest::run_test_file(fs::path(getwd(), "inst", "tinytest", "test_funcname.R"))
# Run specific test files, selecting the files by order
tinytest::run_test_file(
list.files(fs::path(getwd(), "inst", "tinytest"), full.names = TRUE)[1:3])Testing file paths
Testing file paths requires some thought because the file separator
depends on the operating system (see .Platform$file.sep)
and the backward slash is used as escape character in R
such that it needs to be escaped itself by doubling them. Thus, a check
on the presence of two successive slashes or backslashes in string
string would use
grepl(pattern = "//", x = string, fixed = TRUE) and
grepl(pattern = "\\\\", x = string, fixed = TRUE),
respectively. The message to point out their presence would be written
as message("Successive '/' or '\\'") which would be printed
as Successive '/' or '\'.
To circumvent the hassle of getting the correct type and number of
slashes to compare with the path recorded in a message, check only for
fixed parts of the message (e.g., "Repeated"), possibly
followed by a check like
tinytest::expect_true(fs::dir_exists(string)).
Update dependencies
First, you should consider if you really need a new dependency. Some
additional effort in choosing dependencies or in coding can allow to
depend on dependencies that themselves have not too many dependencies,
which makes a project more stable over time. See the various
contributions to the tinyverse.
Importing packages or functions
The standard way to use functions from other packages is to import
the package (i.e., put it in the Imports: field of the
DESCRIPTION file; this is done byusethis::use_package("<pkg>", type = "Imports", min_version = "<version>"))
and in code use the package name followed by two colons and the function
name, e.g., utils::osVersion().
Using two colons to specify the package is not possible if the
function is an operator: then it is necessary to also list the function
in the NAMESPACE file, e.g., to add the line#' @importFrom utils osVersion to the file
R/<pkg>-package.R that was created by
usethis::use_package_doc(). This is done by
usethis::use_import_from(package = "utils", fun = "osVersion").
usethis::use_import_from(package = "utils", fun = "osVersion")
usethis::use_package("utils", type = "Suggests", min_version = "4.1.0")Specifying minimum versions
Specifying a minimum package version when importing packages ensures
that used features are actually present. Setting
min_version = TRUE in usethis::use_package()
uses the currently installed package version but that might be too
strict as features are likely also present in older versions.
To check in which version used features were introduced, you can
search the NEWS file of the relevant package for the
function name to find the news item announcing its introduction. If that
does not work, you can search for the function R file on the GitHub-page
of the package and look in its history to see when it was created (or
use the Blame feature to get a fine-grained overview of
when code in that file was changed to see when a feature was
introduced). Finally, you can also specify different minimum package
versions in checks through GitHub actions and iteratively change them to
find the minimum version that passes the check. Then specify that
version as minimum version in your DESCRIPTION file.
Since R 4.6.0, read.dcf() recognises lines
starting with # as comment lines, making it possible to use
comments in the DESCRIPTION file to indicate why a
particular package version is needed.
# Declare a minimum version for R itself
usethis::use_package("R", type = "Depends", min_version = "4.1.0")
# Declare a dependency on a package: 'use_package()' to declare a minimum
# version and 'use_dev_package()' to specify the remote repository to download
# the package from.
utils::packageVersion("checkinput")
usethis::use_package(package = "checkinput", type = "Imports", min_version = TRUE)
usethis::use_dev_package(package = "checkinput", type = "Imports",
remote = "github::JesseAlderliesten/checkinput")
utils::packageVersion("progutils")
usethis::use_package(package = "progutils", type = "Imports", min_version = TRUE)
usethis::use_dev_package(package = "progutils", type = "Imports",
remote = "github::JesseAlderliesten/progutils")
devtools::document()Do:
- Add the minimum declared
Rversion to workflows for GitHub Actions, see the section Use GitHub Actions.
Adding vignettes
Set up
usethis::use_vignette("my_vignette", title = "Some title")
# Add suggested dependencies on 'knitr' and 'rmarkdown'
usethis::use_package(package = "knitr", type = "Suggests")
usethis::use_package(package = "rmarkdown", type = "Suggests")
devtools::document()
pkgdown::build_article()
browseVignettes(package = basename(getwd()))If no vignettes are visible after running
browseVignettes(package = basename(getwd())),
devtools::install() was probably run with the default
argument build_vignettes = FALSE, use
build_vignettes = TRUE instead:
devtools::install(quick = FALSE, upgrade = FALSE, build_vignettes = TRUE).
Run tools::pkgVignettes(package = "<pkg>") for
information about the vignettes that R finds.
Use utils::vignette("<vignette_title>") (e.g.,
utils::vignette("pkg_devel")) to render a vignette in the
help pane of RStudio. To do so with an Rd
file, use tools::Rd2txt("path/to/file.Rd").
Styling
See the vignette RMarkdown and knitr:
vignette("rmarkdown_knitr", package = "develcoder")) on
using RMarkdown to style vignettes.
Put the next lines in the header of vignettes to get a table of contents:
output:
rmarkdown::html_vignette:
toc: true
toc_depth: 3Linking
- Link to another section in the same document:
[<link text>][<Section title>]or[<Section title>]. - Link to a help page of a package:
help("<func>", package = "<pkg>")(unfortunately,help("<pkg>::<func>")does not work). - Link from a help-page to a vignette:
The vignette *<vignette title>*: `vignette("<vignette>", package = "<pkg>")` - Link to another vignette in the same package:
[<link text>](<vignette_filename>.html)
There is no
official way to link from vignettes to help-pages or vice versa.
pkgdown recognises calls like `<func>()`
and `<pkg>::<func>()`, such that relevant links
for such calls will be created on a package website (see the documentation
for details).
Adding miscellaneous files
Non-standard files or folders should be added in the
inst directory to pass R CMD checks.
Those files and folders will be in the top directory in the installed
package.
Preparing for updates
Check tests
Check if there are functions for which no test file was written and
run all test files. Use devtools::test() instead of
tinytest::test_all() if you used package testthat to create tests.
devtools::document()
tinytest::test_all() # or devtools::test() if testthat was used to create tests
develcoder::check_tests() # character(0) if all is fineAutomated checks
tools::CRAN_check_results(),
tools::CRAN_check_details() and
tools::CRAN_check_issues() give information about the
current check status of CRAN packages. cransays (source
code here) provides
information about the status of packages during package submission to
CRAN.
The next sections provide code to run checks from various packages.
devtools (local)
The default devtools::check() from devtools should
be run often. devtools::check() uses the preferred approach
of first building the package before checking it, whereas rcmdcheck::rcmdcheck()
does not but is able to compare output from different checks.
See the CRAN
cookbook and the appendix R-CMD-check
from the book ‘R packages’ on how to proceed if checks fail.
The call to devtools::check() used below is more strict
than the default, following suggestions from the Writing
R extensions manual and from R
packages (see the manual
for details about the environment variables):
Using
manual = TRUEto build and check the manual.-
Using
remote = TRUE(and thusincoming = TRUE) to run additional checks that are used by CRAN for new package submissions.These checks flag dependencies that are on GitHub, leading to NOTEs like
Strong dependencies not in the CRAN or BioC software repositories: <pkg>,Suggests or Enhances not in mainstream repositories: <pkg>, andUnknown, possibly misspelled, fields in DESCRIPTION: 'Remotes'.
If you do not intend to submit to CRAN, you can ignore these NOTEs.These checks also identify problems with linked URLs (i.e., not with URLs in comments). URLs:
- should be accessible (e.g., point to public GitHub repositories, not to private repositories)
- should be direct links, not redirects
- should use the protocol
https://instead ofhttp:// - should use the canonical forms expected by CRAN, not the ‘simple’
forms displayed in the webbrowser:
-
https://CRAN.R-project.org/package=<pkg>for packages -
https://CRAN.R-project.org/manuals.htmlto refer to manuals in general and URLs of the formhttps://CRAN.R-project.org/doc/manuals/r-release/R-exts.htmlto refer to a specific manual -
https://CRAN.R-project.org/web/packages/policies.htmlto refer to the CRAN policies.
-
Using
TRUEfor environment variable_R_CHECK_DEPENDS_ONLY_to run code while only using dependencies listed in theDependsandImportsfields of theDESCRIPTIONfile. This catches cases where a package that is listed in theSuggestsfield of theDESCRIPTIONfile is used in a vignette without being run conditionally throughif(requireNamespace(<pkg>)) {<code>}.Using
TRUEfor environment variable_R_CHECK_SUGGESTS_ONLY_to run code while only using dependencies listed in theDepends,ImportsandSuggestsfields of theDESCRIPTIONfile.
devtools::document()
devtools::check(manual = TRUE, remote = TRUE)
devtools::check(manual = TRUE, remote = TRUE,
env_vars = c("_R_CHECK_DEPENDS_ONLY_" = TRUE,
"_R_CHECK_SUGGESTS_ONLY_" = TRUE))
devtools::release_checks()
if(utils::packageVersion("devtools") >= "2.5.0") {
# check for missing `\value` and `\examples` fields in `Rd` files
devtools::check_doc_fields()
}devtools (remote)
The following checks might be used to check the package on Windows or
MacOS, respectively. devtools::check_win_release() emails a
link to a webpage with the check results if the check is done.
devtools::check_mac_release() links to a webpage where the
results are shown if the check is done (the webpage might display ‘504
Gateway Time-out’ if it has not finished yet).
These checks might malfunction if your package has dependencies that
are not on CRAN or BioConductor. Such dependencies should have been
flagged above by
devtools::check(manual = TRUE, remote = TRUE) as
not in the CRAN or BioC software repositories or as
not in mainstream repositories.
devtools::check_win_release()
devtools::check_mac_release()codetools
Check R code for possible problems.
devtools::load_all()
# Return is invisible and silent if all is well
codetools::checkUsagePackage(pack = basename(getwd()),
all = TRUE, suppressParamAssigns = TRUE)utils
Spell checking. This requires system libraries like Aspell.
utils::aspell_package_Rd_files(dir = getwd())
utils::aspell_package_vignettes(dir = getwd())goodpractice
Runs checks of its own and checks from various other packages.
I do not use pkgcheck::pkgcheck()
because their ‘own’
checks are largely covered by the checks from devtools
used above, their checks from
goodpractice are already covered here (see also this
post on the relation between goodpractice and
pkgcheck), and the checks from pkgstats
are not very useful and require system libraries
ctags-universal and GNU global. However, the
pkgcheck GitHub
action (see also here) might be
useful.
# Select checks
# Show groups of checks: goodpractice::all_check_groups()
# Show all checks in some groups: goodpractice::checks_by_group(c("cyclocomp", "lintr"))
# Run all check from some groups:
# goodpractice::goodpractice(checks = goodpractice::checks_by_group(c("cyclocomp", "lintr")))
goodpractice_all_checks <- goodpractice::all_checks()
my_checks_goodpractice <- progutils::not_in(
goodpractice_all_checks,
c("covr", # time-consuming and wants 100% coverage
"complexity_function_length", "cyclocomp", # I write complex functions
# The lintr issue `Use == instead of %in% for scalar comparison` should be
# ignored for 'x %in% y' if 'x' or 'y' might contain 'NA' that should be
# removed: 'x %in% NA' and 'NA %in% y' return 'FALSE', whereas 'x == NA' and
# 'NA == y' return 'NA'.
"lintr_scalar_in_linter",
"lintr_line_length_linter",
"lintr_outer_negation_linter", # changes handling of NAs
# flags data.frame() even if 'strings_as_factors' is not explicitly set
"lintr_strings_as_factors_linter",
"tidyverse_brace_linter",
"tidyverse_function_left_parentheses_linter",
"tidyverse_indentation_linter",
"tidyverse_line_length_linter",
"tidyverse_object_name_linter",
"tidyverse_spaces_left_parentheses_linter",
# does not find test-files in inst/tinytest, use check_test_files() instead.
"tidyverse_test_file_names",
"tidyverse_whitespace_linter",
# Checks similar to those from 'rcmdcheck' and 'urlchecker' are also used by
# devtools::check() that already has been run above
goodpractice_all_checks[
grepl(pattern = "^rcmdcheck_|^urlchecker_", x = goodpractice_all_checks)]
)
)
res_goodpractice <- goodpractice::goodpractice(
path = ".", checks = my_checks_goodpractice)
res_goodpractice_failed <- goodpractice::failed_checks(res_goodpractice)
res_goodpractice_failed
# Can also show output of selected checks through
# res_goodpractice$checks$<check_name>
res_goodpracticeUpdate package-wide documentation
DESCRIPTION
Run desc::desc_normalize() to normalize the
DESCRIPTION file:
desc::desc_normalize()To show the DESCRIPTION file, use
desc::desc() or
utils::packageDescription(pkg = basename(getwd())). To only
show the dependencies, use desc::desc_get_deps() or
utils::packageDescription(pkg = basename(getwd()), fields = c("Depends", "Imports", "Suggests", "Enhances")).
Manually increment the package version in the
DESCRIPTION file, or run R as administrator
and then use usethis::use_version(). In the latter case, do
not automatically commit the change, but
do so manually to adjust the commit message to
Bump to version x.y.z. Indicating the version number in the
commit title makes it easier to find changes back later on (the pull
request can have a description of the changes, i.e., the updated section
of the NEWS file). See package lifecycle
on how to add badges to packages and functions to indicate their
lifecycle and its vignette Lifecycle stages,
chapter Lifecycle, and
the Semantic Versioning Specification
on versioning.
CITATION
Update the CITATION.cff file to reflect the new package
version (this code updates the citation file if it exists and otherwise
uses the DESCRIPTION file to create a citation file):
cffr::cff_write(dependencies = FALSE) # Create or update a citation fileREADME
Install the development version of the package by running
devtools::install() to ensure the updated version number
without Git-commit ID will be included in the citation format in the
README:
devtools::install(quick = FALSE, upgrade = FALSE, build_vignettes = TRUE)Then Knit the README.Rmd to produce a
README.md file. The citation in the README
should then display the updated version number. The version badge at the
top will still display the old version number, but that will change to
the updated number when pushed to GitHub.
If the requirement that README.Rmd and
README.md are staged at the same time was accidentally
introduced, delete the the (hidden) file
.git/hooks/pre-commit from the R-project folder (see the
Description section in
help("use_readme_rmd", package = "usethis") to remove that
requirement.
Check reverse dependencies
Acknowledgement
This section reproduces a contribution by Ivan Krylov to the R-pkg-devel mailing list of 26 May 2026.
To check if packages that use your package still pass their checks if
you made breaking changes, install the new version of your package, run
tools::package_dependencies(reverse = TRUE, which = "most", recursive = "strong")
to get the list of reverse dependencies, then use
utils::download.packages(...) to obtain their latest
tarballs and finally run tools::check_packages_in_dir() to
check them.
tools::package_dependencies() and the related
tools::dependsOnPkgs() only take packages from CRAN into
account.
devtools::revdep(pkg = <your pkg>, bioconductor = TRUE)
also takes packages from BioConductor into account. To take
other non-CRAN packages into account, use revdepcheck::revdep_check()
or xfun::rev_check()
(which has a GitHub Action: crandalf). If you find
reverse dependencies that broke because of your changes, you can
identify their maintainers using
devtools::revdep_maintainers(pkg = <your pkg>) to
notify them.
Locally test update
devtools::document()
.libPaths() # Check if output of .libPaths() is correct.
# If the next line leads to the error 'lazy-load database
# '.../R/win-library/<X.Y>/<pkg>/R/<pkg>.rdb' is corrupt', you should restart R
# and again run the next line.
devtools::install(quick = FALSE, upgrade = FALSE, build_vignettes = TRUE)
# Load the package and view the help files as usual outside devtools:
library(basename(getwd()), character.only = TRUE)
browseVignettes(package = basename(getwd()))
?progutils::reorder_levelsUpdating
Use GitHub Actions
To manually trigger GitHub Actions (GHA) set up
workflow_dispatch (see section Automate checks
in the vignette Package setup:
vignette("pkg_setup", package = "develcoder")).
To check if a reverse dependency (i.e., a package that depends on a
package you changed) that you created is still working fine: go to the
Actions tab of the reverse dependency, select the action
you want to trigger (e.g., check-standard.yaml), and use
the Run workflow button shown at the top of the overview
with workflow runs to run the GHA. You can select which branch it should
run on but need to trigger it once manually on the main
branch to be able to trigger it manually on other branches.
Scheduled jobs that failed can be rerun through the button
Re-run jobs > Re-run failed jobs >
Re-run jobs. If the GitHub actions page (e.g., https://github.com/JesseAlderliesten/develcoder/actions)
indicates the package passes the R CMD checks
whereas the badge on the README indicates it fails, make
sure the R CMD check considers the main branch
(i.e., if the devel branch passes but the main
branch fails, the badge will have failing): use the
Run workflow button to run the GHA on the main
branch (see the previous paragraph).
If the package declares a dependency on a minimum R
version, it is useful to specify the minimum declared R
version to run in addition to the ones that are by default used in the
template: for example, add
- {os: ubuntu-latest, r: '4.1.0'} to section
matrix: config: to also run the workflow with
R 4.1.0 if your package declares R 4.1.0 as
minimum version.
GHA: documentation and help
For more background on GitHub Actions, including an explanation of
the syntax used in .yaml files, see the section about GitHub Actions
in the book R packages,
the GitHub reference
and HowTo,
and the section Use GitHub Actions in the vignette
Package development:
vignette("pkg_devel", package = "develcoder").
For help debugging build failures, see the Appendix R-CMD-check
in the book R packages
and the section Where to find
help in the documentation of the actions
package.
pkgdown website
See the documentation about package pkgdown and the chapter from the
R packages book for further details.
# To manually update the website
pkgdown::build_site()Open docs/index.html in a web browser to preview the
website, or look at the files that constitute your package’s website are
in the local docs directory.
Instead of manually updating the pkgdown website, one can use a GitHub Action workflow (e.g., pkgdown.yaml)
that updates the website after a pull request or push. To set this up,
run usethis::use_pkgdown_github_pages().
Styling
To create a thematic index instead of the default alphabetically ordered one, see the documentation and the example.
To customise the order in which Articles are listed,
specify their order in the _pkgdown.yml file (run
tools::pkgVignettes(package = "<pkg>")$names to get
their names; see the documentation
and for example the _pkgdown.yml file
and non-alphabetical order of the articles
in the checkrpkgs package.
To create a custom function index, include a section
reference: in the _pkgdown.yml file with the
desired headings and topics, see the documentation,
an official
example, and my
own example. Then build the reference with
pkgdown::build_reference() and view it locally by opening
the file "<pkg>\docs\index.html" and browse to
Reference to see the package index.
Merge devel-branch with main
To merge the devel branch with main (i.e.,
to incorporate the changes you made to the devel branch in
the main branch), go the the devel branch on
GitHub. Then use <Contribute> >
Open Pull Request. Copy the updated NEWS in
the description field and use the button
Create pull request.
If the message
No conflicts with base branch: Merging can be performed automatically,
is displayed, you can use the green Merge pull request
button, or change to Squash and merge.
Otherwise, the message
This branch has conflicts that must be resolved will be
displayed: follow the instructions to resolve the conflicts. Then push
the button Commit merge. Then you should see
No conflicts with base branch and you can proceed as
described in the previous paragraph.
After a successful merge, you will see a message that you can delete
the devel-branch, which you can do. To do so later, go to
Pull requests, select the Closed tab, and
scroll down to the button Delete branch.
Overwrite devel-branch after merge
In RStudio, open the relevant project to check there are no commits
left. Then you can move to the main branch and
Pull to get all updates you just committed to the
main branch. Then click the New branch button
in RStudio (besides the Switch branch icon indicating which
branch (e.g., main or devel) you are using),
use devel as branch name and click Create. You
will be notified that devel already exists and asked if you
want to overwrite it. If you have just merged
devel into main, you can choose to overwrite
it to have a new devel branch.
Set up a new branch
Instead of overwriting the devel-branch after merging
into main, you can also create a completely new branch:
- At the GitHub page of the package:
Branchicon > greenNew branchbutton > specify a name for the branch > greenCreate new branchbutton. - Go back to the GitHub page of the package, and at the green
Codebutton >copy URL to clipboard. - In RStudio:
File>New project>Version control>Gitand paste the copied URL in theRepository URL>Create Project. - Then (still in RStudio) in the
Gitmenu change frommainto the just-created branch.
Installing the updated package
Then you can delete the old package version from your PC
(find.package("<pkg>") gives its location) and
install the updated version following your own instructions on the
GitHub pages of the relevant packages.
Troubleshooting
-
If running checks lead to the warning
Warning in get_engine(options$engine): Unknown language engine '<name>' (must be registered via knit_engines$set()), you probably forgot to indicate the knit-engine when naming a code chunk:```{use-sum} 1 + 1 ```erroneously tries to use the engine
use-sum, whereas the probably intended{r use-sum}correctly indicates that therengine should be used and the code chunk should be nameduse-sum:```{r use-sum} 1 + 1 ```See
sort(names(knitr::knit_engines$get()))for the available knit-engines. If running checks lead to the error
Failed with error: 'there is no package called '<pkg>''Quitting from <filename>.Rmd:<line numbers> [<chunk name>], you probably forgot to uselibrary(<pkg>)in a code chunck, used a package that is not declared as dependency in theDESCRIPTIONfile, or used a package that is declared as suggested dependency (i.e., is in theSuggestsfield of theDESCRIPTIONfile) without running that code conditionally on the presence of<pkg>throughif(requireNamespace(<pkg>)) {<code>}. The latter is catched by using argumentenv_vars = c("_R_CHECK_DEPENDS_ONLY_" = TRUE)when runningdevtools::check().If checks fail because of
LaTeXerrors when building the manual, you can usemanual = FALSE.If running
devtools::document()leads to the error@section Could not resolve link to topic ":blank:" in the dependencies or base packages,regex-classes in example code are being interpreted as links. To prevent this, use backticks (`) to format a line as code, or wrap consecutive lines in\code{...}`.Errors can arise if package development is not done from a clean R session. Use
loadedNamespaces()to check which packages are loaded.See also section
Troubleshootingin the vignette about R packages in packagecheckrpkgs: Troubleshooting
Documentation and help
Guidelines on package development
- The
Writing R extensionsmanual, which is the official guide on extending R - The
CRAN Repository policy(with an overview of changes here) andBioConductor package guide, which are the official guides for CRAN and BioConductor - The
blueprints for software developmentfrom EpiverseTrace - The
R development guidefrom the R Contribution Working Group - The
package development guide, theStatistical Software Peer Reviewguide, and a sectionPublish packagesin theR universe documentationfrom rOpenSci
Other useful resources
- The
CRAN cookbook - The book
R packagesby Wickham and Bryan - The book
R in productionby Wickham and Masiello - The chapter
Building R PackagesofMastering Software Development in Rby Peng, Kross, and Anderson - The website
What They Forgot to Teach You About R - The R
developer pagewithdeveloper guidelinesandtechnical documentation - The
cheatsheetabout package development by Posit - The package
checkrpkgsthat explains how to get information about to-be-installed and already-installed packages, and how to get the source code of R functions -
Package Development and Maintenance(currently a proposal for aCRAN Task View) with an annotated thematic collection of R packages that assist in developing R packages - The R
NEWSfor the development branch - Chapters from Advanced R.