| Title: | Deal with Check Outputs |
|---|---|
| Description: | Deal with packages 'check' outputs and reduce the risk of rejection by 'CRAN' by following policies. |
| Authors: | Vincent Guyader [aut, cre] (ORCID: <https://orcid.org/0000-0003-0671-9270>), Sebastien Rochette [aut] (ORCID: <https://orcid.org/0000-0002-1565-9313>, previous maintainer), Arthur Bréant [aut] (ORCID: <https://orcid.org/0000-0003-1668-0963>), Murielle Delmotte [aut] (ORCID: <https://orcid.org/0000-0002-1339-2424>), ThinkR [cph] |
| Maintainer: | Vincent Guyader <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.0.9000 |
| Built: | 2026-05-17 16:57:09 UTC |
| Source: | https://github.com/ThinkR-open/checkhelper |
Writes the rewritten file in place (unless dry_run = TRUE). Files that
do not contain any non-ASCII characters are skipped without rewriting,
so file mtimes stay clean.
asciify_file( path, strategy = c("auto", "escape", "translit", "report"), identifiers = c("error", "warn", "skip"), dry_run = FALSE )asciify_file( path, strategy = c("auto", "escape", "translit", "report"), identifiers = c("error", "warn", "skip"), dry_run = FALSE )
path |
path to a file. Suffixes |
strategy |
one of:
|
identifiers |
what to do when a non-ASCII identifier (variable, function name, formal, slot...) is found:
|
dry_run |
logical. If |
invisibly, a list with:
path: path of the file
changed: TRUE if the file was rewritten (or would be in dry-run)
n_chars: number of non-ASCII characters in the file
n_tokens: number of distinct source locations to rewrite
(an accented string literal counts once regardless of how many
non-ASCII characters it contains)
text: rewritten content if changed, else the original
Rewrite non-ASCII characters inside a string of R source code
asciify_r_source( text, strategy = c("auto", "escape", "translit", "report"), identifiers = c("error", "warn", "skip") )asciify_r_source( text, strategy = c("auto", "escape", "translit", "report"), identifiers = c("error", "warn", "skip") )
text |
character(1), the full source of an R script. |
strategy |
one of:
|
identifiers |
what to do when a non-ASCII identifier (variable, function name, formal, slot...) is found:
|
This function does not touch identifiers, even with
identifiers = "skip": CRAN's policy is to forbid non-ASCII identifiers,
but rewriting them automatically is unsafe (it would silently rename the
user's exported API). Use find_nonascii_tokens() to surface them.
Strings declared with the R 4.0 raw form (r"(...)", R"---(...)---")
are detected - by default they are still treated like regular STR_CONST
(escaped); pass strategy = "translit" if you want to keep them raw and
lose the accents instead.
character(1), the rewritten source code. The original is returned unchanged if no non-ASCII tokens are found.
src <- ' # accent dans un commentaire: ete x <- "deja vu" ' cat(asciify_r_source(src))src <- ' # accent dans un commentaire: ete x <- "deja vu" ' cat(asciify_r_source(src))
Lists every line containing non-ASCII bytes across the package files.
CRAN raises a NOTE when source code or documentation contains non-ASCII
characters that are not properly escaped. Wraps find_nonascii_files().
audit_ascii( pkg = ".", scope = c("R", "tests", "vignettes", "man", "DESCRIPTION", "NAMESPACE"), ignore_ext = c("png", "jpg", "jpeg", "gif", "rds", "rda", "rdata", "pdf", "ico", "svg"), size_limit = 5e+05 )audit_ascii( pkg = ".", scope = c("R", "tests", "vignettes", "man", "DESCRIPTION", "NAMESPACE"), ignore_ext = c("png", "jpg", "jpeg", "gif", "rds", "rda", "rdata", "pdf", "ico", "svg"), size_limit = 5e+05 )
pkg |
Path to the package to audit. |
scope |
Character vector of subdirectories / files to scan. |
ignore_ext |
Extensions to skip (binary assets, snapshots). |
size_limit |
Skip files larger than this many bytes. |
A data frame with columns file, line, text, n_tokens.
fix_ascii() to apply the rewrite, find_nonascii_files().
## Not run: pkg <- create_example_pkg() audit_ascii(pkg) ## End(Not run)## Not run: pkg <- create_example_pkg() audit_ascii(pkg) ## End(Not run)
Invokes R CMD check with the env vars and options used by CRAN's
incoming-pretest scripts, so local checks match CRAN as closely as
possible. Wraps check_as_cran().
audit_check( pkg = ".", check_output = file.path(dirname(normalizePath(pkg, mustWork = FALSE)), "check"), scratch = tempfile("scratch_dir"), Ncpus = 1, as_command = FALSE, clean_before = TRUE, open = FALSE, repos = getOption("repos") )audit_check( pkg = ".", check_output = file.path(dirname(normalizePath(pkg, mustWork = FALSE)), "check"), scratch = tempfile("scratch_dir"), Ncpus = 1, as_command = FALSE, clean_before = TRUE, open = FALSE, repos = getOption("repos") )
pkg |
Path to the package to check. |
check_output |
Where to store check outputs. |
scratch |
Where to store temporary files. |
Ncpus |
Number of CPUs. |
as_command |
Run as Linux command line instead of in R.
Currently a no-op: the |
clean_before |
Wipe |
open |
Open the check directory at the end. |
repos |
Repositories used for dependency resolution. |
The rcmdcheck results object.
## Not run: audit_check(".") ## End(Not run)## Not run: audit_check(".") ## End(Not run)
inst/CITATION for old-style calls flagged by CRANSurfaces every call to personList(), as.personList() or
citEntry() in the package's inst/CITATION file, with the line
number and a one-line suggestion of the modern equivalent. CRAN
rejects new submissions whose CITATION file still uses these
(Package CITATION file contains call(s) to old-style ...).
audit_citation(pkg = ".")audit_citation(pkg = ".")
pkg |
Path to the package to audit. |
Detection is purely static (parse + token walk via
utils::getParseData()), so it does not source the file and never
executes user code.
A tibble with columns call, line, suggestion. Empty
when the file is modern, or when there is no inst/CITATION.
## Not run: audit_citation(".") ## End(Not run)## Not run: audit_citation(".") ## End(Not run)
Lists every dataset under data/ and reports whether a roxygen
documentation file is found in R/. CRAN raises a NOTE for undocumented
datasets.
audit_dataset_doc(pkg = ".")audit_dataset_doc(pkg = ".")
pkg |
Path to the package to audit. |
A tibble with columns name and has_doc.
## Not run: audit_dataset_doc(".") ## End(Not run)## Not run: audit_dataset_doc(".") ## End(Not run)
Description fieldCRAN policy: package names (and software names in general) inside
the Description field of a DESCRIPTION file must be wrapped in
single quotes (e.g. 'jsonlite', 'httr'). An unquoted package
name produces the
Package names should be quoted in the Description field
warning on CRAN incoming pretest.
audit_description(pkg = ".")audit_description(pkg = ".")
pkg |
Path to the package to audit. |
audit_description() reads the Description field, tokenises it,
and surfaces every word that matches an installed package name yet
is not wrapped in single quotes. Detection is purely static: no
package is loaded, no namespace is touched.
A tibble with columns word, position and suggestion.
Empty when every match is already quoted, when the Description
field is plain prose, or when the package has no DESCRIPTION.
## Not run: audit_description(".") ## End(Not run)## Not run: audit_description(".") ## End(Not run)
\dontrun{} blocks across the package's Rd filesSurfaces every \dontrun{} block in man/*.Rd, with the source
Rd file, the documented topic, the line number, and a one-line
suggestion of the modern equivalent. CRAN policy is that
\dontrun{} should only wrap example code that genuinely cannot
be executed (missing API key, missing system dependency, side
effect on the user's filespace). The contributor should otherwise
use \donttest{}, which still gets exercised by
R CMD check --run-donttest but is skipped by default.
audit_dontrun(pkg = ".")audit_dontrun(pkg = ".")
pkg |
Path to the package to audit. |
Detection is purely static: each Rd file is read line-by-line and
the literal \dontrun{ opener is matched (commented-out forms
starting with % are ignored). The function never sources the
file and never executes user code.
A tibble with columns rd_file, topic, line,
suggestion. Empty when the package has no \dontrun{}
blocks, or when there is no man/ directory.
## Not run: audit_dontrun(".") ## End(Not run)## Not run: audit_dontrun(".") ## End(Not run)
CRAN policy: package code that downloads files or hits the network
at install / runtime must degrade gracefully when the network is
unavailable (offline build farms, sandboxed CI, locked-down user
environment). Common rejection causes: downloads from inside
.onLoad(), .onAttach(), vignettes or examples that have no
tryCatch() / skip_if_offline() / \dontrun{} guard.
audit_downloads(pkg = ".")audit_downloads(pkg = ".")
pkg |
Path to the package to audit. |
audit_downloads() walks R/, tests/, vignettes/ and inst/
and surfaces every call to a known download or HTTP function so
the dev can review each one. Detection is purely static: each file
is parsed and the AST is walked; nothing is sourced.
A tibble with columns file, line, function and
suggestion. Empty when no download call is found, or when the
package has none of the watched directories.
## Not run: audit_downloads(".") ## End(Not run)## Not run: audit_downloads(".") ## End(Not run)
Runs R CMD check on the package and extracts every
no visible binding for global variable and no visible global function
note. Use fix_globals() to print or write the corresponding
globalVariables() block. Wraps get_no_visible().
audit_globals(pkg = ".", checks = NULL)audit_globals(pkg = ".", checks = NULL)
pkg |
Path to the package to audit. |
checks |
Optional. A pre-computed |
A list with three tibbles, globalVariables, functions
and operators, or NULL if the package has no global notes.
globalVariables collects names that need a
utils::globalVariables() declaration; functions collects
external functions to import via @importFrom; operators
collects NSE tokens / data.table / rlang pronouns (:=,
.SD, .data, !!, ...) that also need @importFrom rather
than a globalVariables() entry.
fix_globals(), get_no_visible().
## Not run: pkg <- create_example_pkg() # One-shot: audit_globals(pkg) # Shared check (avoid running R CMD check twice): chk <- rcmdcheck::rcmdcheck(pkg) audit_globals(pkg, checks = chk) fix_globals(pkg, checks = chk) ## End(Not run)## Not run: pkg <- create_example_pkg() # One-shot: audit_globals(pkg) # Shared check (avoid running R CMD check twice): chk <- rcmdcheck::rcmdcheck(pkg) audit_globals(pkg, checks = chk) fix_globals(pkg, checks = chk) ## End(Not run)
Reports exported functions that lack @return, and documented internal
functions that lack @noRd (these trigger CRAN's
Please add \value to .Rd files message). Wraps find_missing_tags().
audit_tags(pkg = ".")audit_tags(pkg = ".")
pkg |
Path to the package to audit. |
A list with three tibbles: package_doc, data, functions.
## Not run: pkg <- create_example_pkg() audit_tags(pkg) ## End(Not run)## Not run: pkg <- create_example_pkg() audit_tags(pkg) ## End(Not run)
Runs the package's tests, examples, vignettes and full check, and lists
files that were created or modified outside the check directory. CRAN
raises a NOTE for "non-standard things in the check directory". Wraps
check_clean_userspace().
audit_userspace(pkg = ".", check_output = tempfile("dircheck"))audit_userspace(pkg = ".", check_output = tempfile("dircheck"))
pkg |
Path to the package to audit. |
check_output |
Where to store check outputs (defaults to a tempfile). |
A tibble of leaked files with columns
source, problem, where, file.
## Not run: pkg <- create_example_pkg() audit_userspace(pkg) ## End(Not run)## Not run: pkg <- create_example_pkg() audit_userspace(pkg) ## End(Not run)
Splits the work between devtools::check(args = "--no-tests")
(the static / install / vignette parts of R CMD check) and
covr::package_coverage(type = "tests") (the test runner, with
coverage instrumentation). The unit tests run exactly once, on
the coverage side, instead of twice (once for the check, once
for the coverage). On a package with a slow suite this halves
the wait.
check_n_covr(pkg = ".", args = character(0), quiet = TRUE)check_n_covr(pkg = ".", args = character(0), quiet = TRUE)
pkg |
Path to the package. |
args |
Character vector of extra args passed to
|
quiet |
Logical. Forwarded to both inner runners
( |
A named list with two elements:
check: the rcmdcheck result returned by
devtools::check().
coverage: the package_coverage object returned by
covr::package_coverage().
## Not run: res <- check_n_covr(".") res$check covr::percent_coverage(res$coverage) ## End(Not run)## Not run: res <- check_n_covr(".") res$check covr::percent_coverage(res$coverage) ## End(Not run)
Create a package example producing notes and errors
create_example_pkg( path = tempfile(pattern = "pkg-"), with_functions = TRUE, with_extra_notes = FALSE, with_nonascii = FALSE, with_undocumented_data = FALSE )create_example_pkg( path = tempfile(pattern = "pkg-"), with_functions = TRUE, with_extra_notes = FALSE, with_nonascii = FALSE, with_undocumented_data = FALSE )
path |
Path where to store the example package |
with_functions |
Logical. Whether there will be functions or not (with notes) |
with_extra_notes |
Logical. Whether there are extra notes or not |
with_nonascii |
Logical. If |
with_undocumented_data |
Logical. If |
Path where the example package is stored.
create_example_pkg()create_example_pkg()
Parses text with base::parse() and utils::getParseData() and returns
the token rows whose source text is not pure ASCII. Used as the building
block of asciify_r_source() and asciify_pkg().
find_nonascii_tokens(text)find_nonascii_tokens(text)
text |
character(1), R source code (one element, possibly with embedded newlines). |
Compared to a hand-rolled regex (e.g. the one used by dreamRs/prefixer),
this catches every relevant context exactly once: string literals,
comments, identifiers, numeric literals, etc., without false matches on
lookalike characters that appear inside larger tokens.
a data.frame, the subset of getParseData() whose text field
contains at least one non-ASCII byte. An extra logical column
is_identifier flags symbol-like tokens that should not be auto-rewritten.
asciify_r_source() to apply the rewrite,
find_nonascii_files() to scan a whole directory.
Escapes non-ASCII string literals to \uXXXX and transliterates
comments / roxygen so the package passes CRAN's "non-ASCII characters"
check. Dry-run by default: pass dry_run = FALSE to actually rewrite
files. Wraps asciify_pkg().
fix_ascii( pkg = ".", scope = c("R", "tests", "vignettes"), strategy = c("auto", "escape", "translit", "report"), identifiers = c("error", "warn", "skip"), dry_run = TRUE )fix_ascii( pkg = ".", scope = c("R", "tests", "vignettes"), strategy = c("auto", "escape", "translit", "report"), identifiers = c("error", "warn", "skip"), dry_run = TRUE )
pkg |
Path to the package to rewrite. |
scope |
Subdirectories to rewrite. |
strategy |
Rewrite strategy (see |
identifiers |
What to do when a non-ASCII identifier is found. |
dry_run |
If |
Invisibly, a data frame of the changes per file.
## Not run: pkg <- create_example_pkg() fix_ascii(pkg, dry_run = TRUE) ## End(Not run)## Not run: pkg <- create_example_pkg() fix_ascii(pkg, dry_run = TRUE) ## End(Not run)
Writes R/{prefix}{name}.R with a roxygen documentation skeleton for the
data/{name}.rda dataset. Wraps use_data_doc().
fix_dataset_doc( name, pkg = ".", prefix = "doc_", description = "Description", source = "Source", overwrite = FALSE )fix_dataset_doc( name, pkg = ".", prefix = "doc_", description = "Description", source = "Source", overwrite = FALSE )
name |
Name of the dataset (without extension). |
pkg |
Path to the package. |
prefix |
Prefix for the generated R file. Defaults to |
description |
Description shown in the roxygen block. |
source |
Source attribution shown in the roxygen block. |
overwrite |
If |
Invisibly, the path of the generated file.
audit_dataset_doc(), use_data_doc().
## Not run: fix_dataset_doc("my_data", description = "My data", source = "Internal") ## End(Not run)## Not run: fix_dataset_doc("my_data", description = "My data", source = "Internal") ## End(Not run)
Convenience wrapper that runs the audit, then either prints the
globalVariables(...) block to console (default) or writes it to
R/globals.R. Wraps print_globals().
fix_globals(pkg = ".", write = FALSE, checks = NULL)fix_globals(pkg = ".", write = FALSE, checks = NULL)
pkg |
Path to the package. |
write |
If |
checks |
Optional. A pre-computed |
Invisibly, the path written (when write = TRUE) or NULL.
audit_globals(), print_globals().
## Not run: pkg <- create_example_pkg() fix_globals(pkg) fix_globals(pkg, write = TRUE) # Reuse a single R CMD check across both audit and fix: chk <- rcmdcheck::rcmdcheck(pkg) audit_globals(pkg, checks = chk) fix_globals(pkg, checks = chk, write = TRUE) ## End(Not run)## Not run: pkg <- create_example_pkg() fix_globals(pkg) fix_globals(pkg, write = TRUE) # Reuse a single R CMD check across both audit and fix: chk <- rcmdcheck::rcmdcheck(pkg) audit_globals(pkg, checks = chk) fix_globals(pkg, checks = chk, write = TRUE) ## End(Not run)