Check for unrestored par()/options()/setwd() changes
Source:R/check-option-restoration.R
cl_check_option_restoration.RdFlags a par(), options(), or setwd() call in R/ that changes
state without a paired on.exit() call in the same function frame to
restore it. Per the CRAN Cookbook, packages shouldn't permanently
change a user's graphical parameters, options, or working directory;
if a function has to, it should save the old value and restore it with
on.exit() immediately.
Details
setwd() always counts as a change. For par()/options(), a bare
call with no arguments, or a call whose only arguments are unnamed
(e.g. par("mfrow"), or par(oldpar)/options(oldopts) restoring a
previously-saved list) is treated as a query/restore rather than a
change and isn't flagged; par(no.readonly = TRUE) is also excluded
as it's the standard snapshot-for-later-restore idiom, not a change by
itself.
This is a coarse heuristic: it doesn't check that the on.exit() call
actually restores the same thing that was changed, or that the
restore happens immediately after the change – only that both are
present in the same function frame. A change with no enclosing function
at all is always flagged, since on.exit() couldn't apply there anyway.
Examples
pkg_dir <- cl_example_pkg(
r_files = list(foo.R = c(
"plot_thing <- function() {",
" par(mfrow = c(1, 2))",
" plot(1)",
"}"
))
)
cl_check_option_restoration(pkg_dir)
#> # A tibble: 1 × 6
#> check file line severity message policy_reference
#> <chr> <chr> <int> <ord> <chr> <chr>
#> 1 option_restoration R/foo.R 2 should_fix par() changes st… https://contrib…
unlink(pkg_dir, recursive = TRUE)